Compare commits

...

11 Commits

Author SHA1 Message Date
Clemens Schwaighofer
5a81626e8c Clean up ACL/Login
Add locale global variable in the format
<lang>_<country>.<encoding>@<suffix>
Default set to en_US.UTF-8

Also remove nested if callse and do early abort/method return for
flatten code:
loginUser
logoutUser
setAcl
printLogin
passwordChange
2022-04-11 09:17:19 +09:00
Clemens Schwaighofer
41cff5e3c6 Remove old comment from DB\IO class about encoding settings 2022-04-08 19:59:37 +09:00
Clemens Schwaighofer
e463f48ad4 Updates for language auto detect, fixes for PHP 7.4
There was a bug in ther SQL interface class where the folder was just
called "Interface" which is not an allowed Namespace name. Renamed to
SqlInterface

Moved the detect lang/etc function used in Form/Generate,
Template/SmartyExtend and Admin/Backend to Language/GetSettings.

Fixed some test class calls
2022-04-07 10:49:28 +09:00
Clemens Schwaighofer
f8ee6044f9 Upgrade from Smarty 3 to Smarty 4 to be PHP 8.1 compatible
Remove all Smarty4 dedicated tests, all are done in the same test file
like before
2022-04-06 15:19:06 +09:00
Clemens Schwaighofer
4b0e9b44c3 Smarty template updates for testing, edit templates updates, translation strings update 2022-04-06 14:51:21 +09:00
Clemens Schwaighofer
e5309b5dbc Stop using DS for DIRECTORY_SEPARATOR replacement
There is no need for a short entry, use the long one.
The DS is still defined for backwards compatible use
2022-04-06 09:21:15 +09:00
Clemens Schwaighofer
aad2e9b11b Test psalm config changes 2022-04-01 16:09:02 +09:00
Clemens Schwaighofer
d6baf58231 Update PHPunit tests 2022-03-28 17:41:32 +09:00
Clemens Schwaighofer
c464a7d884 Add phpunit tests for db\io db num rows, etc calls with dbReturn* 2022-03-23 15:13:32 +09:00
Clemens Schwaighofer
60613bf311 Comment fixes in Convert\Color 2022-03-23 11:38:05 +09:00
Clemens Schwaighofer
2a583e525c Update config.master, color convert hsb/hsl is full float
All Convert\Color calls for hsb or hsl are full float compatible
2022-03-23 10:38:23 +09:00
511 changed files with 36023 additions and 14786 deletions

View File

@@ -95,7 +95,7 @@ return [
'www/vendor',
'www/tests',
'www/lib/Smarty',
'www/lib/smarty-3.1.30',
'www/lib/smarty-4.1.0',
'www/templates_c',
'www/log',
'www/tmp',
@@ -117,11 +117,7 @@ return [
'www/admin/qq_file_upload_front.php',
'www/admin/qq_file_upload_ajax.php',
// symlink ignore
'www/lib/smarty-3.1.30/SmartyBC.class.php',
'www/lib/htmlMimeMail-2.5.1/HtmlMimeMailCreate.php',
// current not checking smarty4 test file
'www/lib/CoreLibs/Template/SmartyExtend4.php',
'www/admin/class_test.smarty4.php',
'www/lib/smarty-4.1.0/libs/Smarty.class.php'
],
// what not to show as problem

View File

@@ -33,3 +33,6 @@ msgstr "I should be translated: I WAS TRANSLATED"
msgid "Are we translated?"
msgstr "Are we translated? Yes, we are!"
msgid "Original with string: %1"
msgstr "Translated with: %1"

View File

@@ -75,3 +75,5 @@ msgstr "「スマーティー」これは正しいです"
msgid "Are we translated?"
msgstr "「クラス」これは翻訳です?"
msgid "Original with string: %1"
msgstr "%1と翻訳した"

View File

@@ -11,7 +11,7 @@ use PHPUnit\Framework\TestCase;
* @coversDefaultClass \CoreLibs\Check\PHPVersion
* @testdox \CoreLibs\Check\PHPVersion method tests
*/
final class CoreLibsCheckPHPVersionTest extends TestCase
final class CoreLibsCheckPhpVersionTest extends TestCase
{
/**
* NOTE: The checks must be adapted to the PHP version or they will fail

View File

@@ -132,7 +132,7 @@ final class CoreLibsConvertColorsTest extends TestCase
],
'valid color' => [
'rgb' => [10, 100, 200],
'hsb' => [212, 95, 78],
'hsb' => [212, 95, 78.0],
'hsb_rgb' => [10, 98, 199], // should be rgb, but rounding error
'hsl' => [211.6, 90.5, 41.2],
'valid' => true,
@@ -327,13 +327,13 @@ final class CoreLibsConvertColorsTest extends TestCase
* @dataProvider hsb2rgbColorProvider
* @testdox hsb2rgb $input_h,$input_s,$input_b will be $expected [$_dataName]
*
* @param integer $input_h
* @param integer $input_s
* @param integer $input_b
* @param float $input_h
* @param float $input_s
* @param float $input_b
* @param array|bool $expected
* @return void
*/
public function testHsb2rgb(int $input_h, int $input_s, int $input_b, $expected): void
public function testHsb2rgb(float $input_h, float $input_s, float $input_b, $expected): void
{
$this->assertEquals(
$expected,

View File

@@ -11,7 +11,7 @@ use PHPUnit\Framework\TestCase;
* @coversDefaultClass \CoreLibs\Convert\Json
* @testdox \CoreLibs\Convert\Json method tests
*/
final class CoreLibsCheckJsonTest extends TestCase
final class CoreLibsConvertJsonTest extends TestCase
{
/**

View File

@@ -2646,7 +2646,8 @@ final class CoreLibsDBIOTest extends TestCase
'level' => 'error',
'id' => '51',
'error' => 'Max query call needs to be set to at least 1',
'source' => 'main::run::run::run::run::run::run::runBare::runTest::testDbErrorHandling::dbSetMaxQueryCall',
// run:: can be +1 if called in set and not direct
'source' => "/^main::run::run::run::run::run::run::(run::)?runBare::runTest::testDbErrorHandling::dbSetMaxQueryCall$/",
'pg_error' => '',
'msg' => '',
]
@@ -3386,8 +3387,37 @@ final class CoreLibsDBIOTest extends TestCase
// if this is a select query, db dbReturn, dbReturnRow, dbReturnArray too
if (preg_match("/^(select|show|with) /i", $query)) {
// TODO also tst dbReturnRow and dbReturnArray
$res = $db->dbReturn($query);
// dbReturn
$db->dbReturn($query);
$this->assertEquals(
$expected_rows,
$db->dbGetNumRows()
);
$this->assertEquals(
$expected_cols,
$db->dbGetNumFields()
);
$this->assertEquals(
$expected_col_names,
$db->dbGetFieldNames()
);
// dbReturnRow
// will return ALL rows there, but returns only the first
$db->dbReturnRow($query);
$this->assertEquals(
$expected_rows,
$db->dbGetNumRows()
);
$this->assertEquals(
$expected_cols,
$db->dbGetNumFields()
);
$this->assertEquals(
$expected_col_names,
$db->dbGetFieldNames()
);
// dbReturnArray
$db->dbReturnArray($query);
$this->assertEquals(
$expected_rows,
$db->dbGetNumRows()

View File

@@ -1,4 +1,4 @@
<?php
<?php // phpcs:disable Generic.Files.LineLength
declare(strict_types=1);
@@ -255,18 +255,27 @@ final class CoreLibsDebugSupportTest extends TestCase
* Undocumented function
*
* @cover ::getCallerMethodList
* @testWith [["main", "run", "run", "run", "run", "run", "run", "runBare", "runTest", "testGetCallerMethodList"]]
* @testWith [["main", "run", "run", "run", "run", "run", "run", "runBare", "runTest", "testGetCallerMethodList"],["main", "run", "run", "run", "run", "run", "run", "run", "runBare", "runTest", "testGetCallerMethodList"]]
* @testdox getCallerMethodList check if it returns $expected [$_dataName]
*
* @param array $expected
* @return void
*/
public function testGetCallerMethodList(array $expected): void
public function testGetCallerMethodList(array $expected, array $expected_group): void
{
$this->assertEquals(
$expected,
\CoreLibs\Debug\Support::getCallerMethodList()
);
$compare = \CoreLibs\Debug\Support::getCallerMethodList();
// if we direct call we have 10, if we call as folder we get 11
if (count($compare) == 10) {
$this->assertEquals(
$expected,
\CoreLibs\Debug\Support::getCallerMethodList()
);
} else {
$this->assertEquals(
$expected_group,
\CoreLibs\Debug\Support::getCallerMethodList()
);
}
}
/**

View File

@@ -4,7 +4,7 @@
// sets the _SERVER['HTTP_HOST'] var so we can have DB detection
$_SERVER['HTTP_HOST'] = 'soba.tokyo.tequila.jp';
// so www/includes/edit_base.php works
require_once('www/lib/Smarty/SmartyBC.class.php');
// require_once('www/lib/Smarty/SmartyBC.class.php');
// for whatever reason it does not load that from the confing.master.php
// for includes/admin_header.php
define('BASE_NAME', '');

View File

@@ -45,9 +45,6 @@ parameters:
- www/lib/smarty-*/
# ignore composer
- www/vendor
# temp ignore smarty 4
- www/lib/CoreLibs/Template/SmartyExtend4.php
- www/admin/class_test.smarty4.php
# ignore errores with
ignoreErrors:
- # this error is ignore because of the PHP 8.0 to 8.1 change for pg_*

View File

@@ -54,7 +54,7 @@ print "SETACL[]: " . $backend->setACL([]) . "<br>";
print "ADBEDITLOG: " . $backend->adbEditLog('CLASSTEST-ADMIN', 'Some info stirng') . "<br>";
print "ADBTOPMENU(0): " . \CoreLibs\Debug\Support::printAr($backend->adbTopMenu()) . "<br>";
print "ADBMSG: " . $backend->adbMsg('info', 'Message: %1$d', [1]) . "<br>";
print "Messaes: " . \CoreLibs\Debug\Support::printAr($this->messages) . "<br>";
print "Messaes: " . \CoreLibs\Debug\Support::printAr($backend->messages) . "<br>";
print "ADBPRINTDATETIME:<br>" . $backend->adbPrintDateTime(2021, 6, 21, 6, 38, '_test') . "<br>";
// error message

View File

@@ -57,6 +57,7 @@ print "\$C::S/COLOR invalid rgb->hex (gray 125): -1, -1, -1: " . $color_class::r
$rgb = [10, 20, 30];
$hex = '#0a141e';
$hsb = [210, 67, 12];
$hsb_f = [210.5, 67.5, 12.5];
$hsl = [210, 50, 7.8];
print "S::COLOR rgb->hex: $rgb[0], $rgb[1], $rgb[2]: " . Colors::rgb2hex($rgb[0], $rgb[1], $rgb[2]) . "<br>";
print "S::COLOR hex->rgb: $hex: " . DgS::printAr(Colors::hex2rgb($hex)) . "<br>";
@@ -69,6 +70,8 @@ print "S::COLOR rgb->hsl: $rgb[0], $rgb[1], $rgb[2]: "
// D(from hsb/hsl) Note that param 2 + 3 is always 0-100 divided
print "S::COLOR hsb->rgb: $hsb[0], $hsb[1], $hsb[2]: "
. DgS::printAr(Colors::hsb2rgb($hsb[0], $hsb[1], $hsb[2])) . "<br>";
print "S::COLOR hsb_f->rgb: $hsb_f[0], $hsb_f[1], $hsb_f[2]: "
. DgS::printAr(Colors::hsb2rgb($hsb_f[0], $hsb_f[1], $hsb_f[2])) . "<br>";
print "S::COLOR hsl->rgb: $hsl[0], $hsl[1], $hsl[2]: "
. DgS::printAr(Colors::hsl2rgb($hsl[0], $hsl[1], $hsl[2])) . "<br>";
@@ -76,6 +79,15 @@ $hsb = [0, 0, 5];
print "S::COLOR hsb->rgb: $hsb[0], $hsb[1], $hsb[2]: "
. DgS::printAr(Colors::hsb2rgb($hsb[0], $hsb[1], $hsb[2])) . "<br>";
// Random text
$h = rand(0, 359);
$s = rand(15, 70);
$b = 100;
$l = 50;
print "RANDOM IN: H: " . $h . ", S: " . $s . ", B/L: " . $b . "/" . $l . "<br>";
print "RANDOM hsb->rgb: <pre>" . DgS::printAr(Colors::hsb2rgb($h, $s, $b)) . "</pre><br>";
print "RANDOM hsl->rgb: <pre>" . DgS::printAr(Colors::hsl2rgb($h, $s, $l)) . "</pre><br>";
// TODO: run compare check input must match output
// error message

View File

@@ -72,7 +72,7 @@ print '<div><a href="class_test.readenvfile.php">Class Test: READ ENV FILE</a></
print '<div><a href="class_test.runningtime.php">Class Test: RUNNING TIME</a></div>';
print '<div><a href="class_test.debug.php">Class Test: DEBUG</a></div>';
print '<div><a href="class_test.output.form.php">Class Test: OUTPUT FORM</a></div>';
print '<div><a href="class_test.backend.php">Class Test: BACKEND ADMIN CLASS</a></div>';
print '<div><a href="class_test.admin.backend.php">Class Test: BACKEND ADMIN CLASS</a></div>';
print '<div><a href="class_test.lang.php">Class Test: LANG/L10n</a></div>';
print '<div><a href="class_test.smarty.php">Class Test: SMARTY</a></div>';
print '<div><a href="class_test.autoloader.php">Class Test: AUTOLOADER</a></div>';
@@ -145,9 +145,7 @@ print "BASE: " . BASE . "<br>";
print "ROOT: " . ROOT . "<br>";
print "HOST: " . HOST_NAME . " => DB HOST: " . DB_CONFIG_NAME . " => " . print_r(DB_CONFIG, true) . "<br>";
$ds = defined('DS') ? DS : DIRECTORY_SEPARATOR;
$du = DS ?? DIRECTORY_SEPARATOR;
print "DS is: " . $ds . "<br>";
print "DS is: " . DIRECTORY_SEPARATOR . "<br>";
print "SERVER HOST: " . $_SERVER['HTTP_HOST'] . "<br>";
// print error messages

View File

@@ -65,16 +65,26 @@ if ($smarty->USE_PROTOTYPE) {
$smarty->JS_SPECIAL_TEMPLATE_NAME = 'jquery.test.js';
}
$smarty->PAGE_WIDTH = '100%';
// require BASE.INCLUDES.'admin_set_paths.php';
$smarty->setSmartyPaths();
// smarty test
$smarty->DATA['SMARTY_TEST'] = 'Test Data';
$smarty->DATA['TRANSLATE_TEST'] = $l->__('Are we translated?');
$smarty->DATA['TRANSLATE_TEST_SMARTY'] = $smarty->l10n->__('Are we translated?');
$smarty->DATA['replace'] = 'Replaced';
// variable variables
$smarty->DATA['test'] = 'foo';
$smarty->DATA['foo'] = 'bar';
// loop
$smarty->DATA['loop_start'] = 5;
// drop down test with optgroups
$options = [
$smarty->DATA['drop_down_test'] = [
'foo' => 'Foo',
'bar' => 'Bar',
'foobar' => 'Foo Bar',
];
$smarty->DATA['drop_down_test_selected'] = 'bar';
$smarty->DATA['drop_down_test_nested'] = [
'' => '選択してください',
'4/25(木)' => [
'4/25(木) 11:00-11:50' => '4/25(木) 11:00-11:50',
@@ -89,11 +99,26 @@ $options = [
'4/27(土) 12:20-13:00' => '4/27(土) 12:20-13:00'
],
];
$smarty->DATA['drop_down_test_nested_selected'] = '';
$smarty->DATA['radio_test'] = [
'0' => 'On',
'1' => 'Off',
'-1' => 'Undefined'
];
$smarty->DATA['radio_test_selected'] = -1;
$smarty->DATA['checkbox_test'] = [
'0' => 'On',
'1' => 'Off',
'-1' => 'Undefined'
];
$smarty->DATA['checkbox_test_pos'] = [
'0' => 'A',
'1' => 'B'
];
$smarty->DATA['checkbox_test_selected'] = ['1', '-1'];
$smarty->DATA['checkbox_test_pos_selected'] = ['0', '-1'];
$smarty->DATA['drop_down_test'] = $options;
$smarty->DATA['drop_down_test_selected'] = '';
$smarty->DATA['loop_start'] = 2;
// require BASE.INCLUDES.'admin_smarty.php';
$smarty->setSmartyVarsAdmin();
// error message

View File

@@ -1,105 +0,0 @@
<?php // phpcs:ignore warning
/**
* @phan-file-suppress PhanTypeSuspiciousStringExpression
*/
declare(strict_types=1);
$DEBUG_ALL_OVERRIDE = false; // set to 1 to debug on live/remote server locations
$DEBUG_ALL = true;
$PRINT_ALL = true;
$DB_DEBUG = true;
if ($DEBUG_ALL) {
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
}
ob_start();
// basic class test file
define('USE_DATABASE', true);
// set language
$lang = 'en_utf8';
// sample config
require 'config.php';
// override ECHO ALL FALSE
$ECHO_ALL = true;
// set session name
if (!defined('SET_SESSION_NAME')) {
define('SET_SESSION_NAME', EDIT_SESSION_NAME);
}
// define log file id
$LOG_FILE_ID = 'classTest-smarty';
ob_end_flush();
$log = new CoreLibs\Debug\Logging([
'log_folder' => BASE . LOG,
'file_id' => $LOG_FILE_ID,
// add file date
'print_file_date' => true,
// set debug and print flags
'debug_all' => $DEBUG_ALL ?? false,
'echo_all' => $ECHO_ALL ?? false,
'print_all' => $PRINT_ALL ?? false,
]);
$basic = new CoreLibs\Basic($log);
$smarty = new CoreLibs\Template\SmartyExtend4();
$l = new CoreLibs\Language\L10n($lang);
print "<html><head><title>TEST CLASS: SMARTY</title><head>";
print "<body>";
print '<div><a href="class_test.php">Class Test Master</a></div>';
$smarty->DATA['JS_DEBUG'] = DEBUG;
$smarty->MASTER_TEMPLATE_NAME = 'main_body4.tpl';
$smarty->TEMPLATE_NAME = 'smarty_test4.tpl';
$smarty->CSS_SPECIAL_TEMPLATE_NAME = 'smart_test.css';
$smarty->USE_PROTOTYPE = false;
$smarty->USE_JQUERY = true;
$smarty->JS_DATEPICKR = false;
if ($smarty->USE_PROTOTYPE) {
$smarty->ADMIN_JAVASCRIPT = 'edit.pt.js';
$smarty->JS_SPECIAL_TEMPLATE_NAME = 'prototype.test.js';
} elseif ($smarty->USE_JQUERY) {
$smarty->ADMIN_JAVASCRIPT = 'edit.jq.js';
$smarty->JS_SPECIAL_TEMPLATE_NAME = 'jquery.test.js';
}
$smarty->PAGE_WIDTH = '100%';
// require BASE.INCLUDES.'admin_set_paths.php';
$smarty->setSmartyPaths();
// smarty test
$smarty->DATA['SMARTY_TEST'] = 'Test Data';
$smarty->DATA['TRANSLATE_TEST'] = $l->__('Are we translated?');
$smarty->DATA['TRANSLATE_TEST_SMARTY'] = $smarty->l10n->__('Are we translated?');
// drop down test with optgroups
$options = [
'' => '選択してください',
'4/25(木)' => [
'4/25(木) 11:00-11:50' => '4/25(木) 11:00-11:50',
'4/25(木) 12:20-13:00' => '4/25(木) 12:20-13:00'
],
'4/26(金)' => [
'4/26(金) 11:00-11:50' => '4/26(金) 11:00-11:50',
'4/26(金) 12:20-13:00' => '4/26(金) 12:20-13:00'
],
'4/27(土)' => [
'4/27(土) 11:00-11:50' => '4/27(土) 11:00-11:50',
'4/27(土) 12:20-13:00' => '4/27(土) 12:20-13:00'
],
];
$smarty->DATA['drop_down_test'] = $options;
$smarty->DATA['drop_down_test_selected'] = '';
$smarty->DATA['loop_start'] = 2;
// require BASE.INCLUDES.'admin_smarty.php';
$smarty->setSmartyVarsAdmin();
// error message
print $log->printErrorMsg();
print "</body></html>";
// __END__

View File

@@ -11,72 +11,72 @@
declare(strict_types=1);
/************* PATHS *********************/
// directory seperator
// [DEPRECATED] directory seperator
define('DS', DIRECTORY_SEPARATOR);
// ** NEW/BETTER DIR DECLARATIONS **
// path to original file (if symlink)
define('DIR', __DIR__ . DS);
define('DIR', __DIR__ . DIRECTORY_SEPARATOR);
// base dir root folder level
define('BASE', str_replace('/configs', '', __DIR__) . DS);
define('BASE', str_replace('/configs', '', __DIR__) . DIRECTORY_SEPARATOR);
// ** OLD DIR DECLARATIONS **
// path to document root of file called
define('ROOT', getcwd() . DS);
define('ROOT', getcwd() . DIRECTORY_SEPARATOR);
// libs path
define('LIB', 'lib' . DS);
define('LIBS', 'lib' . DS);
define('LIB', 'lib' . DIRECTORY_SEPARATOR);
define('LIBS', 'lib' . DIRECTORY_SEPARATOR);
// configs folder
define('CONFIGS', 'configs' . DS);
define('CONFIGS', 'configs' . DIRECTORY_SEPARATOR);
// includes (strings, arrays for static, etc)
define('INCLUDES', 'includes' . DS);
define('INCLUDES', 'includes' . DIRECTORY_SEPARATOR);
// data folder (mostly in includes, or root for internal data)
define('DATA', 'data' . DS);
define('DATA', 'data' . DIRECTORY_SEPARATOR);
// layout base path
define('LAYOUT', 'layout' . DS);
define('LAYOUT', 'layout' . DIRECTORY_SEPARATOR);
// pic-root (compatible to CMS)
define('PICTURES', 'images' . DS);
define('PICTURES', 'images' . DIRECTORY_SEPARATOR);
// images
define('IMAGES', 'images' . DS);
define('IMAGES', 'images' . DIRECTORY_SEPARATOR);
// icons (below the images/ folder)
define('ICONS', 'icons' . DS);
define('ICONS', 'icons' . DIRECTORY_SEPARATOR);
// media (accessable from outside)
define('MEDIA', 'media' . DS);
define('MEDIA', 'media' . DIRECTORY_SEPARATOR);
// uploads (anything to keep or data)
define('UPLOADS', 'uploads' . DS);
define('UPLOADS', 'uploads' . DIRECTORY_SEPARATOR);
// files (binaries) (below media or data)
define('BINARIES', 'binaries' . DS);
define('BINARIES', 'binaries' . DIRECTORY_SEPARATOR);
// files (videos) (below media or data)
define('VIDEOS', 'videos' . DS);
define('VIDEOS', 'videos' . DIRECTORY_SEPARATOR);
// files (documents) (below media or data)
define('DOCUMENTS', 'documents' . DS);
define('DOCUMENTS', 'documents' . DIRECTORY_SEPARATOR);
// files (pdfs) (below media or data)
define('PDFS', 'documents' . DS);
define('PDFS', 'documents' . DIRECTORY_SEPARATOR);
// files (general) (below media or data)
define('FILES', 'files' . DS);
define('FILES', 'files' . DIRECTORY_SEPARATOR);
// CSV
define('CSV', 'csv' . DS);
define('CSV', 'csv' . DIRECTORY_SEPARATOR);
// css
define('CSS', 'css' . DS);
define('CSS', 'css' . DIRECTORY_SEPARATOR);
// font (web)
define('FONT', 'font' . DS);
define('FONT', 'font' . DIRECTORY_SEPARATOR);
// js
define('JS', 'javascript' . DS);
define('JS', 'javascript' . DIRECTORY_SEPARATOR);
// table arrays
define('TABLE_ARRAYS', 'table_arrays' . DS);
define('TABLE_ARRAYS', 'table_arrays' . DIRECTORY_SEPARATOR);
// smarty libs path
define('SMARTY', 'Smarty' . DS);
define('SMARTY', 'Smarty' . DIRECTORY_SEPARATOR);
// po langs
define('LANG', 'lang' . DS);
define('LANG', 'lang' . DIRECTORY_SEPARATOR);
// cache path
define('CACHE', 'cache' . DS);
define('CACHE', 'cache' . DIRECTORY_SEPARATOR);
// temp path
define('TMP', 'tmp' . DS);
define('TMP', 'tmp' . DIRECTORY_SEPARATOR);
// log files
define('LOG', 'log' . DS);
define('LOG', 'log' . DIRECTORY_SEPARATOR);
// compiled template folder
define('TEMPLATES_C', 'templates_c' . DS);
define('TEMPLATES_C', 'templates_c' . DIRECTORY_SEPARATOR);
// template base
define('TEMPLATES', 'templates' . DS);
define('TEMPLATES', 'templates' . DIRECTORY_SEPARATOR);
/************* HASH / ACL DEFAULT / ERROR SETTINGS / SMARTY *************/
// default hash type
@@ -256,10 +256,11 @@ $GLOBALS['DB_CONFIG'] = DB_CONFIG;
// where global tables are that are used by all schemas (eg queue tables for online, etc)
// define('GLOBAL_DB_SCHEMA', PUBLIC_SCHEMA);
// debug settings, site lang, etc
define('TARGET', $SITE_CONFIG[HOST_NAME]['location']);
define('DEBUG', $SITE_CONFIG[HOST_NAME]['debug_flag']);
define('SITE_LANG', $SITE_CONFIG[HOST_NAME]['site_lang']);
define('LOGIN_ENABLED', $SITE_CONFIG[HOST_NAME]['login_enabled']);
define('TARGET', $SITE_CONFIG[HOST_NAME]['location'] ?? 'test');
define('DEBUG', $SITE_CONFIG[HOST_NAME]['debug_flag'] ?? false);
define('SITE_LANG', $SITE_CONFIG[HOST_NAME]['site_lang'] ?? 'en_utf8');
define('LOGIN_ENABLED', $SITE_CONFIG[HOST_NAME]['login_enabled'] ?? false);
define('AUTH', $SITE_CONFIG[HOST_NAME]['auth'] ?? false);
// paths
// define('CSV_PATH', $PATHS[TARGET]['csv_path']);
// define('EXPORT_SCRIPT', $PATHS[TARGET]['perl_bin']);

View File

@@ -21,9 +21,9 @@ $paths = [
];
// find convert
foreach ($paths as $path) {
if (file_exists($path . DS . 'convert') && is_file($path . DS . 'convert')) {
if (file_exists($path . DIRECTORY_SEPARATOR . 'convert') && is_file($path . DIRECTORY_SEPARATOR . 'convert')) {
// image magick convert location
define('CONVERT', $path . DS . 'convert');
define('CONVERT', $path . DIRECTORY_SEPARATOR . 'convert');
break;
}
}

View File

@@ -46,8 +46,8 @@ for ($dir_pos = 0, $dir_max = count(explode(DIRECTORY_SEPARATOR, __DIR__)); $dir
break;
}
}
// fail if no base DS is not set
if (!defined('DS')) {
// fail if no base DIR is not set
if (!defined('DIR')) {
exit('Base config unloadable');
}
// find trigger name "admin/" or "frontend/" in the getcwd() folder

Binary file not shown.

Binary file not shown.

View File

@@ -33,26 +33,26 @@ function pop(theURL, winName, features) {
<!-- ERROR MSG END //-->
<!-- TOP MENU START //-->
<tr>
<td width="{$table_width}" class="menu_bgcolor" valign="top">
<table width="100%" border="0" cellpadding="2" cellspacing="1">
<form method="post">
<tr>
<td width="{$table_width}" class="menu_bgcolor" valign="top">
<table width="100%" border="0" cellpadding="2" cellspacing="1">
<form method="post">
<tr>
<td bgcolor="{$HEADER_COLOR}" class="normal">
Hello <b>{$USER_NAME|upper}</b> [{$EUID}] from the group <b>{$GROUP_NAME}</b> with Access Level <b>{$GROUP_LEVEL}</b>
</td>
<td bgcolor="{$HEADER_COLOR}" class="normal" align="right">
<input type="submit" name="login_logout" value="Logout">
</td>
</tr>
</form>
</table>
<table width="100%" border="0" cellpadding="2" cellspacing="1">
<tr>
</tr>
</form>
</table>
<table width="100%" border="0" cellpadding="2" cellspacing="1">
<tr>
{* foreach menu *}
{foreach from=$menu_data item=menu_element}
{* if split factor is reached *}
{if $menu_element.splitfactor_in}
<td class="menu_fgcolor" class="small" valign="top">
<td class="menu_fgcolor" class="small" valign="top">
{/if}
{if $menu_element.position}
<b><a href="{$menu_element.filename}">{$menu_element.pagename}</a></b><br>
@@ -67,22 +67,22 @@ function pop(theURL, winName, features) {
</td>
{/if}
{/foreach}
</tr>
</table>
<table width="100%" border="0" cellpadding="10" cellspacing="1">
<tr>
<td class="edit_fgcolor_alt" class="headline" align="center">
{$page_name}
</td>
</tr>
</table>
</td>
</tr>
</tr>
</table>
<table width="100%" border="0" cellpadding="10" cellspacing="1">
<tr>
<td class="edit_fgcolor_alt" class="headline" align="center">
{$page_name}
</td>
</tr>
</table>
</td>
</tr>
<!-- TOP MENU END //-->
<tr>
<td width="{$table_width}" class="edit_bgcolor">
<form method="post" name="edit_form" style="margin-block-end: 0em;">
<table width="100%" border="0" cellpadding="2" cellspacing="1">
<tr>
<td width="{$table_width}" class="edit_bgcolor">
<form method="post" name="edit_form" style="margin-block-end: 0em;">
<table width="100%" border="0" cellpadding="2" cellspacing="1">
<!-- LOAD START //-->
{include file="edit_load.tpl"}
<!-- LOAD END //-->
@@ -93,23 +93,23 @@ function pop(theURL, winName, features) {
{if $form_yes}
{include file="edit_save_delete.tpl"}
{if $form_my_page_name == "edit_pages" && $filename_exist}
<tr>
<td class="edit_fgcolor" class="normal">
Filename:
</td>
<td class="edit_fgcolor" class="normal">
{$filename}
<input type="hidden" name="filename" value="{$filename}">
</td>
</tr>
<tr>
<td class="edit_fgcolor" class="normal">
Filename:
</td>
<td class="edit_fgcolor" class="normal">
{$filename}
<input type="hidden" name="filename" value="{$filename}">
</td>
</tr>
{/if}
{include file="edit_elements.tpl"}
{include file="edit_hidden.tpl"}
{include file="edit_save_delete.tpl"}
{/if}
</table>
</form>
</td>
</table>
</form>
</td>
</tr>
</table>
</body>

View File

@@ -8,16 +8,16 @@
********************************************************************
*}
<tr>
<td class="edit_fgcolor_alt" class="normal">
{t}Create new media:{/t}
</td>
<td class="edit_fgcolor_alt" class="normal">
{if $new.show_checkbox}
<input type="checkbox" name="really_new" value="yes">&nbsp;{t}really{/t}&nbsp;
{else}
<input type="hidden" name="really_new" value="yes">
{/if}
<input type="submit" name="new" value="{$new.new_name}">
</td>
</tr>
<tr>
<td class="edit_fgcolor_alt" class="normal">
{t}Create new media:{/t}
</td>
<td class="edit_fgcolor_alt" class="normal">
{if $new.show_checkbox}
<input type="checkbox" name="really_new" value="yes">&nbsp;{t}really{/t}&nbsp;
{else}
<input type="hidden" name="really_new" value="yes">
{/if}
<input type="submit" name="new" value="{$new.new_name}">
</td>
</tr>

View File

@@ -25,7 +25,7 @@
<!-- ERROR MSG END //-->
<!-- BODY START //-->
<tr>
<td class="edit_bgcolor">
<td class="edit_bgcolor">
<table width="100%" border="0" cellpadding="2" cellspacing="1">
<!-- ANFANG Neu //-->
<form method="post" enctype="multipart/form-data">
@@ -68,7 +68,7 @@
</form>
<!-- ENDE FOOTER //-->
</table>
</td>
</td>
</tr>
<!-- BODY END //-->
</table>

View File

@@ -26,7 +26,7 @@
<input type="submit" name="delete" value="{t}Delete{/t}">
{else}
<td class="edit_fgcolor_alt" class="normal">
&nbsp;
&nbsp;
{/if}
</td>
</tr>

View File

@@ -1,16 +1,27 @@
<div>
{$SMARTY_TEST}
</div>
<div>
TRANSLATION CLASS (OUT): {$TRANSLATE_TEST}
SMARTY_TEST: {$SMARTY_TEST}
</div>
<div {popup width="250" caption="Info" text="Text block<br>Control"} style="border: 1px solid black; margin: 5px 0 5px 0; padding: 5px;">
POPUP HERE (hover mouse)
</div>
<div>
<b>Outside translation test</b><br>
TRANSLATION CLASS (OUT): {$TRANSLATE_TEST}<br>
TRANSLATION CLASS (SMARTY): {$TRANSLATE_TEST_SMARTY}
</div>
<div>
<select id="drop_down_test" name="drop_down_test">
{html_options options=$drop_down_test selected=$drop_down_test_selected}
</select>
<b>Translate Test with replace:</b><br>
ORIGINAL: Original with string: %1 ({$replace})<br>
TRANSLATED: {t 1=$replace}Original with string: %1{/t}<br>
TRANSLATED (escape): {t escape=on 1=$replace}Original with string: %1{/t}
</div>
<div>
<b>Variable variables:</b><br>
Test: {$test}<br>
Foo: {$foo}<br>
{assign var="bar" value="test"}
vFoo ($test = $foo = bar): {$test|getvar}<br>
vFoo ($bar = $test = foo): {$bar|getvar}
</div>
<div class="jq-container">
<div id="jq-test" class="jp-test">
@@ -23,11 +34,30 @@
</div>
</div>
<div class="loop-test">
<div>LOOP TEST</div>
<div><b>LOOP TEST</b></div>
{section name=page_list start=1 loop=$loop_start+1}
<div>LOOP OUTPUT: {$smarty.section.page_list.index}</div>
{/section}
</div>
<div>
<select id="drop_down_test" name="drop_down_test">
{html_options options=$drop_down_test selected=$drop_down_test_selected}
</select>
</div>
<div>
<select id="drop_down_test_nested" name="drop_down_test_nested">
{html_options options=$drop_down_test_nested selected=$drop_down_test_nested_selected}
</select>
</div>
<div>
{html_radios name="radio_test" options=$radio_test selected=$radio_test_selected}
</div>
<div>
{html_checkboxes name="checkbox_test" options=$checkbox_test selected=$checkbox_test_selected}
</div>
<div>
{html_checkboxes name="checkbox_test_pos" options=$checkbox_test selected=$checkbox_test_pos_selected pos=$checkbox_test_pos}
</div>
{* progresss indicator *}
<div id="indicator"></div>
{* the action confirm box *}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -92,6 +92,8 @@ class Backend
/** @var string */
public $lang_short;
/** @var string */
public $domain;
/** @var string */
public $encoding;
/** @var \CoreLibs\Debug\Logging logger */
public $log;
@@ -171,27 +173,13 @@ class Backend
*/
private function setLangEncoding(): void
{
// just emergency fallback for language
// set encoding
if (isset($_SESSION['DEFAULT_CHARSET'])) {
$this->encoding = $_SESSION['DEFAULT_CHARSET'];
} else {
$this->encoding = DEFAULT_ENCODING;
}
// gobal override
if (isset($GLOBALS['OVERRIDE_LANG'])) {
$this->lang = $GLOBALS['OVERRIDE_LANG'];
} elseif (isset($_SESSION['DEFAULT_LANG'])) {
// session (login)
$this->lang = $_SESSION['DEFAULT_LANG'];
} else {
// mostly default SITE LANG or DEFAULT LANG
$this->lang = defined('SITE_LANG') ? SITE_LANG : DEFAULT_LANG;
}
// create the char lang encoding
$this->lang_short = substr($this->lang, 0, 2);
// set the language folder
$this->lang_dir = BASE . INCLUDES . LANG . CONTENT_PATH;
list (
$this->encoding,
$this->lang,
$this->lang_short,
$this->domain,
$this->lang_dir
) = \CoreLibs\Language\GetSettings::setLangEncoding();
}
// PUBLIC METHODS |=================================================>

View File

@@ -66,7 +66,8 @@ class Colors
}
$rgbArray = [];
if (strlen($hexStr) == 6) {
// If a proper hex code, convert using bitwise operation. No overhead... faster
// If a proper hex code, convert using bitwise operation.
// No overhead... faster
$colorVal = hexdec($hexStr);
$rgbArray['r'] = 0xFF & ($colorVal >> 0x10);
$rgbArray['g'] = 0xFF & ($colorVal >> 0x8);
@@ -135,13 +136,13 @@ class Colors
* hsb2rgb does not clean convert back to hsb in a round trip
* converts HSB/V to RGB values RGB is full INT
* if HSB/V value is invalid, sets this value to 0
* @param int $H hue 0-360 (int)
* @param int $S saturation 0-100 (int)
* @param int $V brightness/value 0-100 (int)
* @param float $H hue 0-360 (int)
* @param float $S saturation 0-100 (int)
* @param float $V brightness/value 0-100 (int)
* @return array<int>|bool 0 red/1 green/2 blue array as 0-255
* false for input value error
*/
public static function hsb2rgb(int $H, int $S, int $V)
public static function hsb2rgb(float $H, float $S, float $V)
{
// check that H is 0 to 359, 360 = 0
// and S and V are 0 to 1
@@ -270,12 +271,12 @@ class Colors
/**
* converts an HSL to RGB
* if HSL value is invalid, set this value to 0
* @param int|float $hue hue: 0-360 (degrees)
* @param float $hue hue: 0-360 (degrees)
* @param float $sat saturation: 0-100
* @param float $lum luminance: 0-100
* @return array<int,float|int>|bool red/blue/green 0-255 each
*/
public static function hsl2rgb($hue, float $sat, float $lum)
public static function hsl2rgb(float $hue, float $sat, float $lum)
{
if (!is_numeric($hue)) {
return false;
@@ -289,7 +290,8 @@ class Colors
if ($lum < 0 || $lum > 100) {
return false;
}
$hue = (1 / 360) * $hue; // calc to internal convert value for hue
// calc to internal convert value for hue
$hue = (1 / 360) * $hue;
// convert to internal 0-1 format
$sat /= 100;
$lum /= 100;

View File

@@ -382,7 +382,7 @@ class IO
public function __construct(
array $db_config,
?\CoreLibs\Debug\Logging $log = null,
?bool $db_debug_override = null,
?bool $db_debug_override = null
) {
// attach logger
$this->log = $log ?? new \CoreLibs\Debug\Logging();
@@ -410,9 +410,6 @@ class IO
false
);
// set the target encoding to the DEFAULT_ENCODING if it is one of them: EUC, Shift_JIS, UTF-8
// @ the moment set only from outside
// set loop protection max count
$this->MAX_QUERY_CALL = self::DEFAULT_MAX_QUERY_CALL;

View File

@@ -51,7 +51,7 @@ namespace CoreLibs\DB\SQL;
// as main system. Currently all @var sets are written as object
/** @#phan-file-suppress PhanUndeclaredTypeProperty,PhanUndeclaredTypeParameter,PhanUndeclaredTypeReturnType */
class PgSQL implements Interface\SqlFunctions
class PgSQL implements \CoreLibs\DB\SQL\SqlInterface\SqlFunctions
{
/** @var string */
private $last_error_query;

View File

@@ -6,7 +6,7 @@
declare(strict_types=1);
namespace CoreLibs\DB\SQL\Interface;
namespace CoreLibs\DB\SQL\SqlInterface;
interface SqlFunctions
{

View File

@@ -0,0 +1,123 @@
<?php
/*
* Internal function for getting languange and encodig settings
*/
declare(strict_types=1);
namespace CoreLibs\Language;
class GetSettings
{
/**
* Sets encoding and language
* Can be overridden with language + path to mo file
* If language is set it must be in the format of:
* <lang>.<encoding>
* <lang>_<country>.<encoding>
* <lang>_<country>@<subset>.<encoding>
*
* @param string|null $language
* @param string|null $path
* @return array
*/
public static function setLangEncoding(
?string $language = null,
?string $domain = null,
?string $path = null
): array {
$lang = '';
$lang_short = '';
$encoding = '';
// if language is set, extract
if (!empty($language)) {
preg_match(
"/^(([a-z]{2,})(_[A-Z]{2,})?(@[a-z]{1,})?)(\.([\w-])+)?$/",
$language,
$matches
);
// 1: lang (always)
$lang = $matches[1] ?? '';
// 2: lang short part
$lang_short = $matches[2] ?? '';
// 3: [ignore] sub part, if set, combined with lang
// 4: [ignore] possible sub part, combined with lang in 1
// 6: encoding if set
$encoding = $matches[5] ?? '';
}
// if domain is set, must be alphanumeric, if not unset
if (
!empty($domain) &&
!preg_match("/^\w+$/", $domain)
) {
$domain = '';
}
// path checks if set, if not valid path unset
if (
!empty($path) &&
!is_dir($path)
) {
$path = '';
}
// just emergency fallback for language
// set encoding
if (empty($encoding)) {
if (!empty($_SESSION['DEFAULT_CHARSET'])) {
$encoding = $_SESSION['DEFAULT_CHARSET'];
} else {
$encoding = DEFAULT_ENCODING;
}
}
// gobal override
if (empty($lang)) {
if (!empty($GLOBALS['OVERRIDE_LANG'])) {
$lang = $GLOBALS['OVERRIDE_LANG'];
} elseif (!empty($_SESSION['DEFAULT_LANG'])) {
// session (login)
$lang = $_SESSION['DEFAULT_LANG'];
} else {
// mostly default SITE LANG or DEFAULT LANG
$lang = defined('SITE_LANG') && !empty(SITE_LANG) ?
SITE_LANG :
DEFAULT_LANG;
}
}
// create the char lang encoding
if (empty($lang_short)) {
$lang_short = substr($lang, 0, 2);
}
// set the language folder
if (empty($path)) {
// LEGACY
$path = BASE . INCLUDES . LANG . CONTENT_PATH;
// will be BASE . INCLUDES . LANG . $language . /LC_MESSAGES/
// so CONTENT_PATH has to be removed
}
// if no domain is set, fall back to content path
if (empty($domain)) {
$domain = str_replace('/', '', CONTENT_PATH);
}
// return
return [
// as array
0 => $encoding,
1 => $lang,
2 => $lang_short,
3 => $domain,
4 => $path,
// with index name
// encoding
'encoding' => $encoding,
// language full string, eg en_US
'lang' => $lang,
// lang short, if eg en_US only en
'lang_short' => $lang_short,
// translation domain (CONTENT_PATH)
'domain' => $domain,
// folder BASE ONLY
'path' => $path,
];
}
}

View File

@@ -16,7 +16,7 @@
* PUBLIC METHODS
* __: returns string (translated or original if not found)
* __e: echos out string (translated or original if not found)
* __ngettext: should return plural. never tested this.
* __n: should return plural. never tested this.
*
* PRIVATE METHODS
*
@@ -24,6 +24,13 @@
* 2005/10/17 (cs) made an on the fly switch method (reload of lang)
*********************************************************************/
// TODO: default path change to <base>/lang/LC_MESSAGES/domain.encoding.mo
// for example: lang: ja_JP.UTF-8, domain: admin
// <base>/ja_JP/LC_MESSAGES/admin.UTF-8.mo
// OLD: includes/lang/admin/ja_utf8.mo
// NEW: includes/lang/ja_JP/LC_MESSAGES/admin.UTF-8.mo
// or fallback: includes/lang/ja/LC_MESSAGES/admin.UTF-8.mo
declare(strict_types=1);
namespace CoreLibs\Language;
@@ -106,12 +113,30 @@ class L10n
return $success;
}
/**
* get current set language
* @return string current set language string
*/
public function __getLang(): string
{
return $this->lang;
}
/**
* get current set mo file
* @return string current set mo language file
*/
public function __getMoFile(): string
{
return $this->mofile;
}
/**
* translates a string and returns translated text
* @param string $text text to translate
* @return string translated text
*/
public function __($text): string
public function __(string $text): string
{
return $this->l10n->translate($text);
}
@@ -121,7 +146,7 @@ class L10n
* @param string $text text to translate
* @return void has no return
*/
public function __e($text): void
public function __e(string $text): void
{
echo $this->l10n->translate($text);
}
@@ -129,33 +154,46 @@ class L10n
// Return the plural form.
/**
* Return the plural form.
* @param string $single string for single word
* @param string $plural string for plural word
* @param string $number number value
* @return string translated plural string
* @param string $single string for single word
* @param string $plural string for plural word
* @param int|float $number number value
* @return string translated plural string
*/
public function __ngettext($single, $plural, $number)
public function __n(string $single, string $plural, $number): string
{
return $this->l10n->ngettext($single, $plural, $number);
}
// alias functions to mimic gettext calls
/**
* get current set language
* @return string current set language string
* Undocumented function
*
* @param string $text
* @return string
*/
public function __getLang()
public function gettext(string $text): string
{
return $this->lang;
return $this->__($text);
}
/**
* get current set mo file
* @return string current set mo language file
* Undocumented function
*
* @param string $single
* @param string $plural
* @param int|float $number
* @return string
*/
public function __getMoFile()
public function ngettext(string $single, string $plural, $number): string
{
return $this->mofile;
return $this->__n($single, $plural, $number);
}
// TODO: dgettext(string $domain, string $message): string
// TODO: dngettext(string $domain, string $singular, string $plural, int $count): string
// TODO: dcgettext(string $domain, string $message, int $category): string
// TODO: dcngettext(string $domain, string $singular, string $plural, int $count, int $category): string
}
// __END__

View File

@@ -286,6 +286,8 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
/** @var string */
public $lang_short;
/** @var string */
public $domain;
/** @var string */
public $encoding;
// language
/** @var \CoreLibs\Language\L10n */
@@ -299,10 +301,13 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
* construct form generator
* @param array<mixed> $db_config db config array
* @param \CoreLibs\Debug\Logging|null $log Logging class
* @param \CoreLibs\Language\L10n|null $l10n l10n language class
* if null, auto set
*/
public function __construct(
array $db_config,
\CoreLibs\Debug\Logging $log = null
\CoreLibs\Debug\Logging $log = null,
?\CoreLibs\Language\L10n $l10n = null
) {
global $table_arrays;
// replace any non valid variable names
@@ -310,7 +315,7 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
$this->my_page_name = str_replace(['.'], '_', System::getPageName(System::NO_EXTENSION));
$this->setLangEncoding();
// init the language class
$this->l = new \CoreLibs\Language\L10n($this->lang);
$this->l = $l10n ?? new \CoreLibs\Language\L10n($this->lang);
// load config array
// get table array definitions for current page name
@@ -452,27 +457,13 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
*/
private function setLangEncoding(): void
{
// just emergency fallback for language
// set encoding
if (isset($_SESSION['DEFAULT_CHARSET'])) {
$this->encoding = $_SESSION['DEFAULT_CHARSET'];
} else {
$this->encoding = DEFAULT_ENCODING;
}
// gobal override
if (isset($GLOBALS['OVERRIDE_LANG'])) {
$this->lang = $GLOBALS['OVERRIDE_LANG'];
} elseif (isset($_SESSION['DEFAULT_LANG'])) {
// session (login)
$this->lang = $_SESSION['DEFAULT_LANG'];
} else {
// mostly default SITE LANG or DEFAULT LANG
$this->lang = defined('SITE_LANG') ? SITE_LANG : DEFAULT_LANG;
}
// create the char lang encoding
$this->lang_short = substr($this->lang, 0, 2);
// set the language folder
$this->lang_dir = BASE . INCLUDES . LANG . CONTENT_PATH;
list (
$this->encoding,
$this->lang,
$this->lang_short,
$this->domain,
$this->lang_dir
) = \CoreLibs\Language\GetSettings::setLangEncoding();
}
// PUBLIC METHODS |=================================================>

View File

@@ -19,21 +19,8 @@ declare(strict_types=1);
namespace CoreLibs\Template;
// I need to manually load Smarty BC here (it is not namespaced)
// require_once(BASE . LIB . SMARTY . 'SmartyBC.class.php');
// we set this hard coded so it works with all checkers
// HARD CODED path:
// __DIR__: lib/CoreLibs/Template/
// smarty located in lib/Smarty/
// require_once(__DIR__ . '/../../Smarty/Smarty.class.php');
require_once(__DIR__ . '/../../Smarty/SmartyBC.class.php');
// So it doesn't start looking around in the wrong naemspace as smarty doesn't have one
// use Smarty;
use SmartyBC;
// technically this can be Smarty
// class SmartyExtend extends Smarty
class SmartyExtend extends SmartyBC
// leading slash if this is in lib\Smarty
class SmartyExtend extends \Smarty
{
// internal translation engine
/** @var \CoreLibs\Language\L10n */
@@ -47,6 +34,8 @@ class SmartyExtend extends SmartyBC
/** @var string */
public $lang_short;
/** @var string */
public $domain;
/** @var string */
public $encoding;
// page name
/** @var string */
@@ -165,17 +154,21 @@ class SmartyExtend extends SmartyBC
* constructor class, just sets the language stuff
* calls L10 for pass on internaly in smarty
* also registers the getvar caller plugin
* @param \CoreLibs\Language\L10n|null $l10n l10n language class
* if null, auto set
*/
public function __construct()
public function __construct(?\CoreLibs\Language\L10n $l10n = null)
{
// call basic smarty
// or Smarty::__construct();
parent::__construct();
// set lang vars
$this->setLangEncoding();
// iinit lang
$this->l10n = new \CoreLibs\Language\L10n($this->lang);
/** @phpstan-ignore-next-line */
$this->registerPlugin('modifier', 'getvar', [&$this, 'get_template_vars']);
$this->l10n = $l10n ?? new \CoreLibs\Language\L10n($this->lang);
// Smarty 3.x
// $this->registerPlugin('modifier', 'getvar', [&$this, 'get_template_vars']);
$this->registerPlugin('modifier', 'getvar', [&$this, 'getTemplateVars']);
$this->page_name = pathinfo($_SERVER["PHP_SELF"])['basename'];
@@ -196,27 +189,13 @@ class SmartyExtend extends SmartyBC
*/
private function setLangEncoding(): void
{
// just emergency fallback for language
// set encoding
if (isset($_SESSION['DEFAULT_CHARSET'])) {
$this->encoding = $_SESSION['DEFAULT_CHARSET'];
} else {
$this->encoding = DEFAULT_ENCODING;
}
// gobal override
if (isset($GLOBALS['OVERRIDE_LANG'])) {
$this->lang = $GLOBALS['OVERRIDE_LANG'];
} elseif (isset($_SESSION['DEFAULT_LANG'])) {
// session (login)
$this->lang = $_SESSION['DEFAULT_LANG'];
} else {
// mostly default SITE LANG or DEFAULT LANG
$this->lang = defined('SITE_LANG') ? SITE_LANG : DEFAULT_LANG;
}
// create the char lang encoding
$this->lang_short = substr($this->lang, 0, 2);
// set the language folder
$this->lang_dir = BASE . INCLUDES . LANG . CONTENT_PATH;
list (
$this->encoding,
$this->lang,
$this->lang_short,
$this->domain,
$this->lang_dir
) = \CoreLibs\Language\GetSettings::setLangEncoding();
}
/**
@@ -330,13 +309,13 @@ class SmartyExtend extends SmartyBC
// check if template names exist
if (!$this->MASTER_TEMPLATE_NAME) {
exit('MASTER TEMPLATE is not set');
} elseif (!file_exists($this->getTemplateDir()[0] . DS . $this->MASTER_TEMPLATE_NAME)) {
} elseif (!file_exists($this->getTemplateDir()[0] . DIRECTORY_SEPARATOR . $this->MASTER_TEMPLATE_NAME)) {
// abort if master template could not be found
exit('MASTER TEMPLATE: ' . $this->MASTER_TEMPLATE_NAME . ' could not be found');
}
if (
$this->TEMPLATE_NAME &&
!file_exists($this->getTemplateDir()[0] . DS . $this->TEMPLATE_NAME)
!file_exists($this->getTemplateDir()[0] . DIRECTORY_SEPARATOR . $this->TEMPLATE_NAME)
) {
exit('INCLUDE TEMPLATE: ' . $this->TEMPLATE_NAME . ' could not be found');
}
@@ -355,7 +334,7 @@ class SmartyExtend extends SmartyBC
}
}
// if we can't find it, dump it
if (!file_exists($this->getTemplateDir()[0] . DS . $this->TEMPLATE_TRANSLATE)) {
if (!file_exists($this->getTemplateDir()[0] . DIRECTORY_SEPARATOR . $this->TEMPLATE_TRANSLATE)) {
$this->TEMPLATE_TRANSLATE = null;
}
}

View File

@@ -1,533 +0,0 @@
<?php // phpcs:ignore PSR1.Files.SideEffects
/**
* @phan-file-suppress PhanRedefinedExtendedClass
*/
// because smarty is symlinked folder
declare(strict_types=1);
/********************************************************************
* AUTHOR: Clemens Schwaighofer
* CREATED: 2004/12/21
* SHORT DESCRIPTION:
* extends smarty with the l10n class so I can use __(, etc calls
* HISTORY:
* 2005/06/22 (cs) include smarty class here, so there is no need to include it in the main file
*********************************************************************/
namespace CoreLibs\Template;
// I need to manually load Smarty BC here (it is not namespaced)
// require_once(BASE . LIB . SMARTY . 'SmartyBC.class.php');
// we set this hard coded so it works with all checkers
// HARD CODED path:
// __DIR__: lib/CoreLibs/Template/
// smarty located in lib/Smarty4/
require_once(__DIR__ . '/../../Smarty4/Smarty.class.php');
// So it doesn't start looking around in the wrong naemspace as smarty doesn't have one
use Smarty;
// technically this can be Smarty
class SmartyExtend4 extends Smarty
{
// internal translation engine
/** @var \CoreLibs\Language\L10n */
public $l10n;
// lang & encoding
/** @var string */
public $lang_dir = '';
/** @var string */
public $lang;
/** @var string */
public $lang_short;
/** @var string */
public $encoding;
// page name
/** @var string */
public $page_name;
// array for data parsing
/** @var array<mixed> */
public $HEADER = [];
/** @var array<mixed> */
public $DATA = [];
/** @var array<mixed> */
public $DEBUG_DATA = [];
/** @var array<mixed> */
private $CONTENT_DATA = [];
// control vars
/** @var bool */
public $USE_PROTOTYPE = USE_PROTOTYPE;
/** @var bool */
public $USE_JQUERY = USE_JQUERY;
/** @var bool */
public $USE_SCRIPTACULOUS = USE_SCRIPTACULOUS;
// sub content input vars
/** @var bool */
public $USE_TINY_MCE = false;
/** @var bool */
public $JS_DATEPICKR = false;
/** @var bool */
public $JS_FLATPICKR = false;
/** @var bool */
public $JS_FILE_UPLOADER = false;
/** @var bool */
public $DEBUG_TMPL = false;
/** @var bool */
public $USE_INCLUDE_TEMPLATE = false;
// cache & compile
/** @var string */
public $CACHE_ID = '';
/** @var string */
public $COMPILE_ID = '';
// template vars
/** @var string */
public $MASTER_TEMPLATE_NAME;
/** @var string */
public $PAGE_FILE_NAME;
/** @var string */
public $CONTENT_INCLUDE;
/** @var string */
public $FORM_NAME;
/** @var string */
public $FORM_ACTION;
/** @var string */
public $L_TITLE;
/** @var string|int */
public $PAGE_WIDTH;
// smarty include/set var
/** @var string */
public $TEMPLATE_PATH;
/** @var string */
public $TEMPLATE_NAME;
/** @var string */
public $INC_TEMPLATE_NAME;
/** @var string */
public $JS_TEMPLATE_NAME;
/** @var string */
public $CSS_TEMPLATE_NAME;
/** @var string|null */
public $TEMPLATE_TRANSLATE;
// core group
/** @var string */
public $JS_CORE_TEMPLATE_NAME;
/** @var string */
public $CSS_CORE_TEMPLATE_NAME;
/** @var string */
public $JS_CORE_INCLUDE;
/** @var string */
public $CSS_CORE_INCLUDE;
// local names
/** @var string */
public $JS_SPECIAL_TEMPLATE_NAME = '';
/** @var string */
public $CSS_SPECIAL_TEMPLATE_NAME = '';
/** @var string */
public $JS_INCLUDE;
/** @var string */
public $CSS_INCLUDE;
/** @var string */
public $JS_SPECIAL_INCLUDE;
/** @var string */
public $CSS_SPECIAL_INCLUDE;
/** @var string */
public $ADMIN_JAVASCRIPT;
/** @var string */
public $ADMIN_STYLESHEET;
/** @var string */
public $FRONTEND_JAVASCRIPT;
/** @var string */
public $FRONTEND_STYLESHEET;
// other smarty folder vars
/** @var string */
public $INCLUDES;
/** @var string */
public $JAVASCRIPT;
/** @var string */
public $CSS;
/** @var string */
public $FONT;
/** @var string */
public $PICTURES;
/** @var string */
public $CACHE_PICTURES;
/** @var string */
public $CACHE_PICTURES_ROOT;
// constructor class, just sets the language stuff
/**
* constructor class, just sets the language stuff
* calls L10 for pass on internaly in smarty
* also registers the getvar caller plugin
*/
public function __construct()
{
// call basic smarty
parent::__construct();
// set lang vars
$this->setLangEncoding();
// iinit lang
$this->l10n = new \CoreLibs\Language\L10n($this->lang);
/** @phpstan-ignore-next-line */
$this->registerPlugin('modifier', 'getvar', [&$this, 'getTemplateVars']);
$this->page_name = pathinfo($_SERVER["PHP_SELF"])['basename'];
// set internal settings
$this->CACHE_ID = defined('CACHE_ID') ? CACHE_ID : '';
$this->COMPILE_ID = defined('COMPILE_ID') ? COMPILE_ID : '';
}
/**
* ORIGINAL in \CoreLibs\Admin\Backend
* set the language encoding and language settings
* the default charset from _SESSION login or from
* config DEFAULT ENCODING
* the lang full name for mo loading from _SESSION login
* or SITE LANG or DEFAULT LANG from config
* creates short lang (only first two chars) from the lang
* @return void
*/
private function setLangEncoding(): void
{
// just emergency fallback for language
// set encoding
if (isset($_SESSION['DEFAULT_CHARSET'])) {
$this->encoding = $_SESSION['DEFAULT_CHARSET'];
} else {
$this->encoding = DEFAULT_ENCODING;
}
// gobal override
if (isset($GLOBALS['OVERRIDE_LANG'])) {
$this->lang = $GLOBALS['OVERRIDE_LANG'];
} elseif (isset($_SESSION['DEFAULT_LANG'])) {
// session (login)
$this->lang = $_SESSION['DEFAULT_LANG'];
} else {
// mostly default SITE LANG or DEFAULT LANG
$this->lang = defined('SITE_LANG') ? SITE_LANG : DEFAULT_LANG;
}
// create the char lang encoding
$this->lang_short = substr($this->lang, 0, 2);
// set the language folder
$this->lang_dir = BASE . INCLUDES . LANG . CONTENT_PATH;
}
/**
* @return void
*/
private function setSmartCoreIncludeCssJs(): void
{
// core CS
$this->CSS_CORE_INCLUDE = '';
if (
file_exists($this->CSS . $this->CSS_CORE_TEMPLATE_NAME) &&
is_file($this->CSS . $this->CSS_CORE_TEMPLATE_NAME)
) {
$this->CSS_CORE_INCLUDE = $this->CSS . $this->CSS_CORE_TEMPLATE_NAME;
}
// core JS
$this->JS_CORE_INCLUDE = '';
if (
file_exists($this->JAVASCRIPT . $this->JS_CORE_TEMPLATE_NAME) &&
is_file($this->JAVASCRIPT . $this->JS_CORE_TEMPLATE_NAME)
) {
$this->JS_CORE_INCLUDE = $this->JAVASCRIPT . $this->JS_CORE_TEMPLATE_NAME;
}
// additional per page Javascript include
$this->JS_INCLUDE = '';
if (
file_exists($this->JAVASCRIPT . $this->JS_TEMPLATE_NAME) &&
is_file($this->JAVASCRIPT . $this->JS_TEMPLATE_NAME)
) {
$this->JS_INCLUDE = $this->JAVASCRIPT . $this->JS_TEMPLATE_NAME;
}
// per page css file
$this->CSS_INCLUDE = '';
if (
file_exists($this->CSS . $this->CSS_TEMPLATE_NAME) &&
is_file($this->CSS . $this->CSS_TEMPLATE_NAME)
) {
$this->CSS_INCLUDE = $this->CSS . $this->CSS_TEMPLATE_NAME;
}
// optional CSS file
$this->CSS_SPECIAL_INCLUDE = '';
if (
file_exists($this->CSS . $this->CSS_SPECIAL_TEMPLATE_NAME) &&
is_file($this->CSS . $this->CSS_SPECIAL_TEMPLATE_NAME)
) {
$this->CSS_SPECIAL_INCLUDE = $this->CSS . $this->CSS_SPECIAL_TEMPLATE_NAME;
}
// optional JS file
$this->JS_SPECIAL_INCLUDE = '';
if (
file_exists($this->JAVASCRIPT . $this->JS_SPECIAL_TEMPLATE_NAME) &&
is_file($this->JAVASCRIPT . $this->JS_SPECIAL_TEMPLATE_NAME)
) {
$this->JS_SPECIAL_INCLUDE = $this->JAVASCRIPT . $this->JS_SPECIAL_TEMPLATE_NAME;
}
}
/**
* sets all internal paths and names that need to be passed on to the smarty template
* @return void
*/
public function setSmartyPaths(): void
{
// master template
if (empty($this->MASTER_TEMPLATE_NAME)) {
$this->MASTER_TEMPLATE_NAME = MASTER_TEMPLATE_NAME;
}
// set include & template names
if (empty($this->CONTENT_INCLUDE)) {
$this->CONTENT_INCLUDE = str_replace('.php', '', $this->page_name) . '.tpl';
}
// strip tpl and replace it with php
// php include file per page
$this->INC_TEMPLATE_NAME = str_replace('.tpl', '.php', $this->CONTENT_INCLUDE);
// javascript include per page
$this->JS_TEMPLATE_NAME = str_replace('.tpl', '.js', $this->CONTENT_INCLUDE);
// css per page
$this->CSS_TEMPLATE_NAME = str_replace('.tpl', '.css', $this->CONTENT_INCLUDE);
// set basic template path (tmp)
$this->INCLUDES = BASE . INCLUDES; // no longer in templates, only global
$this->TEMPLATE_PATH = BASE . INCLUDES . TEMPLATES . CONTENT_PATH;
$this->setTemplateDir($this->TEMPLATE_PATH);
$this->JAVASCRIPT = LAYOUT . JS;
$this->CSS = LAYOUT . CSS;
$this->FONT = LAYOUT . FONT;
$this->PICTURES = LAYOUT . IMAGES;
$this->CACHE_PICTURES = LAYOUT . CACHE;
$this->CACHE_PICTURES_ROOT = ROOT . $this->CACHE_PICTURES;
// check if we have an external file with the template name
if (
file_exists($this->INCLUDES . $this->INC_TEMPLATE_NAME) &&
is_file($this->INCLUDES . $this->INC_TEMPLATE_NAME)
) {
include($this->INCLUDES . $this->INC_TEMPLATE_NAME);
}
// check for template include
if (
$this->USE_INCLUDE_TEMPLATE === true &&
!$this->TEMPLATE_NAME
) {
$this->TEMPLATE_NAME = $this->CONTENT_INCLUDE;
// add to cache & compile id
$this->COMPILE_ID .= '_' . $this->TEMPLATE_NAME;
$this->CACHE_ID .= '_' . $this->TEMPLATE_NAME;
}
// set all the additional CSS/JS parths
$this->setSmartCoreIncludeCssJs();
// check if template names exist
if (!$this->MASTER_TEMPLATE_NAME) {
exit('MASTER TEMPLATE is not set');
} elseif (!file_exists($this->getTemplateDir()[0] . DS . $this->MASTER_TEMPLATE_NAME)) {
// abort if master template could not be found
exit('MASTER TEMPLATE: ' . $this->MASTER_TEMPLATE_NAME . ' could not be found');
}
if (
$this->TEMPLATE_NAME &&
!file_exists($this->getTemplateDir()[0] . DS . $this->TEMPLATE_NAME)
) {
exit('INCLUDE TEMPLATE: ' . $this->TEMPLATE_NAME . ' could not be found');
}
// javascript translate data as template for auto translate
if (empty($this->TEMPLATE_TRANSLATE)) {
$this->TEMPLATE_TRANSLATE = 'jsTranslate_' . $this->lang . '.tpl';
} else {
// we assume we have some fixed set
// we must add _<$this->lang>
// if .tpl, put before .tpl
// if not .tpl, add _<$this->lang>.tpl
if (strpos($this->TEMPLATE_TRANSLATE, '.tpl')) {
$this->TEMPLATE_TRANSLATE = str_replace('.tpl', '_' . $this->lang . '.tpl', $this->TEMPLATE_TRANSLATE);
} else {
$this->TEMPLATE_TRANSLATE .= '_' . $this->lang . '.tpl';
}
}
// if we can't find it, dump it
if (!file_exists($this->getTemplateDir()[0] . DS . $this->TEMPLATE_TRANSLATE)) {
$this->TEMPLATE_TRANSLATE = null;
}
}
/**
* wrapper call for setSmartyVars
* this is for frontend type and will not set any only admin needed variables
* @return void
*/
public function setSmartyVarsFrontend(): void
{
$this->setSmartyVars();
}
/**
* wrapper call for setSmartyVars
* this is only for admin interface and will set additional variables
*/
public function setSmartyVarsAdmin(): void
{
$this->setSmartyVars(true);
}
/**
* set smarty pass on variables, sub template names and finally calls the smarty parser
* @param boolean $admin_call default false, will set admin only variables
* @return void
*/
private function setSmartyVars($admin_call = false): void
{
/** @var \CoreLibs\Admin\Backend This is an assumption */
global $cms;
if (is_object($cms)) {
$this->mergeCmsSmartyVars($cms);
}
// trigger flags
$this->HEADER['USE_PROTOTYPE'] = $this->USE_PROTOTYPE;
// scriptacolous, can only be used with prototype
if ($this->HEADER['USE_PROTOTYPE']) {
$this->HEADER['USE_SCRIPTACULOUS'] = $this->USE_SCRIPTACULOUS;
}
// jquery and prototype should not be used together
$this->HEADER['USE_JQUERY'] = $this->USE_JQUERY;
// set all the additional CSS/JS parths
$this->setSmartCoreIncludeCssJs();
// the actual include files for javascript (per page)
$this->HEADER['JS_CORE_INCLUDE'] = $this->JS_CORE_INCLUDE;
$this->HEADER['CSS_CORE_INCLUDE'] = $this->CSS_CORE_INCLUDE;
$this->HEADER['JS_INCLUDE'] = $this->JS_INCLUDE;
$this->HEADER['CSS_INCLUDE'] = $this->CSS_INCLUDE;
$this->HEADER['CSS_SPECIAL_INCLUDE'] = $this->CSS_SPECIAL_INCLUDE;
$this->HEADER['JS_SPECIAL_INCLUDE'] = $this->JS_SPECIAL_INCLUDE;
// paths to the files
$this->DATA['includes'] = $this->INCLUDES;
$this->DATA['js'] = $this->JAVASCRIPT;
$this->DATA['css'] = $this->CSS;
$this->DATA['pictures'] = $this->PICTURES;
// default CMS settings
// define all needed smarty stuff for the general HTML/page building
$this->HEADER['CSS'] = CSS;
$this->HEADER['FONT'] = FONT;
$this->HEADER['JS'] = JS;
$this->HEADER['ENCODING'] = $this->encoding;
$this->HEADER['DEFAULT_ENCODING'] = DEFAULT_ENCODING;
// form name
$this->DATA['FORM_NAME'] = !$this->FORM_NAME ?
str_replace('.php', '', $this->page_name) :
$this->FORM_NAME;
$this->DATA['FORM_ACTION'] = $this->FORM_ACTION;
// special for admin
if ($admin_call === true) {
// set ACL extra show
if (is_object($cms)) {
$this->DATA['show_ea_extra'] = $cms->acl['show_ea_extra'] ?? false;
$this->DATA['ADMIN'] = $cms->acl['admin'] ?? 0;
// top menu
$this->DATA['nav_menu'] = $cms->adbTopMenu();
$this->DATA['nav_menu_count'] = is_array($this->DATA['nav_menu']) ? count($this->DATA['nav_menu']) : 0;
// messages = ['msg' =>, 'class' => 'error/warning/...']
$this->DATA['messages'] = $cms->messages;
} else { /** @phpstan-ignore-line Because I assume object for phpstan */
$this->DATA['show_ea_extra'] = false;
$this->DATA['ADMIN'] = 0;
$this->DATA['nav_menu'] = [];
$this->DATA['nav_menu_count'] = 0;
$this->DATA['messages'] = [];
}
// set style sheets
$this->HEADER['STYLESHEET'] = $this->ADMIN_STYLESHEET ? $this->ADMIN_STYLESHEET : ADMIN_STYLESHEET;
$this->HEADER['JAVASCRIPT'] = $this->ADMIN_JAVASCRIPT ? $this->ADMIN_JAVASCRIPT : ADMIN_JAVASCRIPT;
// the page name
$this->DATA['page_name'] = $this->page_name;
$this->DATA['table_width'] = empty($this->PAGE_WIDTH) ?: PAGE_WIDTH;
$this->DATA['form_name'] = $this->DATA['FORM_NAME'];
// for tinymce special
$this->DATA['TINYMCE_LANG'] = $this->lang_short;
// include flags
$this->DATA['USE_TINY_MCE'] = $this->USE_TINY_MCE;
// debug data, if DEBUG flag is on, this data is print out
$this->DEBUG_DATA['DEBUG'] = $this->DEBUG_TMPL;
} else {
$this->HEADER['STYLESHEET'] = $this->FRONTEND_STYLESHEET ? $this->FRONTEND_STYLESHEET : STYLESHEET;
$this->HEADER['JAVASCRIPT'] = $this->FRONTEND_JAVASCRIPT ? $this->FRONTEND_JAVASCRIPT : JAVASCRIPT;
}
// html title
// set local page title
$this->HEADER['HTML_TITLE'] = !$this->L_TITLE ?
ucfirst(str_replace('_', ' ', \CoreLibs\Get\System::getPageName(1)))
. (defined('G_TITLE') ? ' - ' . $this->l10n->__(G_TITLE) : '') :
$this->l10n->__($this->L_TITLE);
// LANG
$this->DATA['LANG'] = $this->lang;
// include flags
$this->DATA['JS_DATEPICKR'] = $this->JS_DATEPICKR;
$this->DATA['JS_FLATPICKR'] = $this->JS_FLATPICKR;
$this->DATA['JS_FILE_UPLOADER'] = $this->JS_FILE_UPLOADER;
// user name
$this->DATA['USER_NAME'] = !empty($_SESSION['USER_NAME']) ? $_SESSION['USER_NAME'] : '';
// the template part to include into the body
$this->DATA['TEMPLATE_NAME'] = $this->TEMPLATE_NAME;
$this->DATA['CONTENT_INCLUDE'] = $this->CONTENT_INCLUDE;
$this->DATA['TEMPLATE_TRANSLATE'] = $this->TEMPLATE_TRANSLATE ?? null;
$this->DATA['PAGE_FILE_NAME'] = str_replace('.php', '', $this->page_name) . '.tpl';
// render page
$this->renderSmarty();
}
/**
* merge outside object HEADER/DATA/DEBUG_DATA vars into the smarty class
* @param object $cms object that has header/data/debug_data
* @return void
*/
public function mergeCmsSmartyVars(object $cms): void
{
// array merge HEADER, DATA, DEBUG DATA
foreach (['HEADER', 'DATA', 'DEBUG_DATA'] as $ext_smarty) {
if (
isset($cms->{$ext_smarty}) &&
is_array($cms->{$ext_smarty})
) {
$this->{$ext_smarty} = array_merge($this->{$ext_smarty}, $cms->{$ext_smarty});
}
}
}
/**
* render smarty data (can be called sepparate)
* @return void
*/
public function renderSmarty(): void
{
// create main data array
$this->CONTENT_DATA = array_merge($this->HEADER, $this->DATA, $this->DEBUG_DATA);
// data is 1:1 mapping (all vars, values, etc)
foreach ($this->CONTENT_DATA as $key => $value) {
$this->assign($key, $value);
}
if (is_dir(BASE . TEMPLATES_C)) {
$this->setCompileDir(BASE . TEMPLATES_C);
}
if (is_dir(BASE . CACHE)) {
$this->setCacheDir(BASE . CACHE);
}
$this->display(
$this->MASTER_TEMPLATE_NAME,
$this->CACHE_ID . ($this->CACHE_ID ? '_' : '') . $this->lang,
$this->COMPILE_ID . ($this->COMPILE_ID ? '_' : '') . $this->lang
);
}
}
// __END__

View File

@@ -1 +1 @@
smarty-3.1.30/
smarty-4.1.0/libs/

View File

@@ -1,22 +0,0 @@
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain

View File

@@ -1,222 +0,0 @@
#################
## Eclipse
#################
*.pydevproject
.project
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# PDT-specific
.buildpath
#################
## Visual Studio
#################
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Rr]elease/
x64/
build/
[Bb]in/
[Oo]bj/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.scc
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.Publish.xml
*.pubxml
# NuGet Packages Directory
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
#packages/
# Windows Azure Build Output
csx
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.[Pp]ublish.xml
*.pfx
*.publishsettings
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
App_Data/*.mdf
App_Data/*.ldf
#############
## Windows detritus
#############
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Mac crap
.DS_Store
#############
## Python
#############
*.py[co]
# Packages
*.egg
*.egg-info
dist/
build/
eggs/
parts/
var/
sdist/
develop-eggs/
.installed.cfg
# Installer logs
pip-log.txt
# Unit test / coverage reports
.coverage
.tox
#Translations
*.mo
#Mr Developer
.mr.developer.cfg
.idea/
.idea\
# Smarty
lexer/*.php
lexer/*.out

View File

@@ -1,18 +0,0 @@
language: php
php:
- 5.3
- 5.4
- 5.5
- 5.6
allow_failures:
- php: hhvm
install:
- git clone --depth=50 --branch=master git://github.com/smarty-php/smarty-phpunit.git
script:
- cd smarty-phpunit
- phpunit ./

View File

@@ -1,455 +0,0 @@
<?php
/**
* Project: Smarty: the PHP compiling template engine
* File: SmartyBC.class.php
* SVN: $Id: $
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* For questions, help, comments, discussion, etc., please join the
* Smarty mailing list. Send a blank e-mail to
* smarty-discussion-subscribe@googlegroups.com
*
* @link http://www.smarty.net/
* @copyright 2008 New Digital Group, Inc.
* @author Monte Ohrt <monte at ohrt dot com>
* @author Uwe Tews
* @author Rodney Rehm
* @package Smarty
*/
/**
* @ignore
*/
require_once(dirname(__FILE__) . '/Smarty.class.php');
/**
* Smarty Backward Compatibility Wrapper Class
*
* @package Smarty
*/
class SmartyBC extends Smarty
{
/**
* Smarty 2 BC
*
* @var string
*/
public $_version = self::SMARTY_VERSION;
/**
* This is an array of directories where trusted php scripts reside.
*
* @var array
*/
public $trusted_dir = array();
/**
* Initialize new SmartyBC object
*
*/
public function __construct()
{
parent::__construct();
}
/**
* 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);
}
/**
* Unregister custom function
*
* @param string $function name of template function
*/
public function unregister_function($function)
{
$this->unregisterPlugin('function', $function);
}
/**
* Registers object to be used in templates
*
* @param string $object name of template object
* @param object $object_impl the referenced PHP object to register
* @param array $allowed list of allowed methods (empty = all)
* @param boolean $smarty_args smarty argument format, else traditional
* @param array $block_methods list of methods that are block format
*
* @throws SmartyException
* @internal param array $block_functs list of methods that are block format
*/
public function register_object($object, $object_impl, $allowed = array(), $smarty_args = true,
$block_methods = array())
{
settype($allowed, 'array');
settype($smarty_args, 'boolean');
$this->registerObject($object, $object_impl, $allowed, $smarty_args, $block_methods);
}
/**
* Unregister 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);
}
/**
* Unregister 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);
}
/**
* Unregister 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);
}
/**
* Unregister 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);
}
/**
* Unregister 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);
}
/**
* Unregister 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);
}
/**
* Unregister 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);
}
/**
* Unregister 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);
}
}

View File

@@ -1,51 +0,0 @@
<?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
* @param $compiler
*
* @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) {
if ($compiler->template->caching && ($compiler->tag_nocache | $compiler->nocache)) {
$compiler->parent_compiler->template->compiled->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->parent_compiler->template->compiled->required_plugins[ 'compiled' ][ 'wordwrap' ][ 'modifier' ][ 'file' ] =
SMARTY_PLUGINS_DIR . 'shared.mb_wordwrap.php';
$compiler->parent_compiler->template->compiled->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

@@ -1,34 +0,0 @@
<?php
/**
* Smarty shared plugin
*
* @package Smarty
* @subpackage PluginsShared
*/
/**
* 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)) {
if (version_compare(PHP_VERSION, '5.2.3', '>=')) {
$string = htmlspecialchars($string, ENT_COMPAT, Smarty::$_CHARSET, false);
} else {
$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

@@ -1,75 +0,0 @@
<?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)!S' . Smarty::$_UTF8_MODIFIER, $str, - 1, PREG_SPLIT_NO_EMPTY + PREG_SPLIT_DELIM_CAPTURE);
$length = 0;
$t = '';
$_previous = false;
$_space = false;
foreach ($tokens as $_token) {
$token_length = mb_strlen($_token, Smarty::$_CHARSET);
$_tokens = array($_token);
if ($token_length > $width) {
if ($cut) {
$_tokens = preg_split('!(.{' . $width . '})!S' . Smarty::$_UTF8_MODIFIER, $_token, - 1,
PREG_SPLIT_NO_EMPTY + PREG_SPLIT_DELIM_CAPTURE);
}
}
foreach ($_tokens as $token) {
$_space = !!preg_match('!^\s$!S' . Smarty::$_UTF8_MODIFIER, $token);
$token_length = mb_strlen($token, Smarty::$_CHARSET);
$length += $token_length;
if ($length > $width) {
// remove space before inserted break
if ($_previous) {
$t = mb_substr($t, 0, - 1, Smarty::$_CHARSET);
}
if (!$_space) {
// add the break before the token
if (!empty($t)) {
$t .= $break;
}
$length = $token_length;
}
} elseif ($token == "\n") {
// hard break must reset counters
$_previous = 0;
$length = 0;
}
$_previous = $_space;
// add the token
$t .= $token;
}
}
return $t;
}
}

View File

@@ -1,77 +0,0 @@
<?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 \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
*
* @return string compiled code
* @throws \SmartyCompilerException
*/
public function compile($args, Smarty_Internal_TemplateCompilerBase $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', null, true);
}
if (isset($_attr[ 'levels' ])) {
if (!is_numeric($_attr[ 'levels' ])) {
$compiler->trigger_template_error('level attribute must be a numeric constant', null, true);
}
$_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)", null, true);
}
return "<?php break {$_levels};?>";
}
}

View File

@@ -1,77 +0,0 @@
<?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 \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
*
* @return string compiled code
* @throws \SmartyCompilerException
*/
public function compile($args, Smarty_Internal_TemplateCompilerBase $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', null, true);
}
if (isset($_attr[ 'levels' ])) {
if (!is_numeric($_attr[ 'levels' ])) {
$compiler->trigger_template_error('level attribute must be a numeric constant', null, true);
}
$_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)", null, true);
}
return "<?php continue {$_levels};?>";
}
}

View File

@@ -1,111 +0,0 @@
<?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 \Smarty_Internal_TemplateCompilerBase $compiler compiler object
*
* @return string
* @throws \SmartyCompilerException
* @throws \SmartyException
*/
public function compile($args, Smarty_Internal_TemplateCompilerBase $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);
/** @var Smarty_Internal_Template $_smarty_tpl
* used in evaluated code
*/
$_smarty_tpl = $compiler->template;
$_filepath = false;
$_file = null;
eval('$_file = @' . $_attr[ 'file' ] . ';');
if (!isset($compiler->smarty->security_policy) && file_exists($_file)) {
$_filepath = $compiler->smarty->_realpath($_file, true);
} 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) {
$_path = $compiler->smarty->_realpath($_script_dir . DS . $_file, true);
if (file_exists($_path)) {
$_filepath = $_path;
break;
}
}
}
}
if ($_filepath == false) {
$compiler->trigger_template_error("{include_php} file '{$_file}' is not readable", null, true);
}
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();\ninclude{$_once} ('{$_filepath}');\n\$_smarty_tpl->assign({$_assign},ob_get_clean());\n?>";
} else {
return "<?php include{$_once} ('{$_filepath}');?>\n";
}
}
}

View File

@@ -1,220 +0,0 @@
<?php
/**
* Smarty Internal Plugin Compile PHP Expression
* Compiles any tag which will output an expression or variable
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
/**
* Smarty Internal Plugin Compile PHP Expression Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Private_Php extends Smarty_Internal_CompileBase
{
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $required_attributes = array('code', 'type');
/**
* Compiles code for generating output from any expression
*
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
*
* @return string
* @throws \SmartyException
*/
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
{
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
$compiler->has_code = false;
if ($_attr[ 'type' ] == 'xml') {
$compiler->tag_nocache = true;
$save = $compiler->template->compiled->has_nocache_code;
$output = addcslashes($_attr[ 'code' ], "'\\");
$compiler->parser->current_buffer->append_subtree($compiler->parser,
new Smarty_Internal_ParseTree_Tag($compiler->parser,
$compiler->processNocacheCode("<?php echo '" .
$output .
"';?>",
true)));
$compiler->template->compiled->has_nocache_code = $save;
return '';
}
if ($_attr[ 'type' ] != 'tag') {
if ($compiler->php_handling == Smarty::PHP_REMOVE) {
return '';
} elseif ($compiler->php_handling == Smarty::PHP_QUOTE) {
$output =
preg_replace_callback('#(<\?(?:php|=)?)|(<%)|(<script\s+language\s*=\s*["\']?\s*php\s*["\']?\s*>)|(\?>)|(%>)|(<\/script>)#i',
array($this, 'quote'), $_attr[ 'code' ]);
$compiler->parser->current_buffer->append_subtree($compiler->parser,
new Smarty_Internal_ParseTree_Text($output));
return '';
} elseif ($compiler->php_handling == Smarty::PHP_PASSTHRU || $_attr[ 'type' ] == 'unmatched') {
$compiler->tag_nocache = true;
$save = $compiler->template->compiled->has_nocache_code;
$output = addcslashes($_attr[ 'code' ], "'\\");
$compiler->parser->current_buffer->append_subtree($compiler->parser,
new Smarty_Internal_ParseTree_Tag($compiler->parser,
$compiler->processNocacheCode("<?php echo '" .
$output .
"';?>",
true)));
$compiler->template->compiled->has_nocache_code = $save;
return '';
} elseif ($compiler->php_handling == Smarty::PHP_ALLOW) {
if (!($compiler->smarty instanceof SmartyBC)) {
$compiler->trigger_template_error('$smarty->php_handling PHP_ALLOW not allowed. Use SmartyBC to enable it',
null, true);
}
$compiler->has_code = true;
return $_attr[ 'code' ];
} else {
$compiler->trigger_template_error('Illegal $smarty->php_handling value', null, true);
}
} else {
$compiler->has_code = true;
if (!($compiler->smarty instanceof SmartyBC)) {
$compiler->trigger_template_error('{php}{/php} tags not allowed. Use SmartyBC to enable them', null,
true);
}
$ldel = preg_quote($compiler->smarty->left_delimiter, '#');
$rdel = preg_quote($compiler->smarty->right_delimiter, '#');
preg_match("#^({$ldel}php\\s*)((.)*?)({$rdel})#", $_attr[ 'code' ], $match);
if (!empty($match[ 2 ])) {
if ('nocache' == trim($match[ 2 ])) {
$compiler->tag_nocache = true;
} else {
$compiler->trigger_template_error("illegal value of option flag \"{$match[2]}\"", null, true);
}
}
return preg_replace(array("#^{$ldel}\\s*php\\s*(.)*?{$rdel}#", "#{$ldel}\\s*/\\s*php\\s*{$rdel}$#"),
array('<?php ', '?>'), $_attr[ 'code' ]);
}
}
/**
* Lexer code for PHP tags
*
* This code has been moved from lexer here fo easier debugging and maintenance
*
* @param $lex
*/
public function parsePhp($lex)
{
$lex->token = Smarty_Internal_Templateparser::TP_PHP;
$close = 0;
$lex->taglineno = $lex->line;
$closeTag = '?>';
if (strpos($lex->value, '<?xml') === 0) {
$lex->is_xml = true;
$lex->token = Smarty_Internal_Templateparser::TP_NOCACHE;
return;
} elseif (strpos($lex->value, '<?') === 0) {
$lex->phpType = 'php';
} elseif (strpos($lex->value, '<%') === 0) {
$lex->phpType = 'asp';
$closeTag = '%>';
} elseif (strpos($lex->value, '%>') === 0) {
$lex->phpType = 'unmatched';
} elseif (strpos($lex->value, '?>') === 0) {
if ($lex->is_xml) {
$lex->is_xml = false;
$lex->token = Smarty_Internal_Templateparser::TP_NOCACHE;
return;
}
$lex->phpType = 'unmatched';
} elseif (strpos($lex->value, '<s') === 0) {
$lex->phpType = 'script';
$closeTag = '</script>';
} elseif (strpos($lex->value, $lex->smarty->left_delimiter) === 0) {
if ($lex->isAutoLiteral()) {
$lex->token = Smarty_Internal_Templateparser::TP_TEXT;
return;
}
$closeTag = "{$lex->smarty->left_delimiter}/php{$lex->smarty->right_delimiter}";
if ($lex->value == $closeTag) {
$lex->compiler->trigger_template_error("unexpected closing tag '{$closeTag}'");
}
$lex->phpType = 'tag';
}
if ($lex->phpType == 'unmatched') {
return;
}
if (($lex->phpType == 'php' || $lex->phpType == 'asp') &&
($lex->compiler->php_handling == Smarty::PHP_PASSTHRU || $lex->compiler->php_handling == Smarty::PHP_QUOTE)
) {
return;
}
$start = $lex->counter + strlen($lex->value);
$body = true;
if (preg_match('~' . preg_quote($closeTag, '~') . '~i', $lex->data, $match, PREG_OFFSET_CAPTURE, $start)) {
$close = $match[ 0 ][ 1 ];
} else {
$lex->compiler->trigger_template_error("missing closing tag '{$closeTag}'");
}
while ($body) {
if (preg_match('~([/][*])|([/][/][^\n]*)|(\'[^\'\\\\]*(?:\\.[^\'\\\\]*)*\')|("[^"\\\\]*(?:\\.[^"\\\\]*)*")~',
$lex->data, $match, PREG_OFFSET_CAPTURE, $start)) {
$value = $match[ 0 ][ 0 ];
$from = $pos = $match[ 0 ][ 1 ];
if ($pos > $close) {
$body = false;
} else {
$start = $pos + strlen($value);
$phpCommentStart = $value == '/*';
if ($phpCommentStart) {
$phpCommentEnd = preg_match('~([*][/])~', $lex->data, $match, PREG_OFFSET_CAPTURE, $start);
if ($phpCommentEnd) {
$pos2 = $match[ 0 ][ 1 ];
$start = $pos2 + strlen($match[ 0 ][ 0 ]);
}
}
while ($close > $pos && $close < $start) {
if (preg_match('~' . preg_quote($closeTag, '~') . '~i', $lex->data, $match, PREG_OFFSET_CAPTURE,
$from)) {
$close = $match[ 0 ][ 1 ];
$from = $close + strlen($match[ 0 ][ 0 ]);
} else {
$lex->compiler->trigger_template_error("missing closing tag '{$closeTag}'");
}
}
if ($phpCommentStart && (!$phpCommentEnd || $pos2 > $close)) {
$lex->taglineno = $lex->line + substr_count(substr($lex->data, $lex->counter, $start), "\n");
$lex->compiler->trigger_template_error("missing PHP comment closing tag '*/'");
}
}
} else {
$body = false;
}
}
$lex->value = substr($lex->data, $lex->counter, $close + strlen($closeTag) - $lex->counter);
}
/*
* Call back function for $php_handling = PHP_QUOTE
*
*/
/**
* @param $match
*
* @return string
*/
private function quote($match)
{
return htmlspecialchars($match[ 0 ], ENT_QUOTES);
}
}

View File

@@ -1,147 +0,0 @@
<?php
/**
* Smarty Extension handler
*
* Load extensions dynamically
*
*
* @package Smarty
* @subpackage PluginsInternal
* @author Uwe Tews
*
* @property Smarty_Internal_Runtime_TplFunction $_tplFunction
* @property Smarty_Internal_Runtime_Foreach $_foreach
* @property Smarty_Internal_Runtime_WriteFile $_writeFile
* @property Smarty_Internal_Runtime_CodeFrame $_codeFrame
* @property Smarty_Internal_Runtime_FilterHandler $_filterHandler
* @property Smarty_Internal_Runtime_GetIncludePath $_getIncludePath
* @property Smarty_Internal_Runtime_UpdateScope $_updateScope
* @property Smarty_Internal_Runtime_CacheModify $_cacheModify
* @property Smarty_Internal_Runtime_UpdateCache $_updateCache
* @property Smarty_Internal_Method_GetTemplateVars $getTemplateVars
* @property Smarty_Internal_Method_Append $append
* @property Smarty_Internal_Method_AppendByRef $appendByRef
* @property Smarty_Internal_Method_AssignGlobal $assignGlobal
* @property Smarty_Internal_Method_AssignByRef $assignByRef
* @property Smarty_Internal_Method_LoadFilter $loadFilter
* @property Smarty_Internal_Method_LoadPlugin $loadPlugin
* @property Smarty_Internal_Method_RegisterFilter $registerFilter
* @property Smarty_Internal_Method_RegisterObject $registerObject
* @property Smarty_Internal_Method_RegisterPlugin $registerPlugin
*/
class Smarty_Internal_Extension_Handler
{
public $objType = null;
/**
* Cache for property information from generic getter/setter
* Preloaded with names which should not use with generic getter/setter
*
* @var array
*/
private $_property_info = array('AutoloadFilters' => 0, 'DefaultModifiers' => 0, 'ConfigVars' => 0,
'DebugTemplate' => 0, 'RegisteredObject' => 0, 'StreamVariable' => 0,
'TemplateVars' => 0,);#
private $resolvedProperties = array();
/**
* Call external Method
*
* @param \Smarty_Internal_Data $data
* @param string $name external method names
* @param array $args argument array
*
* @return mixed
* @throws SmartyException
*/
public function _callExternalMethod(Smarty_Internal_Data $data, $name, $args)
{
/* @var Smarty $data ->smarty */
$smarty = isset($data->smarty) ? $data->smarty : $data;
if (!isset($smarty->ext->$name)) {
$class = 'Smarty_Internal_Method_' . ucfirst($name);
if (preg_match('/^(set|get)([A-Z].*)$/', $name, $match)) {
if (!isset($this->_property_info[ $prop = $match[ 2 ] ])) {
// convert camel case to underscored name
$this->resolvedProperties[ $prop ] = $pn = strtolower(join('_',
preg_split('/([A-Z][^A-Z]*)/', $prop,
- 1, PREG_SPLIT_NO_EMPTY |
PREG_SPLIT_DELIM_CAPTURE)));
$this->_property_info[ $prop ] = property_exists($data, $pn) ? 1 :
($data->_objType == 2 && property_exists($smarty, $pn) ? 2 : 0);
}
if ($this->_property_info[ $prop ]) {
$pn = $this->resolvedProperties[ $prop ];
if ($match[ 1 ] == 'get') {
return $this->_property_info[ $prop ] == 1 ? $data->$pn : $data->smarty->$pn;
} else {
return $this->_property_info[ $prop ] == 1 ? $data->$pn = $args[ 0 ] :
$data->smarty->$pn = $args[ 0 ];
}
} elseif (!class_exists($class)) {
throw new SmartyException("property '$pn' does not exist.");
}
}
if (class_exists($class)) {
$callback = array($smarty->ext->$name = new $class(), $name);
}
} else {
$callback = array($smarty->ext->$name, $name);
}
array_unshift($args, $data);
if (isset($callback) && $callback[ 0 ]->objMap | $data->_objType) {
return call_user_func_array($callback, $args);
}
return call_user_func_array(array(new Smarty_Internal_Undefined(), $name), $args);
}
/**
* set extension property
*
* @param string $property_name property name
* @param mixed $value value
*
* @throws SmartyException
*/
public function __set($property_name, $value)
{
$this->$property_name = $value;
}
/**
* get extension object
*
* @param string $property_name property name
*
* @return mixed|Smarty_Template_Cached
* @throws SmartyException
*/
public function __get($property_name)
{
// object properties of runtime template extensions will start with '_'
if ($property_name[ 0 ] == '_') {
$class = 'Smarty_Internal_Runtime_' . ucfirst(substr($property_name, 1));
} else {
$class = 'Smarty_Internal_Method_' . ucfirst($property_name);
}
return $this->$property_name = new $class();
}
/**
* Call error handler for undefined method
*
* @param string $name unknown method-name
* @param array $args argument array
*
* @return mixed
* @throws SmartyException
*/
public function __call($name, $args)
{
return call_user_func_array(array(new Smarty_Internal_Undefined(), $name), array($this));
}
}

View File

@@ -1,44 +0,0 @@
<?php
/**
* Smarty Method RegisterResource
*
* Smarty::registerResource() method
*
* @package Smarty
* @subpackage PluginsInternal
* @author Uwe Tews
*/
class Smarty_Internal_Method_RegisterResource
{
/**
* Valid for Smarty and template object
*
* @var int
*/
public $objMap = 3;
/**
* Registers a resource to fetch a template
*
* @api Smarty::registerResource()
* @link http://www.smarty.net/docs/en/api.register.resource.tpl
*
* @param \Smarty_Internal_TemplateBase|\Smarty_Internal_Template|\Smarty $obj
* @param string $name name of resource type
* @param Smarty_Resource|array $resource_handler or instance of
* Smarty_Resource, or
* array of callbacks to
* handle resource
* (deprecated)
*
* @return \Smarty|\Smarty_Internal_Template
*/
public function registerResource(Smarty_Internal_TemplateBase $obj, $name, $resource_handler)
{
$smarty = isset($obj->smarty) ? $obj->smarty : $obj;
$smarty->registered_resources[ $name ] =
$resource_handler instanceof Smarty_Resource ? $resource_handler : array($resource_handler, false);
return $obj;
}
}

View File

@@ -1,128 +0,0 @@
<?php
/**
* Smarty Internal Plugin Templateparser Parse Tree
* These are classes to build parse tree in the template parser
*
* @package Smarty
* @subpackage Compiler
* @author Thue Kristensen
* @author Uwe Tews
*/
/**
* Template element
*
* @package Smarty
* @subpackage Compiler
* @ignore
*/
class Smarty_Internal_ParseTree_Template extends Smarty_Internal_ParseTree
{
/**
* Array of template elements
*
* @var array
*/
public $subtrees = Array();
/**
* Create root of parse tree for template elements
*
*/
public function __construct()
{
}
/**
* Append buffer to subtree
*
* @param \Smarty_Internal_Templateparser $parser
* @param Smarty_Internal_ParseTree $subtree
*/
public function append_subtree(Smarty_Internal_Templateparser $parser, Smarty_Internal_ParseTree $subtree)
{
if (!empty($subtree->subtrees)) {
$this->subtrees = array_merge($this->subtrees, $subtree->subtrees);
} else {
if ($subtree->data !== '') {
$this->subtrees[] = $subtree;
}
}
}
/**
* Append array to subtree
*
* @param \Smarty_Internal_Templateparser $parser
* @param \Smarty_Internal_ParseTree[] $array
*/
public function append_array(Smarty_Internal_Templateparser $parser, $array = array())
{
if (!empty($array)) {
$this->subtrees = array_merge($this->subtrees, (array) $array);
}
}
/**
* Prepend array to subtree
*
* @param \Smarty_Internal_Templateparser $parser
* @param \Smarty_Internal_ParseTree[] $array
*/
public function prepend_array(Smarty_Internal_Templateparser $parser, $array = array())
{
if (!empty($array)) {
$this->subtrees = array_merge((array) $array, $this->subtrees);
}
}
/**
* Sanitize and merge subtree buffers together
*
* @param \Smarty_Internal_Templateparser $parser
*
* @return string template code content
*/
public function to_smarty_php(Smarty_Internal_Templateparser $parser)
{
$code = '';
for ($key = 0, $cnt = count($this->subtrees); $key < $cnt; $key ++) {
if ($this->subtrees[ $key ] instanceof Smarty_Internal_ParseTree_Text) {
$subtree = $this->subtrees[ $key ]->to_smarty_php($parser);
while ($key + 1 < $cnt && ($this->subtrees[ $key + 1 ] instanceof Smarty_Internal_ParseTree_Text ||
$this->subtrees[ $key + 1 ]->data == '')) {
$key ++;
if ($this->subtrees[ $key ]->data == '') {
continue;
}
$subtree .= $this->subtrees[ $key ]->to_smarty_php($parser);
}
if ($subtree == '') {
continue;
}
$code .= preg_replace('/((<%)|(%>)|(<\?php)|(<\?)|(\?>)|(<\/?script))/', "<?php echo '\$1'; ?>\n",
$subtree);
continue;
}
if ($this->subtrees[ $key ] instanceof Smarty_Internal_ParseTree_Tag) {
$subtree = $this->subtrees[ $key ]->to_smarty_php($parser);
while ($key + 1 < $cnt && ($this->subtrees[ $key + 1 ] instanceof Smarty_Internal_ParseTree_Tag ||
$this->subtrees[ $key + 1 ]->data == '')) {
$key ++;
if ($this->subtrees[ $key ]->data == '') {
continue;
}
$subtree = $parser->compiler->appendCode($subtree, $this->subtrees[ $key ]->to_smarty_php($parser));
}
if ($subtree == '') {
continue;
}
$code .= $subtree;
continue;
}
$code .= $this->subtrees[ $key ]->to_smarty_php($parser);
}
return $code;
}
}

View File

@@ -1,99 +0,0 @@
<?php
/**
* Smarty Internal Plugin Resource Registered
*
* @package Smarty
* @subpackage TemplateResources
* @author Uwe Tews
* @author Rodney Rehm
*/
/**
* Smarty Internal Plugin Resource Registered
* Implements the registered resource for Smarty template
*
* @package Smarty
* @subpackage TemplateResources
* @deprecated
*/
class Smarty_Internal_Resource_Registered extends Smarty_Resource
{
/**
* populate Source Object with meta data from Resource
*
* @param Smarty_Template_Source $source source object
* @param Smarty_Internal_Template $_template template object
*
* @return void
*/
public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template = null)
{
$source->filepath = $source->type . ':' . $source->name;
$source->uid = sha1($source->filepath . $source->smarty->_joined_template_dir);
$source->timestamp = $this->getTemplateTimestamp($source);
$source->exists = !!$source->timestamp;
}
/**
* populate Source Object with timestamp and exists from Resource
*
* @param Smarty_Template_Source $source source object
*
* @return void
*/
public function populateTimestamp(Smarty_Template_Source $source)
{
$source->timestamp = $this->getTemplateTimestamp($source);
$source->exists = !!$source->timestamp;
}
/**
* Get timestamp (epoch) the template source was modified
*
* @param Smarty_Template_Source $source source object
*
* @return integer|boolean timestamp (epoch) the template was modified, false if resources has no timestamp
*/
public function getTemplateTimestamp(Smarty_Template_Source $source)
{
// return timestamp
$time_stamp = false;
call_user_func_array($source->smarty->registered_resources[ $source->type ][ 0 ][ 1 ],
array($source->name, &$time_stamp, $source->smarty));
return is_numeric($time_stamp) ? (int) $time_stamp : $time_stamp;
}
/**
* Load template's source by invoking the registered callback into current template object
*
* @param Smarty_Template_Source $source source object
*
* @return string template source
* @throws SmartyException if source cannot be loaded
*/
public function getContent(Smarty_Template_Source $source)
{
// return template string
$content = null;
$t = call_user_func_array($source->smarty->registered_resources[ $source->type ][ 0 ][ 0 ],
array($source->name, &$content, $source->smarty));
if (is_bool($t) && !$t) {
throw new SmartyException("Unable to read template {$source->type} '{$source->name}'");
}
return $content;
}
/**
* Determine basename for compiled filename
*
* @param Smarty_Template_Source $source source object
*
* @return string resource's basename
*/
public function getBasename(Smarty_Template_Source $source)
{
return basename($source->name);
}
}

View File

@@ -1,98 +0,0 @@
<?php
/**
* Smarty Internal Extension
* This file contains the Smarty template extension to create a code frame
*
* @package Smarty
* @subpackage Template
* @author Uwe Tews
*/
/**
* Class Smarty_Internal_Extension_CodeFrame
* Create code frame for compiled and cached templates
*/
class Smarty_Internal_Runtime_CodeFrame
{
/**
* Create code frame for compiled and cached templates
*
* @param Smarty_Internal_Template $_template
* @param string $content optional template content
* @param string $functions compiled template function and block code
* @param bool $cache flag for cache file
* @param \Smarty_Internal_TemplateCompilerBase $compiler
*
* @return string
*/
public function create(Smarty_Internal_Template $_template, $content = '', $functions = '', $cache = false,
Smarty_Internal_TemplateCompilerBase $compiler = null)
{
// build property code
$properties[ 'version' ] = Smarty::SMARTY_VERSION;
$properties[ 'unifunc' ] = 'content_' . str_replace(array('.', ','), '_', uniqid('', true));
if (!$cache) {
$properties[ 'has_nocache_code' ] = $_template->compiled->has_nocache_code;
$properties[ 'file_dependency' ] = $_template->compiled->file_dependency;
$properties[ 'includes' ] = $_template->compiled->includes;
} else {
$properties[ 'has_nocache_code' ] = $_template->cached->has_nocache_code;
$properties[ 'file_dependency' ] = $_template->cached->file_dependency;
$properties[ 'cache_lifetime' ] = $_template->cache_lifetime;
}
$output = "<?php\n";
$output .= "/* Smarty version " . Smarty::SMARTY_VERSION . ", created on " . strftime("%Y-%m-%d %H:%M:%S") .
"\n from \"" . $_template->source->filepath . "\" */\n\n";
$output .= "/* @var Smarty_Internal_Template \$_smarty_tpl */\n";
$dec = "\$_smarty_tpl->_decodeProperties(\$_smarty_tpl, " . var_export($properties, true) . ',' .
($cache ? 'true' : 'false') . ")";
$output .= "if ({$dec}) {\n";
$output .= "function {$properties['unifunc']} (Smarty_Internal_Template \$_smarty_tpl) {\n";
if (!$cache && !empty($compiler->tpl_function)) {
$output .= "\$_smarty_tpl->ext->_tplFunction->registerTplFunctions(\$_smarty_tpl, " .
var_export($compiler->tpl_function, true) . ");\n";
}
if ($cache && isset($_template->ext->_tplFunction)) {
$output .= "\$_smarty_tpl->ext->_tplFunction->registerTplFunctions(\$_smarty_tpl, " .
var_export($_template->ext->_tplFunction->getTplFunction(), true) . ");\n";
}
// include code for plugins
if (!$cache) {
if (!empty($_template->compiled->required_plugins[ 'compiled' ])) {
foreach ($_template->compiled->required_plugins[ 'compiled' ] as $tmp) {
foreach ($tmp as $data) {
$file = addslashes($data[ 'file' ]);
if (is_array($data[ 'function' ])) {
$output .= "if (!is_callable(array('{$data['function'][0]}','{$data['function'][1]}'))) require_once '{$file}';\n";
} else {
$output .= "if (!is_callable('{$data['function']}')) require_once '{$file}';\n";
}
}
}
}
if ($_template->caching && !empty($_template->compiled->required_plugins[ 'nocache' ])) {
$_template->compiled->has_nocache_code = true;
$output .= "echo '/*%%SmartyNocache:{$_template->compiled->nocache_hash}%%*/<?php \$_smarty = \$_smarty_tpl->smarty; ";
foreach ($_template->compiled->required_plugins[ 'nocache' ] as $tmp) {
foreach ($tmp as $data) {
$file = addslashes($data[ 'file' ]);
if (is_array($data[ 'function' ])) {
$output .= addslashes("if (!is_callable(array('{$data['function'][0]}','{$data['function'][1]}'))) require_once '{$file}';\n");
} else {
$output .= addslashes("if (!is_callable('{$data['function']}')) require_once '{$file}';\n");
}
}
}
$output .= "?>/*/%%SmartyNocache:{$_template->compiled->nocache_hash}%%*/';\n";
}
}
$output .= "?>\n";
$output .= $content;
$output .= "<?php }\n?>";
$output .= $functions;
$output .= "<?php }\n";
// remove unneeded PHP tags
return preg_replace(array('/\s*\?>[\n]?<\?php\s*/', '/\?>\s*$/'), array("\n", ''), $output);
}
}

View File

@@ -1,595 +0,0 @@
<?php
/**
* Smarty Internal TestInstall
* Test Smarty installation
*
* @package Smarty
* @subpackage Utilities
* @author Uwe Tews
*/
/**
* TestInstall class
*
* @package Smarty
* @subpackage Utilities
*/
class Smarty_Internal_TestInstall
{
/**
* diagnose Smarty setup
* If $errors is secified, the diagnostic report will be appended to the array, rather than being output.
*
* @param \Smarty $smarty
* @param array $errors array to push results into rather than outputting them
*
* @return bool status, true if everything is fine, false else
*/
public static function testInstall(Smarty $smarty, &$errors = null)
{
$status = true;
if ($errors === null) {
echo "<PRE>\n";
echo "Smarty Installation test...\n";
echo "Testing template directory...\n";
}
$_stream_resolve_include_path = function_exists('stream_resolve_include_path');
// test if all registered template_dir are accessible
foreach ($smarty->getTemplateDir() as $template_dir) {
$_template_dir = $template_dir;
$template_dir = realpath($template_dir);
// resolve include_path or fail existence
if (!$template_dir) {
if ($smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_template_dir)) {
// try PHP include_path
if ($_stream_resolve_include_path) {
$template_dir = stream_resolve_include_path($_template_dir);
} else {
$template_dir = $smarty->ext->_getIncludePath->getIncludePath($_template_dir, null, $smarty);
}
if ($template_dir !== false) {
if ($errors === null) {
echo "$template_dir is OK.\n";
}
continue;
} else {
$status = false;
$message =
"FAILED: $_template_dir does not exist (and couldn't be found in include_path either)";
if ($errors === null) {
echo $message . ".\n";
} else {
$errors[ 'template_dir' ] = $message;
}
continue;
}
} else {
$status = false;
$message = "FAILED: $_template_dir does not exist";
if ($errors === null) {
echo $message . ".\n";
} else {
$errors[ 'template_dir' ] = $message;
}
continue;
}
}
if (!is_dir($template_dir)) {
$status = false;
$message = "FAILED: $template_dir is not a directory";
if ($errors === null) {
echo $message . ".\n";
} else {
$errors[ 'template_dir' ] = $message;
}
} elseif (!is_readable($template_dir)) {
$status = false;
$message = "FAILED: $template_dir is not readable";
if ($errors === null) {
echo $message . ".\n";
} else {
$errors[ 'template_dir' ] = $message;
}
} else {
if ($errors === null) {
echo "$template_dir is OK.\n";
}
}
}
if ($errors === null) {
echo "Testing compile directory...\n";
}
// test if registered compile_dir is accessible
$__compile_dir = $smarty->getCompileDir();
$_compile_dir = realpath($__compile_dir);
if (!$_compile_dir) {
$status = false;
$message = "FAILED: {$__compile_dir} does not exist";
if ($errors === null) {
echo $message . ".\n";
} else {
$errors[ 'compile_dir' ] = $message;
}
} elseif (!is_dir($_compile_dir)) {
$status = false;
$message = "FAILED: {$_compile_dir} is not a directory";
if ($errors === null) {
echo $message . ".\n";
} else {
$errors[ 'compile_dir' ] = $message;
}
} elseif (!is_readable($_compile_dir)) {
$status = false;
$message = "FAILED: {$_compile_dir} is not readable";
if ($errors === null) {
echo $message . ".\n";
} else {
$errors[ 'compile_dir' ] = $message;
}
} elseif (!is_writable($_compile_dir)) {
$status = false;
$message = "FAILED: {$_compile_dir} is not writable";
if ($errors === null) {
echo $message . ".\n";
} else {
$errors[ 'compile_dir' ] = $message;
}
} else {
if ($errors === null) {
echo "{$_compile_dir} is OK.\n";
}
}
if ($errors === null) {
echo "Testing plugins directory...\n";
}
// test if all registered plugins_dir are accessible
// and if core plugins directory is still registered
$_core_plugins_dir = realpath(dirname(__FILE__) . '/../plugins');
$_core_plugins_available = false;
foreach ($smarty->getPluginsDir() as $plugin_dir) {
$_plugin_dir = $plugin_dir;
$plugin_dir = realpath($plugin_dir);
// resolve include_path or fail existence
if (!$plugin_dir) {
if ($smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_plugin_dir)) {
// try PHP include_path
if ($_stream_resolve_include_path) {
$plugin_dir = stream_resolve_include_path($_plugin_dir);
} else {
$plugin_dir = $smarty->ext->_getIncludePath->getIncludePath($_plugin_dir, null, $smarty);
}
if ($plugin_dir !== false) {
if ($errors === null) {
echo "$plugin_dir is OK.\n";
}
continue;
} else {
$status = false;
$message = "FAILED: $_plugin_dir does not exist (and couldn't be found in include_path either)";
if ($errors === null) {
echo $message . ".\n";
} else {
$errors[ 'plugins_dir' ] = $message;
}
continue;
}
} else {
$status = false;
$message = "FAILED: $_plugin_dir does not exist";
if ($errors === null) {
echo $message . ".\n";
} else {
$errors[ 'plugins_dir' ] = $message;
}
continue;
}
}
if (!is_dir($plugin_dir)) {
$status = false;
$message = "FAILED: $plugin_dir is not a directory";
if ($errors === null) {
echo $message . ".\n";
} else {
$errors[ 'plugins_dir' ] = $message;
}
} elseif (!is_readable($plugin_dir)) {
$status = false;
$message = "FAILED: $plugin_dir is not readable";
if ($errors === null) {
echo $message . ".\n";
} else {
$errors[ 'plugins_dir' ] = $message;
}
} elseif ($_core_plugins_dir && $_core_plugins_dir == realpath($plugin_dir)) {
$_core_plugins_available = true;
if ($errors === null) {
echo "$plugin_dir is OK.\n";
}
} else {
if ($errors === null) {
echo "$plugin_dir is OK.\n";
}
}
}
if (!$_core_plugins_available) {
$status = false;
$message = "WARNING: Smarty's own libs/plugins is not available";
if ($errors === null) {
echo $message . ".\n";
} elseif (!isset($errors[ 'plugins_dir' ])) {
$errors[ 'plugins_dir' ] = $message;
}
}
if ($errors === null) {
echo "Testing cache directory...\n";
}
// test if all registered cache_dir is accessible
$__cache_dir = $smarty->getCacheDir();
$_cache_dir = realpath($__cache_dir);
if (!$_cache_dir) {
$status = false;
$message = "FAILED: {$__cache_dir} does not exist";
if ($errors === null) {
echo $message . ".\n";
} else {
$errors[ 'cache_dir' ] = $message;
}
} elseif (!is_dir($_cache_dir)) {
$status = false;
$message = "FAILED: {$_cache_dir} is not a directory";
if ($errors === null) {
echo $message . ".\n";
} else {
$errors[ 'cache_dir' ] = $message;
}
} elseif (!is_readable($_cache_dir)) {
$status = false;
$message = "FAILED: {$_cache_dir} is not readable";
if ($errors === null) {
echo $message . ".\n";
} else {
$errors[ 'cache_dir' ] = $message;
}
} elseif (!is_writable($_cache_dir)) {
$status = false;
$message = "FAILED: {$_cache_dir} is not writable";
if ($errors === null) {
echo $message . ".\n";
} else {
$errors[ 'cache_dir' ] = $message;
}
} else {
if ($errors === null) {
echo "{$_cache_dir} is OK.\n";
}
}
if ($errors === null) {
echo "Testing configs directory...\n";
}
// test if all registered config_dir are accessible
foreach ($smarty->getConfigDir() as $config_dir) {
$_config_dir = $config_dir;
// resolve include_path or fail existence
if (!$config_dir) {
if ($smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_config_dir)) {
// try PHP include_path
if ($_stream_resolve_include_path) {
$config_dir = stream_resolve_include_path($_config_dir);
} else {
$config_dir = $smarty->ext->_getIncludePath->getIncludePath($_config_dir, null, $smarty);
}
if ($config_dir !== false) {
if ($errors === null) {
echo "$config_dir is OK.\n";
}
continue;
} else {
$status = false;
$message = "FAILED: $_config_dir does not exist (and couldn't be found in include_path either)";
if ($errors === null) {
echo $message . ".\n";
} else {
$errors[ 'config_dir' ] = $message;
}
continue;
}
} else {
$status = false;
$message = "FAILED: $_config_dir does not exist";
if ($errors === null) {
echo $message . ".\n";
} else {
$errors[ 'config_dir' ] = $message;
}
continue;
}
}
if (!is_dir($config_dir)) {
$status = false;
$message = "FAILED: $config_dir is not a directory";
if ($errors === null) {
echo $message . ".\n";
} else {
$errors[ 'config_dir' ] = $message;
}
} elseif (!is_readable($config_dir)) {
$status = false;
$message = "FAILED: $config_dir is not readable";
if ($errors === null) {
echo $message . ".\n";
} else {
$errors[ 'config_dir' ] = $message;
}
} else {
if ($errors === null) {
echo "$config_dir is OK.\n";
}
}
}
if ($errors === null) {
echo "Testing sysplugin files...\n";
}
// test if sysplugins are available
$source = SMARTY_SYSPLUGINS_DIR;
if (is_dir($source)) {
$expectedSysplugins = array('smartycompilerexception.php' => true, 'smartyexception.php' => true,
'smarty_cacheresource.php' => true, 'smarty_cacheresource_custom.php' => true,
'smarty_cacheresource_keyvaluestore.php' => true, 'smarty_data.php' => true,
'smarty_internal_block.php' => true,
'smarty_internal_cacheresource_file.php' => true,
'smarty_internal_compilebase.php' => true,
'smarty_internal_compile_append.php' => true,
'smarty_internal_compile_assign.php' => true,
'smarty_internal_compile_block.php' => true,
'smarty_internal_compile_break.php' => true,
'smarty_internal_compile_call.php' => true,
'smarty_internal_compile_capture.php' => true,
'smarty_internal_compile_config_load.php' => true,
'smarty_internal_compile_continue.php' => true,
'smarty_internal_compile_debug.php' => true,
'smarty_internal_compile_eval.php' => true,
'smarty_internal_compile_extends.php' => true,
'smarty_internal_compile_for.php' => true,
'smarty_internal_compile_foreach.php' => true,
'smarty_internal_compile_function.php' => true,
'smarty_internal_compile_if.php' => true,
'smarty_internal_compile_include.php' => true,
'smarty_internal_compile_include_php.php' => true,
'smarty_internal_compile_insert.php' => true,
'smarty_internal_compile_ldelim.php' => true,
'smarty_internal_compile_make_nocache.php' => true,
'smarty_internal_compile_nocache.php' => true,
'smarty_internal_compile_private_block_plugin.php' => true,
'smarty_internal_compile_private_foreachsection.php' => true,
'smarty_internal_compile_private_function_plugin.php' => true,
'smarty_internal_compile_private_modifier.php' => true,
'smarty_internal_compile_private_object_block_function.php' => true,
'smarty_internal_compile_private_object_function.php' => true,
'smarty_internal_compile_private_php.php' => true,
'smarty_internal_compile_private_print_expression.php' => true,
'smarty_internal_compile_private_registered_block.php' => true,
'smarty_internal_compile_private_registered_function.php' => true,
'smarty_internal_compile_private_special_variable.php' => true,
'smarty_internal_compile_rdelim.php' => true,
'smarty_internal_compile_section.php' => true,
'smarty_internal_compile_setfilter.php' => true,
'smarty_internal_compile_shared_inheritance.php' => true,
'smarty_internal_compile_while.php' => true,
'smarty_internal_configfilelexer.php' => true,
'smarty_internal_configfileparser.php' => true,
'smarty_internal_config_file_compiler.php' => true,
'smarty_internal_data.php' => true, 'smarty_internal_debug.php' => true,
'smarty_internal_extension_clear.php' => true,
'smarty_internal_extension_handler.php' => true,
'smarty_internal_method_addautoloadfilters.php' => true,
'smarty_internal_method_adddefaultmodifiers.php' => true,
'smarty_internal_method_append.php' => true,
'smarty_internal_method_appendbyref.php' => true,
'smarty_internal_method_assignbyref.php' => true,
'smarty_internal_method_assignglobal.php' => true,
'smarty_internal_method_clearallassign.php' => true,
'smarty_internal_method_clearallcache.php' => true,
'smarty_internal_method_clearassign.php' => true,
'smarty_internal_method_clearcache.php' => true,
'smarty_internal_method_clearcompiledtemplate.php' => true,
'smarty_internal_method_clearconfig.php' => true,
'smarty_internal_method_compileallconfig.php' => true,
'smarty_internal_method_compilealltemplates.php' => true,
'smarty_internal_method_configload.php' => true,
'smarty_internal_method_createdata.php' => true,
'smarty_internal_method_getautoloadfilters.php' => true,
'smarty_internal_method_getconfigvars.php' => true,
'smarty_internal_method_getdebugtemplate.php' => true,
'smarty_internal_method_getdefaultmodifiers.php' => true,
'smarty_internal_method_getglobal.php' => true,
'smarty_internal_method_getregisteredobject.php' => true,
'smarty_internal_method_getstreamvariable.php' => true,
'smarty_internal_method_gettags.php' => true,
'smarty_internal_method_gettemplatevars.php' => true,
'smarty_internal_method_loadfilter.php' => true,
'smarty_internal_method_loadplugin.php' => true,
'smarty_internal_method_mustcompile.php' => true,
'smarty_internal_method_registercacheresource.php' => true,
'smarty_internal_method_registerclass.php' => true,
'smarty_internal_method_registerdefaultconfighandler.php' => true,
'smarty_internal_method_registerdefaultpluginhandler.php' => true,
'smarty_internal_method_registerdefaulttemplatehandler.php' => true,
'smarty_internal_method_registerfilter.php' => true,
'smarty_internal_method_registerobject.php' => true,
'smarty_internal_method_registerplugin.php' => true,
'smarty_internal_method_registerresource.php' => true,
'smarty_internal_method_setautoloadfilters.php' => true,
'smarty_internal_method_setdebugtemplate.php' => true,
'smarty_internal_method_setdefaultmodifiers.php' => true,
'smarty_internal_method_unloadfilter.php' => true,
'smarty_internal_method_unregistercacheresource.php' => true,
'smarty_internal_method_unregisterfilter.php' => true,
'smarty_internal_method_unregisterobject.php' => true,
'smarty_internal_method_unregisterplugin.php' => true,
'smarty_internal_method_unregisterresource.php' => true,
'smarty_internal_nocache_insert.php' => true,
'smarty_internal_parsetree.php' => true,
'smarty_internal_parsetree_code.php' => true,
'smarty_internal_parsetree_dq.php' => true,
'smarty_internal_parsetree_dqcontent.php' => true,
'smarty_internal_parsetree_tag.php' => true,
'smarty_internal_parsetree_template.php' => true,
'smarty_internal_parsetree_text.php' => true,
'smarty_internal_resource_eval.php' => true,
'smarty_internal_resource_extends.php' => true,
'smarty_internal_resource_file.php' => true,
'smarty_internal_resource_php.php' => true,
'smarty_internal_resource_registered.php' => true,
'smarty_internal_resource_stream.php' => true,
'smarty_internal_resource_string.php' => true,
'smarty_internal_runtime_cachemodify.php' => true,
'smarty_internal_runtime_capture.php' => true,
'smarty_internal_runtime_codeframe.php' => true,
'smarty_internal_runtime_filterhandler.php' => true,
'smarty_internal_runtime_foreach.php' => true,
'smarty_internal_runtime_getincludepath.php' => true,
'smarty_internal_runtime_inheritance.php' => true,
'smarty_internal_runtime_make_nocache.php' => true,
'smarty_internal_runtime_tplfunction.php' => true,
'smarty_internal_runtime_updatecache.php' => true,
'smarty_internal_runtime_updatescope.php' => true,
'smarty_internal_runtime_writefile.php' => true,
'smarty_internal_smartytemplatecompiler.php' => true,
'smarty_internal_template.php' => true,
'smarty_internal_templatebase.php' => true,
'smarty_internal_templatecompilerbase.php' => true,
'smarty_internal_templatelexer.php' => true,
'smarty_internal_templateparser.php' => true,
'smarty_internal_testinstall.php' => true,
'smarty_internal_undefined.php' => true, 'smarty_resource.php' => true,
'smarty_resource_custom.php' => true, 'smarty_resource_recompiled.php' => true,
'smarty_resource_uncompiled.php' => true, 'smarty_security.php' => true,
'smarty_template_cached.php' => true, 'smarty_template_compiled.php' => true,
'smarty_template_config.php' => true,
'smarty_template_resource_base.php' => true,
'smarty_template_source.php' => true, 'smarty_undefined_variable.php' => true,
'smarty_variable.php' => true,);
$iterator = new DirectoryIterator($source);
foreach ($iterator as $file) {
if (!$file->isDot()) {
$filename = $file->getFilename();
if (isset($expectedSysplugins[ $filename ])) {
unset($expectedSysplugins[ $filename ]);
}
}
}
if ($expectedSysplugins) {
$status = false;
$message = "FAILED: files missing from libs/sysplugins: " . join(', ', array_keys($expectedSysplugins));
if ($errors === null) {
echo $message . ".\n";
} else {
$errors[ 'sysplugins' ] = $message;
}
} elseif ($errors === null) {
echo "... OK\n";
}
} else {
$status = false;
$message = "FAILED: " . SMARTY_SYSPLUGINS_DIR . ' is not a directory';
if ($errors === null) {
echo $message . ".\n";
} else {
$errors[ 'sysplugins_dir_constant' ] = $message;
}
}
if ($errors === null) {
echo "Testing plugin files...\n";
}
// test if core plugins are available
$source = SMARTY_PLUGINS_DIR;
if (is_dir($source)) {
$expectedPlugins =
array('block.textformat.php' => true, 'function.counter.php' => true, 'function.cycle.php' => true,
'function.fetch.php' => true, 'function.html_checkboxes.php' => true,
'function.html_image.php' => true, 'function.html_options.php' => true,
'function.html_radios.php' => true, 'function.html_select_date.php' => true,
'function.html_select_time.php' => true, 'function.html_table.php' => true,
'function.mailto.php' => true, 'function.math.php' => true, 'modifier.capitalize.php' => true,
'modifier.date_format.php' => true, 'modifier.debug_print_var.php' => true,
'modifier.escape.php' => true, 'modifier.regex_replace.php' => true,
'modifier.replace.php' => true, 'modifier.spacify.php' => true, 'modifier.truncate.php' => true,
'modifiercompiler.cat.php' => true, 'modifiercompiler.count_characters.php' => true,
'modifiercompiler.count_paragraphs.php' => true, 'modifiercompiler.count_sentences.php' => true,
'modifiercompiler.count_words.php' => true, 'modifiercompiler.default.php' => true,
'modifiercompiler.escape.php' => true, 'modifiercompiler.from_charset.php' => true,
'modifiercompiler.indent.php' => true, 'modifiercompiler.lower.php' => true,
'modifiercompiler.noprint.php' => true, 'modifiercompiler.string_format.php' => true,
'modifiercompiler.strip.php' => true, 'modifiercompiler.strip_tags.php' => true,
'modifiercompiler.to_charset.php' => true, 'modifiercompiler.unescape.php' => true,
'modifiercompiler.upper.php' => true, 'modifiercompiler.wordwrap.php' => true,
'outputfilter.trimwhitespace.php' => true, 'shared.escape_special_chars.php' => true,
'shared.literal_compiler_param.php' => true, 'shared.make_timestamp.php' => true,
'shared.mb_str_replace.php' => true, 'shared.mb_unicode.php' => true,
'shared.mb_wordwrap.php' => true, 'variablefilter.htmlspecialchars.php' => true,);
$iterator = new DirectoryIterator($source);
foreach ($iterator as $file) {
if (!$file->isDot()) {
$filename = $file->getFilename();
if (isset($expectedPlugins[ $filename ])) {
unset($expectedPlugins[ $filename ]);
}
}
}
if ($expectedPlugins) {
$status = false;
$message = "FAILED: files missing from libs/plugins: " . join(', ', array_keys($expectedPlugins));
if ($errors === null) {
echo $message . ".\n";
} else {
$errors[ 'plugins' ] = $message;
}
} elseif ($errors === null) {
echo "... OK\n";
}
} else {
$status = false;
$message = "FAILED: " . SMARTY_PLUGINS_DIR . ' is not a directory';
if ($errors === null) {
echo $message . ".\n";
} else {
$errors[ 'plugins_dir_constant' ] = $message;
}
}
if ($errors === null) {
echo "Tests complete.\n";
echo "</PRE>\n";
}
return $status;
}
}

View File

@@ -1,49 +0,0 @@
<?php
/**
* Smarty Method AppendByRef
*
* Smarty::appendByRef() method
*
* @package Smarty
* @subpackage PluginsInternal
* @author Uwe Tews
*/
class Smarty_Internal_Undefined
{
/**
* This function is executed automatically when a compiled or cached template file is included
* - Decode saved properties from compiled template and cache files
* - Check if compiled or cache file is valid
*
* @param \Smarty_Internal_Template $tpl
* @param array $properties special template properties
* @param bool $cache flag if called from cache file
*
* @return bool flag if compiled or cache file is valid
*/
public function decodeProperties(Smarty_Internal_Template $tpl, $properties, $cache = false)
{
if ($cache) {
$tpl->cached->valid = false;
} else {
$tpl->mustCompile = true;
}
return false;
}
/**
* Call error handler for undefined method
*
* @param string $name unknown method-name
* @param array $args argument array
*
* @return mixed
* @throws SmartyException
*/
public function __call($name, $args)
{
throw new SmartyException(get_class($args[ 0 ]) . "->{$name}() undefined method");
}
}

View File

@@ -0,0 +1,77 @@
# https://help.github.com/en/categories/automating-your-workflow-with-github-actions
on:
- pull_request
- push
name: CI
jobs:
tests:
name: Tests
runs-on: ${{ matrix.os }}
env:
PHP_EXTENSIONS: dom, json, libxml, mbstring, pdo_sqlite, soap, xml, xmlwriter
PHP_INI_VALUES: assert.exception=1, zend.assertions=1
strategy:
fail-fast: false
matrix:
os:
- ubuntu-latest
php-version:
- "7.1"
- "7.2"
- "7.3"
- "7.4"
- "8.0"
- "8.1"
compiler:
- default
include:
- os: ubuntu-latest
php-version: "8.0"
compiler: jit
- os: ubuntu-latest
php-version: "8.1"
compiler: jit
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Override PHP ini values for JIT compiler
if: matrix.compiler == 'jit'
run: echo "PHP_INI_VALUES::assert.exception=1, zend.assertions=1, opcache.enable=1, opcache.enable_cli=1, opcache.optimization_level=-1, opcache.jit=1255, opcache.jit_buffer_size=32M" >> $GITHUB_ENV
- name: Install PHP with extensions
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
coverage: pcov
extensions: ${{ env.PHP_EXTENSIONS }}
ini-values: ${{ env.PHP_INI_VALUES }}
- name: Validate composer.json and composer.lock
run: composer validate
- name: Cache Composer packages
id: composer-cache
uses: actions/cache@v2
with:
path: vendor
key: ${{ runner.os }}-php-${{ matrix.php-version }}-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-php-${{ matrix.php-version }}-
- name: Install dependencies
if: steps.composer-cache.outputs.cache-hit != 'true'
run: composer install --prefer-dist --no-progress --no-suggest
- name: Run tests with phpunit
run: ./phpunit.sh

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,179 @@
Smarty: the PHP compiling template engine
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 3.0 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 below for more details.
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View File

@@ -0,0 +1,20 @@
# Smarty template engine
Smarty is a template engine for PHP, facilitating the separation of presentation (HTML/CSS) from application logic.
![CI](https://github.com/smarty-php/smarty/workflows/CI/badge.svg)
## Documentation
Read the [documentation](https://smarty-php.github.io/smarty/) to find out how to use it.
## Requirements
Smarty can be run with PHP 7.1 to PHP 8.1.
## Installation
Smarty versions 3.1.11 or later can be installed with [Composer](https://getcomposer.org/).
To get the latest stable version of Smarty use:
```bash
composer require smarty/smarty
````
More in the [Getting Started](./docs/getting-started.md) section of the docs.

View File

@@ -0,0 +1,19 @@
# Security Policy
## Supported Versions
Smarty currently supports the latest minor version of Smarty 3 and Smarty 4. (Smarty 4 has not been released yet.)
| Version | Supported |
| ------- | ------------------ |
| 4.0.x | :white_check_mark: |
| 3.1.x | :white_check_mark: |
| < 3.1 | :x: |
## Reporting a Vulnerability
If you have discovered a security issue with Smarty, please contact us at mail [at] simonwisselink.nl. Do not
disclose your findings publicly and PLEASE PLEASE do not file an Issue.
We will try to confirm the vulnerability and develop a fix if appropriate. When we release the fix, we will publish
a security release. Please let us know if you want to be credited.

View File

@@ -0,0 +1,49 @@
{
"name": "smarty/smarty",
"type": "library",
"description": "Smarty - the compiling PHP template engine",
"keywords": [
"templating"
],
"homepage": "https://smarty-php.github.io/smarty/",
"license": "LGPL-3.0",
"authors": [
{
"name": "Monte Ohrt",
"email": "monte@ohrt.com"
},
{
"name": "Uwe Tews",
"email": "uwe.tews@googlemail.com"
},
{
"name": "Rodney Rehm",
"email": "rodney.rehm@medialize.de"
},
{
"name": "Simon Wisselink",
"homepage": "https://www.iwink.nl/"
}
],
"support": {
"issues": "https://github.com/smarty-php/smarty/issues",
"forum": "https://github.com/smarty-php/smarty/discussions"
},
"require": {
"php": "^7.1 || ^8.0"
},
"autoload": {
"classmap": [
"libs/"
]
},
"extra": {
"branch-alias": {
"dev-master": "4.0.x-dev"
}
},
"require-dev": {
"phpunit/phpunit": "^8.5 || ^7.5",
"smarty/smarty-lexer": "^3.1"
}
}

View File

@@ -0,0 +1,5 @@
title = Welcome to Smarty!
cutoff_size = 40
[setup]
bold = true

View File

@@ -0,0 +1,35 @@
<?php
/**
* Example Application
*
* @package Example-application
*/
require '../libs/Smarty.class.php';
$smarty = new Smarty;
//$smarty->force_compile = true;
$smarty->debugging = true;
$smarty->caching = true;
$smarty->cache_lifetime = 120;
$smarty->assign("Name", "Fred Irving Johnathan Bradley Peppergill", true);
$smarty->assign("FirstName", array("John", "Mary", "James", "Henry"));
$smarty->assign("LastName", array("Doe", "Smith", "Johnson", "Case"));
$smarty->assign(
"Class",
array(
array("A", "B", "C", "D"),
array("E", "F", "G", "H"),
array("I", "J", "K", "L"),
array("M", "N", "O", "P")
)
);
$smarty->assign(
"contacts",
array(
array("phone" => "1", "fax" => "2", "cell" => "3"),
array("phone" => "555-4444", "fax" => "555-3333", "cell" => "760-1234")
)
);
$smarty->assign("option_values", array("NY", "NE", "KS", "IA", "OK", "TX"));
$smarty->assign("option_output", array("New York", "Nebraska", "Kansas", "Iowa", "Oklahoma", "Texas"));
$smarty->assign("option_selected", "NE");
$smarty->display('index.tpl');

View File

@@ -0,0 +1,85 @@
<?php
/**
* APC CacheResource
* CacheResource Implementation based on the KeyValueStore API to use
* memcache as the storage resource for Smarty's output caching.
* *
*
* @package CacheResource-examples
* @author Uwe Tews
*/
class Smarty_CacheResource_Apc extends Smarty_CacheResource_KeyValueStore
{
/**
* Smarty_CacheResource_Apc constructor.
*
* @throws \Exception
*/
public function __construct()
{
// test if APC is present
if (!function_exists('apc_cache_info')) {
throw new Exception('APC Template Caching Error: APC is not installed');
}
}
/**
* 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
* @return boolean true on success, false on failure
*/
protected function read(array $keys)
{
$_res = array();
$res = apc_fetch($keys);
foreach ($res as $k => $v) {
$_res[ $k ] = $v;
}
return $_res;
}
/**
* 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 function write(array $keys, $expire = null)
{
foreach ($keys as $k => $v) {
apc_store($k, $v, $expire);
}
return true;
}
/**
* Remove values from cache
*
* @param array $keys list of keys to delete
*
* @return boolean true on success, false on failure
*/
protected function delete(array $keys)
{
foreach ($keys as $k) {
apc_delete($k);
}
return true;
}
/**
* Remove *all* values from cache
*
* @return boolean true on success, false on failure
*/
protected function purge()
{
return apc_clear_cache('user');
}
}

View File

@@ -0,0 +1,99 @@
<?php
/**
* Memcache CacheResource
* CacheResource Implementation based on the KeyValueStore API to use
* memcache as the storage resource for Smarty's output caching.
* Note that memcache has a limitation of 256 characters per cache-key.
* To avoid complications all cache-keys are translated to a sha1 hash.
*
* @package CacheResource-examples
* @author Rodney Rehm
*/
class Smarty_CacheResource_Memcache extends Smarty_CacheResource_KeyValueStore
{
/**
* memcache instance
*
* @var Memcache
*/
protected $memcache = null;
/**
* Smarty_CacheResource_Memcache constructor.
*/
public function __construct()
{
if (class_exists('Memcached')) {
$this->memcache = new Memcached();
} else {
$this->memcache = new Memcache();
}
$this->memcache->addServer('127.0.0.1', 11211);
}
/**
* 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
* @return boolean true on success, false on failure
*/
protected function read(array $keys)
{
$res = array();
foreach ($keys as $key) {
$k = sha1($key);
$res[$key] = $this->memcache->get($k);
}
return $res;
}
/**
* 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 function write(array $keys, $expire = null)
{
foreach ($keys as $k => $v) {
$k = sha1($k);
if (class_exists('Memcached')) {
$this->memcache->set($k, $v, $expire);
} else {
$this->memcache->set($k, $v, 0, $expire);
}
}
return true;
}
/**
* Remove values from cache
*
* @param array $keys list of keys to delete
*
* @return boolean true on success, false on failure
*/
protected function delete(array $keys)
{
foreach ($keys as $k) {
$k = sha1($k);
$this->memcache->delete($k);
}
return true;
}
/**
* Remove *all* values from cache
*
* @return boolean true on success, false on failure
*/
protected function purge()
{
return $this->memcache->flush();
}
}

View File

@@ -0,0 +1,183 @@
<?php
/**
* MySQL CacheResource
* CacheResource Implementation based on the Custom API to use
* MySQL as the storage resource for Smarty's output caching.
* Table definition:
* <pre>CREATE TABLE IF NOT EXISTS `output_cache` (
* `id` CHAR(40) NOT NULL COMMENT 'sha1 hash',
* `name` VARCHAR(250) NOT NULL,
* `cache_id` VARCHAR(250) NULL DEFAULT NULL,
* `compile_id` VARCHAR(250) NULL DEFAULT NULL,
* `modified` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
* `content` LONGTEXT NOT NULL,
* PRIMARY KEY (`id`),
* INDEX(`name`),
* INDEX(`cache_id`),
* INDEX(`compile_id`),
* INDEX(`modified`)
* ) ENGINE = InnoDB;</pre>
*
* @package CacheResource-examples
* @author Rodney Rehm
*/
class Smarty_CacheResource_Mysql extends Smarty_CacheResource_Custom
{
/**
* @var \PDO
*/
protected $db;
/**
* @var \PDOStatement
*/
protected $fetch;
/**
* @var \PDOStatement
*/
protected $fetchTimestamp;
/**
* @var \PDOStatement
*/
protected $save;
/**
* Smarty_CacheResource_Mysql constructor.
*
* @throws \SmartyException
*/
public function __construct()
{
try {
$this->db = new PDO("mysql:dbname=test;host=127.0.0.1", "smarty");
} catch (PDOException $e) {
throw new SmartyException('Mysql Resource failed: ' . $e->getMessage());
}
$this->fetch = $this->db->prepare('SELECT modified, content FROM output_cache WHERE id = :id');
$this->fetchTimestamp = $this->db->prepare('SELECT modified FROM output_cache WHERE id = :id');
$this->save = $this->db->prepare(
'REPLACE INTO output_cache (id, name, cache_id, compile_id, content)
VALUES (:id, :name, :cache_id, :compile_id, :content)'
);
}
/**
* 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 function fetch($id, $name, $cache_id, $compile_id, &$content, &$mtime)
{
$this->fetch->execute(array('id' => $id));
$row = $this->fetch->fetch();
$this->fetch->closeCursor();
if ($row) {
$content = $row[ 'content' ];
$mtime = strtotime($row[ 'modified' ]);
} else {
$content = null;
$mtime = null;
}
}
/**
* Fetch cached content's modification timestamp from data source
*
* @note 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)
{
$this->fetchTimestamp->execute(array('id' => $id));
$mtime = strtotime($this->fetchTimestamp->fetchColumn());
$this->fetchTimestamp->closeCursor();
return $mtime;
}
/**
* 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 time in seconds or null
* @param string $content content to cache
*
* @return boolean success
*/
protected function save($id, $name, $cache_id, $compile_id, $exp_time, $content)
{
$this->save->execute(
array('id' => $id,
'name' => $name,
'cache_id' => $cache_id,
'compile_id' => $compile_id,
'content' => $content,)
);
return !!$this->save->rowCount();
}
/**
* 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 or null
*
* @return integer number of deleted caches
*/
protected function delete($name, $cache_id, $compile_id, $exp_time)
{
// delete the whole cache
if ($name === null && $cache_id === null && $compile_id === null && $exp_time === null) {
// returning the number of deleted caches would require a second query to count them
$query = $this->db->query('TRUNCATE TABLE output_cache');
return -1;
}
// build the filter
$where = array();
// equal test name
if ($name !== null) {
$where[] = 'name = ' . $this->db->quote($name);
}
// equal test compile_id
if ($compile_id !== null) {
$where[] = 'compile_id = ' . $this->db->quote($compile_id);
}
// range test expiration time
if ($exp_time !== null) {
$where[] = 'modified < DATE_SUB(NOW(), INTERVAL ' . intval($exp_time) . ' SECOND)';
}
// equal test cache_id and match sub-groups
if ($cache_id !== null) {
$where[] =
'(cache_id = ' .
$this->db->quote($cache_id) .
' OR cache_id LIKE ' .
$this->db->quote($cache_id . '|%') .
')';
}
// run delete query
$query = $this->db->query('DELETE FROM output_cache WHERE ' . join(' AND ', $where));
return $query->rowCount();
}
}

View File

@@ -0,0 +1,346 @@
<?php
/**
* PDO Cache Handler
* Allows you to store Smarty Cache files into your db.
* Example table :
* CREATE TABLE `smarty_cache` (
* `id` char(40) NOT NULL COMMENT 'sha1 hash',
* `name` varchar(250) NOT NULL,
* `cache_id` varchar(250) DEFAULT NULL,
* `compile_id` varchar(250) DEFAULT NULL,
* `modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
* `expire` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
* `content` mediumblob NOT NULL,
* PRIMARY KEY (`id`),
* KEY `name` (`name`),
* KEY `cache_id` (`cache_id`),
* KEY `compile_id` (`compile_id`),
* KEY `modified` (`modified`),
* KEY `expire` (`expire`)
* ) ENGINE=InnoDB
* Example usage :
* $cnx = new PDO("mysql:host=localhost;dbname=mydb", "username", "password");
* $smarty->setCachingType('pdo');
* $smarty->loadPlugin('Smarty_CacheResource_Pdo');
* $smarty->registerCacheResource('pdo', new Smarty_CacheResource_Pdo($cnx, 'smarty_cache'));
*
* @author Beno!t POLASZEK - 2014
*/
class Smarty_CacheResource_Pdo extends Smarty_CacheResource_Custom
{
/**
* @var string[]
*/
protected $fetchStatements = array('default' => 'SELECT %2$s
FROM %1$s
WHERE 1
AND id = :id
AND cache_id IS NULL
AND compile_id IS NULL',
'withCacheId' => 'SELECT %2$s
FROM %1$s
WHERE 1
AND id = :id
AND cache_id = :cache_id
AND compile_id IS NULL',
'withCompileId' => 'SELECT %2$s
FROM %1$s
WHERE 1
AND id = :id
AND compile_id = :compile_id
AND cache_id IS NULL',
'withCacheIdAndCompileId' => 'SELECT %2$s
FROM %1$s
WHERE 1
AND id = :id
AND cache_id = :cache_id
AND compile_id = :compile_id');
/**
* @var string
*/
protected $insertStatement = 'INSERT INTO %s
SET id = :id,
name = :name,
cache_id = :cache_id,
compile_id = :compile_id,
modified = CURRENT_TIMESTAMP,
expire = DATE_ADD(CURRENT_TIMESTAMP, INTERVAL :expire SECOND),
content = :content
ON DUPLICATE KEY UPDATE
name = :name,
cache_id = :cache_id,
compile_id = :compile_id,
modified = CURRENT_TIMESTAMP,
expire = DATE_ADD(CURRENT_TIMESTAMP, INTERVAL :expire SECOND),
content = :content';
/**
* @var string
*/
protected $deleteStatement = 'DELETE FROM %1$s WHERE %2$s';
/**
* @var string
*/
protected $truncateStatement = 'TRUNCATE TABLE %s';
/**
* @var string
*/
protected $fetchColumns = 'modified, content';
/**
* @var string
*/
protected $fetchTimestampColumns = 'modified';
/**
* @var \PDO
*/
protected $pdo;
/**
* @var
*/
protected $table;
/**
* @var null
*/
protected $database;
/**
* Constructor
*
* @param PDO $pdo PDO : active connection
* @param string $table : table (or view) name
* @param string $database : optional - if table is located in another db
*
* @throws \SmartyException
*/
public function __construct(PDO $pdo, $table, $database = null)
{
if (is_null($table)) {
throw new SmartyException("Table name for caching can't be null");
}
$this->pdo = $pdo;
$this->table = $table;
$this->database = $database;
$this->fillStatementsWithTableName();
}
/**
* Fills the table name into the statements.
*
* @return $this Current Instance
* @access protected
*/
protected function fillStatementsWithTableName()
{
foreach ($this->fetchStatements as &$statement) {
$statement = sprintf($statement, $this->getTableName(), '%s');
}
$this->insertStatement = sprintf($this->insertStatement, $this->getTableName());
$this->deleteStatement = sprintf($this->deleteStatement, $this->getTableName(), '%s');
$this->truncateStatement = sprintf($this->truncateStatement, $this->getTableName());
return $this;
}
/**
* Gets the fetch statement, depending on what you specify
*
* @param string $columns : the column(s) name(s) you want to retrieve from the database
* @param string $id unique cache content identifier
* @param string|null $cache_id cache id
* @param string|null $compile_id compile id
*
* @access protected
* @return \PDOStatement
*/
protected function getFetchStatement($columns, $id, $cache_id = null, $compile_id = null)
{
$args = array();
if (!is_null($cache_id) && !is_null($compile_id)) {
$query = $this->fetchStatements[ 'withCacheIdAndCompileId' ] and
$args = array('id' => $id, 'cache_id' => $cache_id, 'compile_id' => $compile_id);
} elseif (is_null($cache_id) && !is_null($compile_id)) {
$query = $this->fetchStatements[ 'withCompileId' ] and
$args = array('id' => $id, 'compile_id' => $compile_id);
} elseif (!is_null($cache_id) && is_null($compile_id)) {
$query = $this->fetchStatements[ 'withCacheId' ] and $args = array('id' => $id, 'cache_id' => $cache_id);
} else {
$query = $this->fetchStatements[ 'default' ] and $args = array('id' => $id);
}
$query = sprintf($query, $columns);
$stmt = $this->pdo->prepare($query);
foreach ($args as $key => $value) {
$stmt->bindValue($key, $value);
}
return $stmt;
}
/**
* fetch cached content and its modification time from data source
*
* @param string $id unique cache content identifier
* @param string $name template name
* @param string|null $cache_id cache id
* @param string|null $compile_id compile id
* @param string $content cached content
* @param integer $mtime cache modification timestamp (epoch)
*
* @return void
* @access protected
*/
protected function fetch($id, $name, $cache_id = null, $compile_id = null, &$content, &$mtime)
{
$stmt = $this->getFetchStatement($this->fetchColumns, $id, $cache_id, $compile_id);
$stmt->execute();
$row = $stmt->fetch();
$stmt->closeCursor();
if ($row) {
$content = $this->outputContent($row[ 'content' ]);
$mtime = strtotime($row[ 'modified' ]);
} else {
$content = null;
$mtime = null;
}
}
/**
* 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|null $cache_id cache id
* @param string|null $compile_id compile id
*
* @return integer|boolean timestamp (epoch) the template was modified, or false if not found
* @access protected
*/
// protected function fetchTimestamp($id, $name, $cache_id = null, $compile_id = null) {
// $stmt = $this->getFetchStatement($this->fetchTimestampColumns, $id, $cache_id, $compile_id);
// $stmt -> execute();
// $mtime = strtotime($stmt->fetchColumn());
// $stmt -> closeCursor();
// return $mtime;
// }
/**
* Save content to cache
*
* @param string $id unique cache content identifier
* @param string $name template name
* @param string|null $cache_id cache id
* @param string|null $compile_id compile id
* @param integer|null $exp_time seconds till expiration time in seconds or null
* @param string $content content to cache
*
* @return boolean success
* @access protected
*/
protected function save($id, $name, $cache_id = null, $compile_id = null, $exp_time, $content)
{
$stmt = $this->pdo->prepare($this->insertStatement);
$stmt->bindValue('id', $id);
$stmt->bindValue('name', $name);
$stmt->bindValue('cache_id', $cache_id, (is_null($cache_id)) ? PDO::PARAM_NULL : PDO::PARAM_STR);
$stmt->bindValue('compile_id', $compile_id, (is_null($compile_id)) ? PDO::PARAM_NULL : PDO::PARAM_STR);
$stmt->bindValue('expire', (int)$exp_time, PDO::PARAM_INT);
$stmt->bindValue('content', $this->inputContent($content));
$stmt->execute();
return !!$stmt->rowCount();
}
/**
* Encodes the content before saving to database
*
* @param string $content
*
* @return string $content
* @access protected
*/
protected function inputContent($content)
{
return $content;
}
/**
* Decodes the content before saving to database
*
* @param string $content
*
* @return string $content
* @access protected
*/
protected function outputContent($content)
{
return $content;
}
/**
* Delete content from cache
*
* @param string|null $name template name
* @param string|null $cache_id cache id
* @param string|null $compile_id compile id
* @param integer|null|-1 $exp_time seconds till expiration or null
*
* @return integer number of deleted caches
* @access protected
*/
protected function delete($name = null, $cache_id = null, $compile_id = null, $exp_time = null)
{
// delete the whole cache
if ($name === null && $cache_id === null && $compile_id === null && $exp_time === null) {
// returning the number of deleted caches would require a second query to count them
$this->pdo->query($this->truncateStatement);
return -1;
}
// build the filter
$where = array();
// equal test name
if ($name !== null) {
$where[] = 'name = ' . $this->pdo->quote($name);
}
// equal test cache_id and match sub-groups
if ($cache_id !== null) {
$where[] =
'(cache_id = ' .
$this->pdo->quote($cache_id) .
' OR cache_id LIKE ' .
$this->pdo->quote($cache_id . '|%') .
')';
}
// equal test compile_id
if ($compile_id !== null) {
$where[] = 'compile_id = ' . $this->pdo->quote($compile_id);
}
// for clearing expired caches
if ($exp_time === Smarty::CLEAR_EXPIRED) {
$where[] = 'expire < CURRENT_TIMESTAMP';
} // range test expiration time
elseif ($exp_time !== null) {
$where[] = 'modified < DATE_SUB(NOW(), INTERVAL ' . intval($exp_time) . ' SECOND)';
}
// run delete query
$query = $this->pdo->query(sprintf($this->deleteStatement, join(' AND ', $where)));
return $query->rowCount();
}
/**
* Gets the formatted table name
*
* @return string
* @access protected
*/
protected function getTableName()
{
return (is_null($this->database)) ? "`{$this->table}`" : "`{$this->database}`.`{$this->table}`";
}
}

View File

@@ -0,0 +1,42 @@
<?php
require_once 'cacheresource.pdo.php';
/**
* PDO Cache Handler with GZIP support
* Example usage :
* $cnx = new PDO("mysql:host=localhost;dbname=mydb", "username", "password");
* $smarty->setCachingType('pdo_gzip');
* $smarty->loadPlugin('Smarty_CacheResource_Pdo_Gzip');
* $smarty->registerCacheResource('pdo_gzip', new Smarty_CacheResource_Pdo_Gzip($cnx, 'smarty_cache'));
*
* @require Smarty_CacheResource_Pdo class
* @author Beno!t POLASZEK - 2014
*/
class Smarty_CacheResource_Pdo_Gzip extends Smarty_CacheResource_Pdo
{
/**
* Encodes the content before saving to database
*
* @param string $content
*
* @return string $content
* @access protected
*/
protected function inputContent($content)
{
return gzdeflate($content);
}
/**
* Decodes the content before saving to database
*
* @param string $content
*
* @return string $content
* @access protected
*/
protected function outputContent($content)
{
return gzinflate($content);
}
}

View File

@@ -0,0 +1,62 @@
<?php
/**
* Extends All Resource
* Resource Implementation modifying the extends-Resource to walk
* through the template_dirs and inherit all templates of the same name
*
* @package Resource-examples
* @author Rodney Rehm
*/
class Smarty_Resource_Extendsall extends Smarty_Internal_Resource_Extends
{
/**
* populate Source Object with meta data from Resource
*
* @param Smarty_Template_Source $source source object
* @param Smarty_Internal_Template $_template template object
*
* @return void
*/
public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template = null)
{
$uid = '';
$sources = array();
$timestamp = 0;
foreach ($source->smarty->getTemplateDir() as $key => $directory) {
try {
$s = Smarty_Resource::source(null, $source->smarty, 'file:' . '[' . $key . ']' . $source->name);
if (!$s->exists) {
continue;
}
$sources[ $s->uid ] = $s;
$uid .= $s->filepath;
$timestamp = $s->timestamp > $timestamp ? $s->timestamp : $timestamp;
} catch (SmartyException $e) {
}
}
if (!$sources) {
$source->exists = false;
return;
}
$sources = array_reverse($sources, true);
reset($sources);
$s = current($sources);
$source->components = $sources;
$source->filepath = $s->filepath;
$source->uid = sha1($uid . $source->smarty->_joined_template_dir);
$source->exists = true;
$source->timestamp = $timestamp;
}
/**
* Disable timestamp checks for extendsall resource.
* The individual source components will be checked.
*
* @return bool false
*/
public function checkTimestamps()
{
return false;
}
}

View File

@@ -0,0 +1,101 @@
<?php
/**
* MySQL Resource
* Resource Implementation based on the Custom API to use
* MySQL as the storage resource for Smarty's templates and configs.
* Table definition:
* <pre>CREATE TABLE IF NOT EXISTS `templates` (
* `name` varchar(100) NOT NULL,
* `modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
* `source` text,
* PRIMARY KEY (`name`)
* ) ENGINE=InnoDB DEFAULT CHARSET=utf8;</pre>
* Demo data:
* <pre>INSERT INTO `templates` (`name`, `modified`, `source`) VALUES ('test.tpl', "2010-12-25 22:00:00", '{$x="hello
* world"}{$x}');</pre>
*
*
* @package Resource-examples
* @author Rodney Rehm
*/
class Smarty_Resource_Mysql extends Smarty_Resource_Custom
{
/**
* PDO instance
*
* @var \PDO
*/
protected $db;
/**
* prepared fetch() statement
*
* @var \PDOStatement
*/
protected $fetch;
/**
* prepared fetchTimestamp() statement
*
* @var \PDOStatement
*/
protected $mtime;
/**
* Smarty_Resource_Mysql constructor.
*
* @throws \SmartyException
*/
public function __construct()
{
try {
$this->db = new PDO("mysql:dbname=test;host=127.0.0.1", "smarty");
} catch (PDOException $e) {
throw new SmartyException('Mysql Resource failed: ' . $e->getMessage());
}
$this->fetch = $this->db->prepare('SELECT modified, source FROM templates WHERE name = :name');
$this->mtime = $this->db->prepare('SELECT modified FROM templates WHERE name = :name');
}
/**
* Fetch a template and its modification time from database
*
* @param string $name template name
* @param string $source template source
* @param integer $mtime template modification timestamp (epoch)
*
* @return void
*/
protected function fetch($name, &$source, &$mtime)
{
$this->fetch->execute(array('name' => $name));
$row = $this->fetch->fetch();
$this->fetch->closeCursor();
if ($row) {
$source = $row[ 'source' ];
$mtime = strtotime($row[ 'modified' ]);
} else {
$source = null;
$mtime = null;
}
}
/**
* Fetch a template's modification time from database
*
* @note implementing this method is optional. Only implement it if modification times can be accessed faster than
* loading the comple template source.
*
* @param string $name template name
*
* @return integer timestamp (epoch) the template was modified
*/
protected function fetchTimestamp($name)
{
$this->mtime->execute(array('name' => $name));
$mtime = $this->mtime->fetchColumn();
$this->mtime->closeCursor();
return strtotime($mtime);
}
}

View File

@@ -0,0 +1,77 @@
<?php
/**
* MySQL Resource
* Resource Implementation based on the Custom API to use
* MySQL as the storage resource for Smarty's templates and configs.
* Note that this MySQL implementation fetches the source and timestamps in
* a single database query, instead of two separate like resource.mysql.php does.
* Table definition:
* <pre>CREATE TABLE IF NOT EXISTS `templates` (
* `name` varchar(100) NOT NULL,
* `modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
* `source` text,
* PRIMARY KEY (`name`)
* ) ENGINE=InnoDB DEFAULT CHARSET=utf8;</pre>
* Demo data:
* <pre>INSERT INTO `templates` (`name`, `modified`, `source`) VALUES ('test.tpl', "2010-12-25 22:00:00", '{$x="hello
* world"}{$x}');</pre>
*
*
* @package Resource-examples
* @author Rodney Rehm
*/
class Smarty_Resource_Mysqls extends Smarty_Resource_Custom
{
/**
* PDO instance
*
* @var \PDO
*/
protected $db;
/**
* prepared fetch() statement
*
* @var \PDOStatement
*/
protected $fetch;
/**
* Smarty_Resource_Mysqls constructor.
*
* @throws \SmartyException
*/
public function __construct()
{
try {
$this->db = new PDO("mysql:dbname=test;host=127.0.0.1", "smarty");
} catch (PDOException $e) {
throw new SmartyException('Mysql Resource failed: ' . $e->getMessage());
}
$this->fetch = $this->db->prepare('SELECT modified, source FROM templates WHERE name = :name');
}
/**
* Fetch a template and its modification time from database
*
* @param string $name template name
* @param string $source template source
* @param integer $mtime template modification timestamp (epoch)
*
* @return void
*/
protected function fetch($name, &$source, &$mtime)
{
$this->fetch->execute(array('name' => $name));
$row = $this->fetch->fetch();
$this->fetch->closeCursor();
if ($row) {
$source = $row[ 'source' ];
$mtime = strtotime($row[ 'modified' ]);
} else {
$source = null;
$mtime = null;
}
}
}

View File

@@ -0,0 +1,2 @@
</BODY>
</HTML>

View File

@@ -0,0 +1,5 @@
<HTML>
<HEAD>
<TITLE>{$title} - {$Name}</TITLE>
</HEAD>
<BODY bgcolor="#ffffff">

View File

@@ -0,0 +1,87 @@
{config_load file="test.conf" section="setup"}
{include file="header.tpl" title=foo}
<PRE>
{* bold and title are read from the config file *}
{if #bold#}<b>{/if}
{* capitalize the first letters of each word of the title *}
Title: {#title#|capitalize}
{if #bold#}</b>{/if}
The current date and time is {$smarty.now|date_format:"%Y-%m-%d %H:%M:%S"}
The value of global assigned variable $SCRIPT_NAME is {$SCRIPT_NAME}
Example of accessing server environment variable SERVER_NAME: {$smarty.server.SERVER_NAME}
The value of {ldelim}$Name{rdelim} is <b>{$Name}</b>
variable modifier example of {ldelim}$Name|upper{rdelim}
<b>{$Name|upper}</b>
An example of a section loop:
{section name=outer
loop=$FirstName}
{if $smarty.section.outer.index is odd by 2}
{$smarty.section.outer.rownum} . {$FirstName[outer]} {$LastName[outer]}
{else}
{$smarty.section.outer.rownum} * {$FirstName[outer]} {$LastName[outer]}
{/if}
{sectionelse}
none
{/section}
An example of section looped key values:
{section name=sec1 loop=$contacts}
phone: {$contacts[sec1].phone}
<br>
fax: {$contacts[sec1].fax}
<br>
cell: {$contacts[sec1].cell}
<br>
{/section}
<p>
testing strip tags
{strip}
<table border=0>
<tr>
<td>
<A HREF="{$SCRIPT_NAME}">
<font color="red">This is a test </font>
</A>
</td>
</tr>
</table>
{/strip}
</PRE>
This is an example of the html_select_date function:
<form>
{html_select_date start_year=1998 end_year=2010}
</form>
This is an example of the html_select_time function:
<form>
{html_select_time use_24_hours=false}
</form>
This is an example of the html_options function:
<form>
<select name=states>
{html_options values=$option_values selected=$option_selected output=$option_output}
</select>
</form>
{include file="footer.tpl"}

View File

@@ -0,0 +1 @@
theme: jekyll-theme-minimal

View File

@@ -0,0 +1,332 @@
Tips & Tricks {#tips}
=============
Blank Variable Handling {#tips.blank.var.handling}
=======================
There may be times when you want to print a default value for an empty
variable instead of printing nothing, such as printing `&nbsp;` so that
html table backgrounds work properly. Many would use an
[`{if}`](#language.function.if) statement to handle this, but there is a
shorthand way with Smarty, using the
[`default`](#language.modifier.default) variable modifier.
> **Note**
>
> "Undefined variable" errors will show an E\_NOTICE if not disabled in
> PHP\'s [`error_reporting()`](&url.php-manual;error_reporting) level or
> Smarty\'s [`$error_reporting`](#variable.error.reporting) property and
> a variable had not been assigned to Smarty.
{* the long way *}
{if $title eq ''}
&nbsp;
{else}
{$title}
{/if}
{* the short way *}
{$title|default:'&nbsp;'}
See also [`default`](#language.modifier.default) modifier and [default
variable handling](#tips.default.var.handling).
Default Variable Handling {#tips.default.var.handling}
=========================
If a variable is used frequently throughout your templates, applying the
[`default`](#language.modifier.default) modifier every time it is
mentioned can get a bit ugly. You can remedy this by assigning the
variable its default value with the
[`{assign}`](#language.function.assign) function.
{* do this somewhere at the top of your template *}
{assign var='title' value=$title|default:'no title'}
{* if $title was empty, it now contains the value "no title" when you use it *}
{$title}
See also [`default`](#language.modifier.default) modifier and [blank
variable handling](#tips.blank.var.handling).
Passing variable title to header template {#tips.passing.vars}
=========================================
When the majority of your templates use the same headers and footers, it
is common to split those out into their own templates and
[`{include}`](#language.function.include) them. But what if the header
needs to have a different title, depending on what page you are coming
from? You can pass the title to the header as an
[attribute](#language.syntax.attributes) when it is included.
`mainpage.tpl` - When the main page is drawn, the title of "Main Page"
is passed to the `header.tpl`, and will subsequently be used as the
title.
{include file='header.tpl' title='Main Page'}
{* template body goes here *}
{include file='footer.tpl'}
`archives.tpl` - When the archives page is drawn, the title will be
"Archives". Notice in the archive example, we are using a variable from
the `archives_page.conf` file instead of a hard coded variable.
{config_load file='archive_page.conf'}
{include file='header.tpl' title=#archivePageTitle#}
{* template body goes here *}
{include file='footer.tpl'}
`header.tpl` - Notice that "Smarty News" is printed if the `$title`
variable is not set, using the [`default`](#language.modifier.default)
variable modifier.
<html>
<head>
<title>{$title|default:'Smarty News'}</title>
</head>
<body>
`footer.tpl`
</body>
</html>
Dates {#tips.dates}
=====
As a rule of thumb, always pass dates to Smarty as
[timestamps](&url.php-manual;time). This allows template designers to
use the [`date_format`](#language.modifier.date.format) modifier for
full control over date formatting, and also makes it easy to compare
dates if necessary.
{$startDate|date_format}
This will output:
Jan 4, 2009
{$startDate|date_format:"%Y/%m/%d"}
This will output:
2009/01/04
Dates can be compared in the template by timestamps with:
{if $order_date < $invoice_date}
...do something..
{/if}
When using [`{html_select_date}`](#language.function.html.select.date)
in a template, the programmer will most likely want to convert the
output from the form back into timestamp format. Here is a function to
help you with that.
<?php
// this assumes your form elements are named
// startDate_Day, startDate_Month, startDate_Year
$startDate = makeTimeStamp($startDate_Year, $startDate_Month, $startDate_Day);
function makeTimeStamp($year='', $month='', $day='')
{
if(empty($year)) {
$year = strftime('%Y');
}
if(empty($month)) {
$month = strftime('%m');
}
if(empty($day)) {
$day = strftime('%d');
}
return mktime(0, 0, 0, $month, $day, $year);
}
?>
See also [`{html_select_date}`](#language.function.html.select.date),
[`{html_select_time}`](#language.function.html.select.time),
[`date_format`](#language.modifier.date.format) and
[`$smarty.now`](#language.variables.smarty.now),
WAP/WML {#tips.wap}
=======
WAP/WML templates require a php [Content-Type
header](&url.php-manual;header) to be passed along with the template.
The easist way to do this would be to write a custom function that
prints the header. If you are using [caching](#caching), that won\'t
work so we\'ll do it using the [`{insert}`](#language.function.insert)
tag; remember `{insert}` tags are not cached! Be sure that there is
nothing output to the browser before the template, or else the header
may fail.
<?php
// be sure apache is configure for the .wml extensions!
// put this function somewhere in your application, or in Smarty.addons.php
function insert_header($params)
{
// this function expects $content argument
if (empty($params['content'])) {
return;
}
header($params['content']);
return;
}
?>
your Smarty template *must* begin with the insert tag :
{insert name=header content="Content-Type: text/vnd.wap.wml"}
<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
<!-- begin new wml deck -->
<wml>
<!-- begin first card -->
<card>
<do type="accept">
<go href="#two"/>
</do>
<p>
Welcome to WAP with Smarty!
Press OK to continue...
</p>
</card>
<!-- begin second card -->
<card id="two">
<p>
Pretty easy isn't it?
</p>
</card>
</wml>
Componentized Templates {#tips.componentized.templates}
=======================
Traditionally, programming templates into your applications goes as
follows: First, you accumulate your variables within your PHP
application, (maybe with database queries.) Then, you instantiate your
Smarty object, [`assign()`](#api.assign) the variables and
[`display()`](#api.display) the template. So lets say for example we
have a stock ticker on our template. We would collect the stock data in
our application, then assign these variables in the template and display
it. Now wouldn\'t it be nice if you could add this stock ticker to any
application by merely including the template, and not worry about
fetching the data up front?
You can do this by writing a custom plugin for fetching the content and
assigning it to a template variable.
`function.load_ticker.php` - drop file in
[`$plugins directory`](#variable.plugins.dir)
<?php
// setup our function for fetching stock data
function fetch_ticker($symbol)
{
// put logic here that fetches $ticker_info
// from some ticker resource
return $ticker_info;
}
function smarty_function_load_ticker($params, $smarty)
{
// call the function
$ticker_info = fetch_ticker($params['symbol']);
// assign template variable
$smarty->assign($params['assign'], $ticker_info);
}
?>
`index.tpl`
{load_ticker symbol='SMARTY' assign='ticker'}
Stock Name: {$ticker.name} Stock Price: {$ticker.price}
See also [`{include_php}`](#language.function.include.php),
[`{include}`](#language.function.include) and
[`{php}`](#language.function.php).
Obfuscating E-mail Addresses {#tips.obfuscating.email}
============================
Do you ever wonder how your email address gets on so many spam mailing
lists? One way spammers collect email addresses is from web pages. To
help combat this problem, you can make your email address show up in
scrambled javascript in the HTML source, yet it it will look and work
correctly in the browser. This is done with the
[`{mailto}`](#language.function.mailto) plugin.
<div id="contact">Send inquiries to
{mailto address=$EmailAddress encode='javascript' subject='Hello'}
</div>
> **Note**
>
> This method isn\'t 100% foolproof. A spammer could conceivably program
> his e-mail collector to decode these values, but not likely\....
> hopefully..yet \... wheres that quantum computer :-?.
See also [`escape`](#language.modifier.escape) modifier and
[`{mailto}`](#language.function.mailto).

View File

@@ -0,0 +1,120 @@
Troubleshooting
===============
Smarty/PHP errors {#smarty.php.errors}
=================
Smarty can catch many errors such as missing tag attributes or malformed
variable names. If this happens, you will see an error similar to the
following:
Warning: Smarty: [in index.tpl line 4]: syntax error: unknown tag - '%blah'
in /path/to/smarty/Smarty.class.php on line 1041
Fatal error: Smarty: [in index.tpl line 28]: syntax error: missing section name
in /path/to/smarty/Smarty.class.php on line 1041
Smarty shows you the template name, the line number and the error. After
that, the error consists of the actual line number in the Smarty class
that the error occurred.
There are certain errors that Smarty cannot catch, such as missing close
tags. These types of errors usually end up in PHP compile-time parsing
errors.
Parse error: parse error in /path/to/smarty/templates_c/index.tpl.php on line 75
When you encounter a PHP parsing error, the error line number will
correspond to the compiled PHP script, NOT the template itself. Usually
you can look at the template and spot the syntax error. Here are some
common things to look for: missing close tags for
[`{if}{/if}`](#language.function.if) or
[`{section}{/section}`](#language.function.if), or syntax of logic
within an `{if}` tag. If you can\'t find the error, you might have to
open the compiled PHP file and go to the line number to figure out where
the corresponding error is in the template.
Warning: Smarty error: unable to read resource: "index.tpl" in...
or
Warning: Smarty error: unable to read resource: "site.conf" in...
- The [`$template_dir`](#variable.template.dir) is incorrect, doesn\'t
exist or the file `index.tpl` is not in the `templates/` directory
- A [`{config_load}`](#language.function.config.load) function is
within a template (or [`configLoad()`](#api.config.load) has been
called) and either [`$config_dir`](#variable.config.dir) is
incorrect, does not exist or `site.conf` is not in the directory.
<!-- -->
Fatal error: Smarty error: the $compile_dir 'templates_c' does not exist,
or is not a directory...
- Either the [`$compile_dir`](#variable.compile.dir)is incorrectly
set, the directory does not exist, or `templates_c` is a file and
not a directory.
<!-- -->
Fatal error: Smarty error: unable to write to $compile_dir '....
- The [`$compile_dir`](#variable.compile.dir) is not writable by the
web server. See the bottom of the [installing
smarty](#installing.smarty.basic) page for more about permissions.
<!-- -->
Fatal error: Smarty error: the $cache_dir 'cache' does not exist,
or is not a directory. in /..
- This means that [`$caching`](#variable.caching) is enabled and
either; the [`$cache_dir`](#variable.cache.dir) is incorrectly set,
the directory does not exist, or `cache/` is a file and not a
directory.
<!-- -->
Fatal error: Smarty error: unable to write to $cache_dir '/...
- This means that [`$caching`](#variable.caching) is enabled and the
[`$cache_dir`](#variable.cache.dir) is not writable by the web
server. See the bottom of the [installing
smarty](#installing.smarty.basic) page for permissions.
<!-- -->
Warning: filemtime(): stat failed for /path/to/smarty/cache/3ab50a623e65185c49bf17c63c90cc56070ea85c.one.tpl.php
in /path/to/smarty/libs/sysplugins/smarty_resource.php
- This means that your application registered a custom error hander
(using [set\_error\_handler()](&url.php-manual;set_error_handler))
which is not respecting the given `$errno` as it should. If, for
whatever reason, this is the desired behaviour of your custom error
handler, please call
[`muteExpectedErrors()`](#api.mute.expected.errors) after you\'ve
registered your custom error handler.
See also [debugging](#chapter.debugging.console).

View File

@@ -0,0 +1,41 @@
Debugging Console {#chapter.debugging.console}
=================
There is a debugging console included with Smarty. The console informs
you of all the [included](./language-builtin-functions/language-function-include.md) templates,
[assigned](../programmers/api-functions/api-assign.md) variables and
[config](./language-variables/language-config-variables.md) file variables for the current
invocation of the template. A template file named `debug.tpl` is
included with the distribution of Smarty which controls the formatting
of the console.
Set [`$debugging`](../programmers/api-variables/variable-debugging.md) to TRUE in Smarty, and if needed
set [`$debug_tpl`](../programmers/api-variables/variable-debug-template.md) to the template resource
path to `debug.tpl` (this is in [`SMARTY_DIR`](../programmers/smarty-constants.md) by
default). When you load the page, a Javascript console window will pop
up and give you the names of all the included templates and assigned
variables for the current page.
To see the available variables for a particular template, see the
[`{debug}`](./language-builtin-functions/language-function-debug.md) template function. To disable the
debugging console, set [`$debugging`](../programmers/api-variables/variable-debugging.md) to FALSE. You
can also temporarily turn on the debugging console by putting
`SMARTY_DEBUG` in the URL if you enable this option with
[`$debugging_ctrl`](../programmers/api-variables/variable-debugging-ctrl.md).
> **Note**
>
> The debugging console does not work when you use the
> [`fetch()`](../programmers/api-functions/api-fetch.md) API, only when using
> [`display()`](../programmers/api-functions/api-display.md). It is a set of javascript statements
> added to the very bottom of the generated template. If you do not like
> javascript, you can edit the `debug.tpl` template to format the output
> however you like. Debug data is not cached and `debug.tpl` info is not
> included in the output of the debug console.
> **Note**
>
> The load times of each template and config file are in seconds, or
> fractions thereof.
See also [troubleshooting](../appendixes/troubleshooting.md).

View File

@@ -0,0 +1,77 @@
Config Files {#config.files}
============
Config files are handy for designers to manage global template variables
from one file. One example is template colors. Normally if you wanted to
change the color scheme of an application, you would have to go through
each and every template file and change the colors. With a config file,
the colors can be kept in one place, and only one file needs to be
updated.
# global variables
pageTitle = "Main Menu"
bodyBgColor = #000000
tableBgColor = #000000
rowBgColor = #00ff00
[Customer]
pageTitle = "Customer Info"
[Login]
pageTitle = "Login"
focus = "username"
Intro = """This is a value that spans more
than one line. you must enclose
it in triple quotes."""
# hidden section
[.Database]
host=my.example.com
db=ADDRESSBOOK
user=php-user
pass=foobar
Values of [config file variables](./language-variables/language-config-variables.md) can be in
quotes, but not necessary. You can use either single or double quotes.
If you have a value that spans more than one line, enclose the entire
value with triple quotes (\"\"\"). You can put comments into config
files by any syntax that is not a valid config file syntax. We recommend
using a `
#` (hash) at the beginning of the line.
The example config file above has two sections. Section names are
enclosed in \[brackets\]. Section names can be arbitrary strings not
containing `[` or `]` symbols. The four variables at the top are global
variables, or variables not within a section. These variables are always
loaded from the config file. If a particular section is loaded, then the
global variables and the variables from that section are also loaded. If
a variable exists both as a global and in a section, the section
variable is used. If you name two variables the same within a section,
the last one will be used unless
[`$config_overwrite`](../programmers/api-variables/variable-config-overwrite.md) is disabled.
Config files are loaded into templates with the built-in template
function [`
{config_load}`](./language-builtin-functions/language-function-config-load.md) or the API
[`configLoad()`](../programmers/api-functions/api-config-load.md) function.
You can hide variables or entire sections by prepending the variable
name or section name with a period(.) eg `[.hidden]`. This is useful if
your application reads the config files and gets sensitive data from
them that the template engine does not need. If you have third parties
doing template editing, you can be certain that they cannot read
sensitive data from the config file by loading it into the template.
Config files (or resources) are loaded by the same resource facilities
as templates. That means that a config file can also be loaded from a db
`$smarty->configLoad("db:my.conf")`.
See also [`{config_load}`](./language-builtin-functions/language-function-config-load.md),
[`$config_overwrite`](../programmers/api-variables/variable-config-overwrite.md),
[`$default_config_handler_func`](../programmers/api-variables/variable-default-config-handler-func.md),
[`getConfigVars()`](../programmers/api-functions/api-get-config-vars.md),
[`clearConfig()`](../programmers/api-functions/api-clear-config.md) and
[`configLoad()`](../programmers/api-functions/api-config-load.md)

View File

@@ -0,0 +1,33 @@
Basic Syntax
============
A simple Smarty template could look like this:
```html
<h1>{$title|escape}</h1>
<ul>
{foreach $cities as $city}
<li>{$city.name|escape} ({$city.population})</li>
{foreachelse}
<li>no cities found</li>
{/foreach}
</ul>
```
All Smarty template tags are enclosed within delimiters. By default
these are `{` and `}`, but they can be
[changed](../programmers/api-variables/variable-left-delimiter.md).
For the examples in this manual, we will assume that you are using the
default delimiters. In Smarty, all content outside of delimiters is
displayed as static content, or unchanged. When Smarty encounters
template tags, it attempts to interpret them, and displays the
appropriate output in their place.
The basis components of the Smarty syntax are:
- [Comments](./language-basic-syntax/language-syntax-comments.md)
- [Variables](./language-basic-syntax/language-syntax-variables.md)
- [Functions](./language-basic-syntax/language-syntax-functions.md)
- [Attributes](./language-basic-syntax/language-syntax-attributes.md)
- [Quotes](./language-basic-syntax/language-syntax-quotes.md)
- [Math](./language-basic-syntax/language-math.md)
- [Escaping](./language-basic-syntax/language-escaping.md)

View File

@@ -0,0 +1,84 @@
Escaping Smarty Parsing {#language.escaping}
=======================
It is sometimes desirable or even necessary to have Smarty ignore
sections it would otherwise parse. A classic example is embedding
Javascript or CSS code in a template. The problem arises as those
languages use the { and } characters which are also the default
[delimiters](#language.function.ldelim) for Smarty.
> **Note**
>
> A good practice for avoiding escapement altogether is by separating
> your Javascript/CSS into their own files and use standard HTML methods
> to access them. This will also take advantage of browser script
> caching. When you need to embed Smarty variables/functions into your
> Javascript/CSS, then the following applies.
In Smarty templates, the { and } braces will be ignored so long as they
are surrounded by white space. This behavior can be disabled by setting
the Smarty class variable [`$auto_literal`](#variable.auto.literal) to
false.
<script>
// the following braces are ignored by Smarty
// since they are surrounded by whitespace
function foobar {
alert('foobar!');
}
// this one will need literal escapement
{literal}
function bazzy {alert('foobar!');}
{/literal}
</script>
[`{literal}..{/literal}`](#language.function.literal) blocks are used
for escaping blocks of template logic. You can also escape the braces
individually with
[`{ldelim}`](#language.function.ldelim),[`{rdelim}`](#language.function.ldelim)
tags or
[`{$smarty.ldelim}`,`{$smarty.rdelim}`](#language.variables.smarty.ldelim)
variables.
Smarty\'s default delimiters { and } cleanly represent presentational
content. However if another set of delimiters suit your needs better,
you can change them with Smarty\'s
[`$left_delimiter`](#variable.left.delimiter) and
[`$right_delimiter`](#variable.right.delimiter) values.
> **Note**
>
> Changing delimiters affects ALL template syntax and escapement. Be
> sure to clear out cache and compiled files if you decide to change
> them.
<?php
$smarty->left_delimiter = '<!--{';
$smarty->right_delimiter = '}-->';
$smarty->assign('foo', 'bar');
$smarty->assign('name', 'Albert');
$smarty->display('example.tpl');
?>
Where the template is:
Welcome <!--{$name}--> to Smarty
<script language="javascript">
var foo = <!--{$foo}-->;
function dosomething() {
alert("foo is " + foo);
}
dosomething();
</script>

View File

@@ -0,0 +1,29 @@
Math {#language.math}
====
Math can be applied directly to variable values.
{$foo+1}
{$foo*$bar}
{* some more complicated examples *}
{$foo->bar-$bar[1]*$baz->foo->bar()-3*7}
{if ($foo+$bar.test%$baz*134232+10+$b+10)}
{$foo|truncate:"`$fooTruncCount/$barTruncFactor-1`"}
{assign var="foo" value="`$foo+$bar`"}
> **Note**
>
> Although Smarty can handle some very complex expressions and syntax,
> it is a good rule of thumb to keep the template syntax minimal and
> focused on presentation. If you find your template syntax getting too
> complex, it may be a good idea to move the bits that do not deal
> explicitly with presentation to PHP by way of plugins or modifiers.

View File

@@ -0,0 +1,50 @@
Attributes {#language.syntax.attributes}
==========
Most of the [functions](#language.syntax.functions) take attributes that
specify or modify their behavior. Attributes to Smarty functions are
much like HTML attributes. Static values don\'t have to be enclosed in
quotes, but it is required for literal strings. Variables with or
without modifiers may also be used, and should not be in quotes. You can
even use PHP function results, plugin results and complex expressions.
Some attributes require boolean values (TRUE or FALSE). These can be
specified as `true` and `false`. If an attribute has no value assigned
it gets the default boolean value of true.
{include file="header.tpl"}
{include file="header.tpl" nocache} // is equivalent to nocache=true
{include file="header.tpl" attrib_name="attrib value"}
{include file=$includeFile}
{include file=#includeFile# title="My Title"}
{assign var=foo value={counter}} // plugin result
{assign var=foo value=substr($bar,2,5)} // PHP function result
{assign var=foo value=$bar|strlen} // using modifier
{assign var=foo value=$buh+$bar|strlen} // more complex expression
{html_select_date display_days=true}
{mailto address="smarty@example.com"}
<select name="company_id">
{html_options options=$companies selected=$company_id}
</select>
> **Note**
>
> Although Smarty can handle some very complex expressions and syntax,
> it is a good rule of thumb to keep the template syntax minimal and
> focused on presentation. If you find your template syntax getting too
> complex, it may be a good idea to move the bits that do not deal
> explicitly with presentation to PHP by way of plugins or modifiers.

View File

@@ -0,0 +1,71 @@
Comments {#language.syntax.comments}
========
Template comments are surrounded by asterisks, and that is surrounded by
the [delimiter](#variable.left.delimiter) tags like so:
::: {.informalexample}
{* this is a comment *}
:::
Smarty comments are NOT displayed in the final output of the template,
unlike `<!-- HTML comments -->`. These are useful for making internal
notes in the templates which no one will see ;-)
{* I am a Smarty comment, I don't exist in the compiled output *}
<html>
<head>
<title>{$title}</title>
</head>
<body>
{* another single line smarty comment *}
<!-- HTML comment that is sent to the browser -->
{* this multiline smarty
comment is
not sent to browser
*}
{*********************************************************
Multi line comment block with credits block
@ author: bg@example.com
@ maintainer: support@example.com
@ para: var that sets block style
@ css: the style output
**********************************************************}
{* The header file with the main logo and stuff *}
{include file='header.tpl'}
{* Dev note: the $includeFile var is assigned in foo.php script *}
<!-- Displays main content block -->
{include file=$includeFile}
{* this <select> block is redundant *}
{*
<select name="company">
{html_options options=$vals selected=$selected_id}
</select>
*}
<!-- Show header from affiliate is disabled -->
{* $affiliate|upper *}
{* you cannot nest comments *}
{*
<select name="company">
{* <option value="0">-- none -- </option> *}
{html_options options=$vals selected=$selected_id}
</select>
*}
</body>
</html>

View File

@@ -0,0 +1,40 @@
Functions {#language.syntax.functions}
=========
Every Smarty tag either prints a [variable](#language.variables) or
invokes some sort of function. These are processed and displayed by
enclosing the function and its [attributes](#language.syntax.attributes)
within delimiters like so: `{funcname attr1="val1" attr2="val2"}`.
{config_load file="colors.conf"}
{include file="header.tpl"}
{insert file="banner_ads.tpl" title="My Site"}
{if $logged_in}
Welcome, <span style="color:{#fontColor#}">{$name}!</span>
{else}
hi, {$name}
{/if}
{include file="footer.tpl"}
- Both [built-in functions](#language.builtin.functions) and [custom
functions](#language.custom.functions) have the same syntax within
templates.
- Built-in functions are the **inner** workings of Smarty, such as
[`{if}`](#language.function.if),
[`{section}`](#language.function.section) and
[`{strip}`](#language.function.strip). There should be no need to
change or modify them.
- Custom functions are **additional** functions implemented via
[plugins](#plugins). They can be modified to your liking, or you can
create new ones. [`{html_options}`](#language.function.html.options)
is an example of a custom function.
See also [`registerPlugin()`](#api.register.plugin)

View File

@@ -0,0 +1,61 @@
Embedding Vars in Double Quotes {#language.syntax.quotes}
===============================
- Smarty will recognize [assigned](#api.assign)
[variables](#language.syntax.variables) embedded in \"double
quotes\" so long as the variable name contains only numbers, letters
and under\_scores. See [naming](&url.php-manual;language.variables)
for more detail.
- With any other characters, for example a period(.) or
`$object->reference`, then the variable must be surrounded by
`` `backticks` ``.
- In addition Smarty3 does allow embedded Smarty tags in double quoted
strings. This is useful if you want to include variables with
modifiers, plugin or PHP function results.
<!-- -->
{func var="test $foo test"} // sees $foo
{func var="test $foo_bar test"} // sees $foo_bar
{func var="test `$foo[0]` test"} // sees $foo[0]
{func var="test `$foo[bar]` test"} // sees $foo[bar]
{func var="test $foo.bar test"} // sees $foo (not $foo.bar)
{func var="test `$foo.bar` test"} // sees $foo.bar
{func var="test `$foo.bar` test"|escape} // modifiers outside quotes!
{func var="test {$foo|escape} test"} // modifiers inside quotes!
{func var="test {time()} test"} // PHP function result
{func var="test {counter} test"} // plugin result
{func var="variable foo is {if !$foo}not {/if} defined"} // Smarty block function
{* will replace $tpl_name with value *}
{include file="subdir/$tpl_name.tpl"}
{* does NOT replace $tpl_name *}
{include file='subdir/$tpl_name.tpl'} // vars require double quotes!
{* must have backticks as it contains a dot "." *}
{cycle values="one,two,`$smarty.config.myval`"}
{* must have backticks as it contains a dot "." *}
{include file="`$module.contact`.tpl"}
{* can use variable with dot syntax *}
{include file="`$module.$view`.tpl"}
> **Note**
>
> Although Smarty can handle some very complex expressions and syntax,
> it is a good rule of thumb to keep the template syntax minimal and
> focused on presentation. If you find your template syntax getting too
> complex, it may be a good idea to move the bits that do not deal
> explicitly with presentation to PHP by way of plugins or modifiers.
See also [`escape`](#language.modifier.escape).

View File

@@ -0,0 +1,111 @@
Variables {#language.syntax.variables}
=========
Template variables start with the \$dollar sign. They can contain
numbers, letters and underscores, much like a [PHP
variable](&url.php-manual;language.variables). You can reference arrays
by index numerically or non-numerically. Also reference object
properties and methods.
[Config file variables](#language.config.variables) are an exception to
the \$dollar syntax and are instead referenced with surrounding
\#hashmarks\#, or via the
[`$smarty.config`](#language.variables.smarty.config) variable.
{$foo} <-- displaying a simple variable (non array/object)
{$foo[4]} <-- display the 5th element of a zero-indexed array
{$foo.bar} <-- display the "bar" key value of an array, similar to PHP $foo['bar']
{$foo.$bar} <-- display variable key value of an array, similar to PHP $foo[$bar]
{$foo->bar} <-- display the object property "bar"
{$foo->bar()} <-- display the return value of object method "bar"
{#foo#} <-- display the config file variable "foo"
{$smarty.config.foo} <-- synonym for {#foo#}
{$foo[bar]} <-- syntax only valid in a section loop, see {section}
{assign var=foo value='baa'}{$foo} <-- displays "baa", see {assign}
Many other combinations are allowed
{$foo.bar.baz}
{$foo.$bar.$baz}
{$foo[4].baz}
{$foo[4].$baz}
{$foo.bar.baz[4]}
{$foo->bar($baz,2,$bar)} <-- passing parameters
{"foo"} <-- static values are allowed
{* display the server variable "SERVER_NAME" ($_SERVER['SERVER_NAME'])*}
{$smarty.server.SERVER_NAME}
Math and embedding tags:
{$x+$y} // will output the sum of x and y.
{assign var=foo value=$x+$y} // in attributes
{$foo[$x+3]} // as array index
{$foo={counter}+3} // tags within tags
{$foo="this is message {counter}"} // tags within double quoted strings
Defining Arrays:
{assign var=foo value=[1,2,3]}
{assign var=foo value=['y'=>'yellow','b'=>'blue']}
{assign var=foo value=[1,[9,8],3]} // can be nested
Short variable assignment:
{$foo=$bar+2}
{$foo = strlen($bar)} // function in assignment
{$foo = myfunct( ($x+$y)*3 )} // as function parameter
{$foo.bar=1} // assign to specific array element
{$foo.bar.baz=1}
{$foo[]=1} // appending to an array
Smarty "dot" syntax (note: embedded {} are used to address ambiguities):
{$foo.a.b.c} => $foo['a']['b']['c']
{$foo.a.$b.c} => $foo['a'][$b]['c'] // with variable index
{$foo.a.{$b+4}.c} => $foo['a'][$b+4]['c'] // with expression as index
{$foo.a.{$b.c}} => $foo['a'][$b['c']] // with nested index
PHP-like syntax, alternative to "dot" syntax:
{$foo[1]} // normal access
{$foo['bar']}
{$foo['bar'][1]}
{$foo[$x+$x]} // index may contain any expression
{$foo[$bar[1]]} // nested index
{$foo[section_name]} // smarty {section} access, not array access!
Variable variables:
$foo // normal variable
$foo_{$bar} // variable name containing other variable
$foo_{$x+$y} // variable name containing expressions
$foo_{$bar}_buh_{$blar} // variable name with multiple segments
{$foo_{$x}} // will output the variable $foo_1 if $x has a value of 1.
Object chaining:
{$object->method1($x)->method2($y)}
Direct PHP function access:
{time()}
> **Note**
>
> Although Smarty can handle some very complex expressions and syntax,
> it is a good rule of thumb to keep the template syntax minimal and
> focused on presentation. If you find your template syntax getting too
> complex, it may be a good idea to move the bits that do not deal
> explicitly with presentation to PHP by way of plugins or modifiers.
Request variables such as `$_GET`, `$_SESSION`, etc are available via
the reserved [`$smarty`](#language.variables.smarty) variable.
See also [`$smarty`](#language.variables.smarty), [config
variables](#language.config.variables)
[`{assign}`](#language.function.assign) and [`assign()`](#api.assign).

View File

@@ -0,0 +1,39 @@
Built-in Functions {#language.builtin.functions}
==================
## Table of contents
- [{$var=...}](./language-builtin-functions/language-function-shortform-assign.md)
- [{append}](./language-builtin-functions/language-function-append.md)
- [{assign}](./language-builtin-functions/language-function-assign.md)
- [{block}](./language-builtin-functions/language-function-block.md)
- [{call}](./language-builtin-functions/language-function-call.md)
- [{capture}](./language-builtin-functions/language-function-capture.md)
- [{config_load}](./language-builtin-functions/language-function-config.load)
- [{debug}](./language-builtin-functions/language-function-debug.md)
- [{extends}](./language-builtin-functions/language-function-extends.md)
- [{for}](./language-builtin-functions/language-function-for.md)
- [{foreach},{foreachelse}](./language-builtin-functions/language-function-foreach.md)
- [{function}](./language-builtin-functions/language-function-function.md)
- [{if},{elseif},{else}](./language-builtin-functions/language-function-if.md)
- [{include}](./language-builtin-functions/language-function-include.md)
- [{include_php}](./language-builtin-functions/language-function-include.php)
- [{insert}](./language-builtin-functions/language-function-insert.md)
- [{ldelim},{rdelim}](./language-builtin-functions/language-function-ldelim.md)
- [{literal}](./language-builtin-functions/language-function-literal.md)
- [{nocache}](./language-builtin-functions/language-function-nocache.md)
- [{section},{sectionelse}](./language-builtin-functions/language-function-section.md)
- [{setfilter}](./language-builtin-functions/language-function-setfilter.md)
- [{strip}](./language-builtin-functions/language-function-strip.md)
- [{while}](./language-builtin-functions/language-function-while.md)
Smarty comes with several built-in functions. These built-in functions
are the integral part of the smarty template engine. They are compiled
into corresponding inline PHP code for maximum performance.
You cannot create your own [custom
functions](./language-custom-functions.md) with the same name; and you
should not need to modify the built-in functions.
A few of these functions have an `assign` attribute which collects the
result the function to a named template variable instead of being
output; much like the [`{assign}`](./language-builtin-functions/language-function-assign.md) function.

View File

@@ -0,0 +1,49 @@
{append} {#language.function.append}
========
`{append}` is used for creating or appending template variable arrays
**during the execution of a template**.
> **Note**
>
> Assignment of variables in-template is essentially placing application
> logic into the presentation that may be better handled in PHP. Use at
> your own discretion.
**Attributes:**
Attribute Name Type Required Default Description
---------------- -------- ---------- --------- ----------------------------------------------------------------------------------------------------
var string Yes *n/a* The name of the variable being assigned
value string Yes *n/a* The value being assigned
index string No *n/a* The index for the new array element. If not specified the value is append to the end of the array.
scope string No *n/a* The scope of the assigned variable: \'parent\',\'root\' or \'global\'
**Option Flags:**
Name Description
--------- -----------------------------------------------------
nocache Assigns the variable with the \'nocache\' attribute
{append var='name' value='Bob' index='first'}
{append var='name' value='Meyer' index='last'}
// or
{append 'name' 'Bob' index='first'} {* short-hand *}
{append 'name' 'Meyer' index='last'} {* short-hand *}
The first name is {$name.first}.<br>
The last name is {$name.last}.
The above example will output:
The first name is Bob.
The last name is Meyer.
See also [`append()`](#api.append) and
[`getTemplateVars()`](#api.get.template.vars).

View File

@@ -0,0 +1,149 @@
{assign} {#language.function.assign}
========
`{assign}` is used for assigning template variables **during the
execution of a template**.
> **Note**
>
> Assignment of variables in-template is essentially placing application
> logic into the presentation that may be better handled in PHP. Use at
> your own discretion.
> **Note**
>
> See also the [`short-form`](#language.function.shortform.assign)
> method of assigning template vars.
**Attributes:**
Attribute Name Type Required Default Description
---------------- -------- ---------- --------- -----------------------------------------------------------------------
var string Yes *n/a* The name of the variable being assigned
value string Yes *n/a* The value being assigned
scope string No *n/a* The scope of the assigned variable: \'parent\',\'root\' or \'global\'
**Option Flags:**
Name Description
--------- -----------------------------------------------------
nocache Assigns the variable with the \'nocache\' attribute
{assign var="name" value="Bob"}
{assign "name" "Bob"} {* short-hand *}
The value of $name is {$name}.
The above example will output:
The value of $name is Bob.
{assign var="name" value="Bob" nocache}
{assign "name" "Bob" nocache} {* short-hand *}
The value of $name is {$name}.
The above example will output:
The value of $name is Bob.
{assign var=running_total value=$running_total+$some_array[$row].some_value}
Variables assigned in the included template will be seen in the
including template.
{include file="sub_template.tpl"}
...
{* display variable assigned in sub_template *}
{$foo}<br>
...
The template above includes the example `sub_template.tpl` below
...
{* foo will be known also in the including template *}
{assign var="foo" value="something" scope=parent}
{* bar is assigned only local in the including template *}
{assign var="bar" value="value"}
...
You can assign a variable to root of the current root tree. The variable
is seen by all templates using the same root tree.
{assign var=foo value="bar" scope="root"}
A global variable is seen by all templates.
{assign var=foo value="bar" scope="global"}
{assign "foo" "bar" scope="global"} {* short-hand *}
To access `{assign}` variables from a php script use
[`getTemplateVars()`](#api.get.template.vars). Here\'s the template that
creates the variable `$foo`.
{assign var="foo" value="Smarty"}
The template variables are only available after/during template
execution as in the following script.
<?php
// this will output nothing as the template has not been executed
echo $smarty->getTemplateVars('foo');
// fetch the template to a variable
$whole_page = $smarty->fetch('index.tpl');
// this will output 'smarty' as the template has been executed
echo $smarty->getTemplateVars('foo');
$smarty->assign('foo','Even smarter');
// this will output 'Even smarter'
echo $smarty->getTemplateVars('foo');
?>
The following functions can also *optionally* assign template variables.
[`{capture}`](#language.function.capture),
[`{include}`](#language.function.include),
[`{include_php}`](#language.function.include.php),
[`{insert}`](#language.function.insert),
[`{counter}`](#language.function.counter),
[`{cycle}`](#language.function.cycle),
[`{eval}`](#language.function.eval),
[`{fetch}`](#language.function.fetch),
[`{math}`](#language.function.math),
[`{textformat}`](#language.function.textformat)
See also [`{$var=...}`](#language.function.shortform.assign),
[`assign()`](#api.assign) and
[`getTemplateVars()`](#api.get.template.vars).

View File

@@ -0,0 +1,191 @@
{block} {#language.function.block}
=======
`{block}` is used to define a named area of template source for template
inheritance. For details see section of [Template
Interitance](#advanced.features.template.inheritance).
The `{block}` template source area of a child template will replace the
correponding areas in the parent template(s).
Optionally `{block}` areas of child and parent templates can be merged
into each other. You can append or prepend the parent `{block}` content
by using the `append` or `prepend` option flag with the childs `{block}`
definition. With the {\$smarty.block.parent} the `{block}` content of
the parent template can be inserted at any location of the child
`{block}` content. {\$smarty.block.child} inserts the `{block}` content
of the child template at any location of the parent `{block}`.
`{blocks}'s` can be nested.
**Attributes:**
Attribute Name Type Required Default Description
---------------- -------- ---------- --------- ---------------------------------------
name string Yes *n/a* The name of the template source block
**Option Flags (in child templates only):**
Name Description
--------- -------------------------------------------------------------------------------------------
append The `{block}` content will be be appended to the content of the parent template `{block}`
prepend The `{block}` content will be prepended to the content of the parent template `{block}`
hide Ignore the block content if no child block of same name is existing.
nocache Disables caching of the `{block}` content
parent.tpl
<html>
<head>
<title>{block name="title"}Default Title{/block}</title>
<title>{block "title"}Default Title{/block}</title> {* short-hand *}
</head>
</html>
child.tpl
{extends file="parent.tpl"}
{block name="title"}
Page Title
{/block}
The result would look like
<html>
<head>
<title>Page Title</title>
</head>
</html>
parent.tpl
<html>
<head>
<title>{block name="title"}Title - {/block}</title>
</head>
</html>
child.tpl
{extends file="parent.tpl"}
{block name="title" prepend}
Page Title
{/block}
The result would look like
<html>
<head>
<title>Title - Page Title</title>
</head>
</html>
parent.tpl
<html>
<head>
<title>{block name="title"} is my title{/block}</title>
</head>
</html>
child.tpl
{extends file="parent.tpl"}
{block name="title" append}
Page Title
{/block}
The result would look like
<html>
<head>
<title>Page title is my titel</title>
</head>
</html>
parent.tpl
<html>
<head>
<title>{block name="title"}The {$smarty.block.child} was inserted here{/block}</title>
</head>
</html>
child.tpl
{extends file="parent.tpl"}
{block name="title"}
Child Title
{/block}
The result would look like
<html>
<head>
<title>The Child Title was inserted here</title>
</head>
</html>
parent.tpl
<html>
<head>
<title>{block name="title"}Parent Title{/block}</title>
</head>
</html>
child.tpl
{extends file="parent.tpl"}
{block name="title"}
You will see now - {$smarty.block.parent} - here
{/block}
The result would look like
<html>
<head>
<title>You will see now - Parent Title - here</title>
</head>
</html>
See also [Template
Inheritance](#advanced.features.template.inheritance),
[`$smarty.block.parent`](#language.variables.smarty.block.parent),
[`$smarty.block.child`](#language.variables.smarty.block.child), and
[`{extends}`](#language.function.extends)

View File

@@ -0,0 +1,76 @@
{call} {#language.function.call}
======
`{call}` is used to call a template function defined by the
[`{function}`](#language.function.function) tag just like a plugin
function.
> **Note**
>
> Template functions are defined global. Since the Smarty compiler is a
> single-pass compiler, The [`{call}`](#language.function.call) tag must
> be used to call a template function defined externally from the given
> template. Otherwise you can directly use the function as
> `{funcname ...}` in the template.
- The `{call}` tag must have the `name` attribute which contains the
the name of the template function.
- Values for variables can be passed to the template function as
[attributes](#language.syntax.attributes).
**Attributes:**
Attribute Name Type Required Default Description
---------------- -------------- ---------- --------- ------------------------------------------------------------------------------------------
name string Yes *n/a* The name of the template function
assign string No *n/a* The name of the variable that the output of called template function will be assigned to
\[var \...\] \[var type\] No *n/a* variable to pass local to template function
**Option Flags:**
Name Description
--------- --------------------------------------------
nocache Call the template function in nocache mode
{* define the function *}
{function name=menu level=0}
<ul class="level{$level}">
{foreach $data as $entry}
{if is_array($entry)}
<li>{$entry@key}</li>
{call name=menu data=$entry level=$level+1}
{else}
<li>{$entry}</li>
{/if}
{/foreach}
</ul>
{/function}
{* create an array to demonstrate *}
{$menu = ['item1','item2','item3' => ['item3-1','item3-2','item3-3' =>
['item3-3-1','item3-3-2']],'item4']}
{* run the array through the function *}
{call name=menu data=$menu}
{call menu data=$menu} {* short-hand *}
Will generate the following output
* item1
* item2
* item3
o item3-1
o item3-2
o item3-3
+ item3-3-1
+ item3-3-2
* item4
See also [`{function}`](#language.function.function)

View File

@@ -0,0 +1,82 @@
{capture} {#language.function.capture}
=========
`{capture}` is used to collect the output of the template between the
tags into a variable instead of displaying it. Any content between
`{capture name='foo'}` and `{/capture}` is collected into the variable
specified in the `name` attribute.
The captured content can be used in the template from the variable
[`$smarty.capture.foo`](#language.variables.smarty.capture) where "foo"
is the value passed in the `name` attribute. If you do not supply the
`name` attribute, then "default" will be used as the name ie
`$smarty.capture.default`.
`{capture}'s` can be nested.
**Attributes:**
Attribute Name Type Required Default Description
---------------- -------- ---------- --------- ----------------------------------------------------------------------
name string Yes *n/a* The name of the captured block
assign string No *n/a* The variable name where to assign the captured output to
append string No *n/a* The name of an array variable where to append the captured output to
**Option Flags:**
Name Description
--------- -----------------------------------------
nocache Disables caching of this captured block
> **Note**
>
> Be careful when capturing [`{insert}`](#language.function.insert)
> output. If you have [`$caching`](#caching) enabled and you have
> [`{insert}`](#language.function.insert) commands that you expect to
> run within cached content, do not capture this content.
{* we don't want to print a div tag unless content is displayed *}
{capture name="banner"}
{capture "banner"} {* short-hand *}
{include file="get_banner.tpl"}
{/capture}
{if $smarty.capture.banner ne ""}
<div id="banner">{$smarty.capture.banner}</div>
{/if}
This example demonstrates the capture function.
{capture name=some_content assign=popText}
{capture some_content assign=popText} {* short-hand *}
The server is {$my_server_name|upper} at {$my_server_addr}<br>
Your ip is {$my_ip}.
{/capture}
<a href="#">{$popText}</a>
This example also demonstrates how multiple calls of capture can be used
to create an array with captured content.
{capture append="foo"}hello{/capture}I say just {capture append="foo"}world{/capture}
{foreach $foo as $text}{$text} {/foreach}
The above example will output:
I say just hello world
See also [`$smarty.capture`](#language.variables.smarty.capture),
[`{eval}`](#language.function.eval),
[`{fetch}`](#language.function.fetch), [`fetch()`](#api.fetch) and
[`{assign}`](#language.function.assign).

View File

@@ -0,0 +1,91 @@
{config\_load} {#language.function.config.load}
==============
`{config_load}` is used for loading config
[`#variables#`](#language.config.variables) from a [configuration
file](#config.files) into the template.
**Attributes:**
Attribute Name Type Required Default Description
---------------- -------- ---------- --------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
file string Yes *n/a* The name of the config file to include
section string No *n/a* The name of the section to load
scope string no *local* How the scope of the loaded variables are treated, which must be one of local, parent or global. local means variables are loaded into the local template context. parent means variables are loaded into both the local context and the parent template that called it. global means variables are available to all templates.
The `example.conf` file.
#this is config file comment
# global variables
pageTitle = "Main Menu"
bodyBgColor = #000000
tableBgColor = #000000
rowBgColor = #00ff00
#customer variables section
[Customer]
pageTitle = "Customer Info"
and the template
{config_load file="example.conf"}
{config_load "example.conf"} {* short-hand *}
<html>
<title>{#pageTitle#|default:"No title"}</title>
<body bgcolor="{#bodyBgColor#}">
<table border="{#tableBorderSize#}" bgcolor="{#tableBgColor#}">
<tr bgcolor="{#rowBgColor#}">
<td>First</td>
<td>Last</td>
<td>Address</td>
</tr>
</table>
</body>
</html>
[Config Files](#config.files) may also contain sections. You can load
variables from within a section with the added attribute `section`. Note
that global config variables are always loaded along with section
variables, and same-named section variables overwrite the globals.
> **Note**
>
> Config file *sections* and the built-in template function called
> [`{section}`](#language.function.section) have nothing to do with each
> other, they just happen to share a common naming convention.
{config_load file='example.conf' section='Customer'}
{config_load 'example.conf' 'Customer'} {* short-hand *}
<html>
<title>{#pageTitle#}</title>
<body bgcolor="{#bodyBgColor#}">
<table border="{#tableBorderSize#}" bgcolor="{#tableBgColor#}">
<tr bgcolor="{#rowBgColor#}">
<td>First</td>
<td>Last</td>
<td>Address</td>
</tr>
</table>
</body>
</html>
See [`$config_overwrite`](#variable.config.overwrite) to create arrays
of config file variables.
See also the [config files](#config.files) page, [config
variables](#language.config.variables) page,
[`$config_dir`](#variable.config.dir),
[`getConfigVars()`](#api.get.config.vars) and
[`configLoad()`](#api.config.load).

View File

@@ -0,0 +1,18 @@
{debug} {#language.function.debug}
=======
`{debug}` dumps the debug console to the page. This works regardless of
the [debug](#chapter.debugging.console) settings in the php script.
Since this gets executed at runtime, this is only able to show the
[assigned](#api.assign) variables; not the templates that are in use.
However, you can see all the currently available variables within the
scope of a template.
If caching is enabled and a page is loaded from cache `{debug}` does
show only the variables which assigned for the cached page.
In order to see also the variables which have been locally assigned
within the template it does make sense to place the `{debug}` tag at the
end of the template.
See also the [debugging console page](#chapter.debugging.console).

View File

@@ -0,0 +1,37 @@
{extends} {#language.function.extends}
=========
`{extends}` tags are used in child templates in template inheritance for
extending parent templates. For details see section of [Template
Interitance](#advanced.features.template.inheritance).
- The `{extends}` tag must be on the first line of the template.
- If a child template extends a parent template with the `{extends}`
tag it may contain only `{block}` tags. Any other template content
is ignored.
- Use the syntax for [template resources](#resources) to extend files
outside of the [`$template_dir`](#variable.template.dir) directory.
> **Note**
>
> When extending a variable parent like `{extends file=$parent_file}`,
> make sure you include `$parent_file` in the
> [`$compile_id`](#variable.compile.id). Otherwise Smarty cannot
> distinguish between different `$parent_file`s.
**Attributes:**
Attribute Name Type Required Default Description
---------------- -------- ---------- --------- -------------------------------------------------
file string Yes *n/a* The name of the template file which is extended
{extends file='parent.tpl'}
{extends 'parent.tpl'} {* short-hand *}
See also [Template Interitance](#advanced.features.template.inheritance)
and [`{block}`](#language.function.block).

View File

@@ -0,0 +1,97 @@
{for} {#language.function.for}
=====
The `{for}{forelse}` tag is used to create simple loops. The following
different formarts are supported:
- `{for $var=$start to $end}` simple loop with step size of 1.
- `{for $var=$start to $end step $step}` loop with individual step
size.
`{forelse}` is executed when the loop is not iterated.
**Attributes:**
Attribute Name Shorthand Type Required Default Description
---------------- ----------- --------- ---------- --------- --------------------------------
max n/a integer No *n/a* Limit the number of iterations
**Option Flags:**
Name Description
--------- --------------------------------------
nocache Disables caching of the `{for}` loop
<ul>
{for $foo=1 to 3}
<li>{$foo}</li>
{/for}
</ul>
The above example will output:
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
$smarty->assign('to',10);
<ul>
{for $foo=3 to $to max=3}
<li>{$foo}</li>
{/for}
</ul>
The above example will output:
<ul>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
$smarty->assign('start',10);
$smarty->assign('to',5);
<ul>
{for $foo=$start to $to}
<li>{$foo}</li>
{forelse}
no iteration
{/for}
</ul>
The above example will output:
no iteration
See also [`{foreach}`](#language.function.foreach),
[`{section}`](#language.function.section) and
[`{while}`](#language.function.while)

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