Compare commits

...

61 Commits

Author SHA1 Message Date
slawkens1
cb8d8c4173 * update TODO 2018-01-12 01:20:33 +01:00
slawkens
1949c197d6 * installation of important stuff with help of AJAX
* installation will be now done with AJAX request (jQuery), that will instaltly notify about the status of the installation (no waiting without clue anymore)
* install items & weapons on installation (before monsters)
2018-01-09 10:26:06 +01:00
slawkens1
16dab3a2cc * updated OTS_House class to support latest TFS 1.x 2018-01-08 22:37:20 +01:00
slawkens1
497a073162 * fixed some MySQL errors on OTS_Player.php
* added function OTS_Player::getAccountId()
* (internal) shortened samples inserting code
* (internal) shortened config.highscores_ignored_ids updating code
* updated TODO
2018-01-08 22:35:36 +01:00
slawkens1
22e245ecff * enabled emoticons plugin in tinymce :) 2018-01-08 20:02:25 +01:00
slawkens
b03433d8a8 * added missing function is_sub_dir (to the last commit) 2018-01-08 17:28:05 +01:00
slawkens
4f0fca021c * uninstall: do not allow directories outside BASE
* uninstall: do not allow absolute paths
2018-01-08 17:19:56 +01:00
slawkens
5aa1ae003e * allow comments inside plugin json file
* updated German translation (by German native speaker)
2018-01-08 16:15:34 +01:00
slawkens
f29758939c * some fixes regarding migrations 2018-01-08 14:03:10 +01:00
slawkens
3703c2b431 * updated tinymce to the latest (4.7.4) version 2018-01-08 13:10:32 +01:00
slawkens
d289d9a8ff * update CHANGELOG from 0.7 branch 2018-01-08 11:57:37 +01:00
slawkens
a083dd048d * fixed PHP warning about country not existing on online and characteres pages 2018-01-08 11:47:41 +01:00
slawkens
f09c30d370 * fixed characters page - config.characters.frags "Notice: Use of undefined constant" 2018-01-08 11:39:49 +01:00
slawkens
9e28d46ee7 * fixed displaying special outfits (GM, CM) in online page 2018-01-08 11:23:44 +01:00
slawkens
c133482659 * added new forum option: "Enable HTML"
* will be by default enabled for newses
* fixed bbcode parsing
2018-01-08 10:53:14 +01:00
slawkens1
bf71c1aee8 * fixed tr bgcolor (#38) 2018-01-08 08:12:32 +01:00
slawkens1
4102b44352 * important fix for servers with promotion column (#36)
* caused player.vocation to be resetted when saving player, for example:
on change name, accept invite to guild, leave guild
* fixed empty success message on leave guild
* (internal) using $player->getVocationName() where possible instead of
older method
* fixed some warning in guild show
2018-01-08 01:00:56 +01:00
slawkens1
acf2e2fb4a * nothing important 2018-01-08 00:19:16 +01:00
slawkens1
f9de0b5eb9 * fixed displaying Premium Account days v2 2018-01-08 00:17:49 +01:00
slawkens1
85083f5979 * fixed displaying premium account days
* function OTS_Account:getPremDays will now return -1 if there's
freePremium configurable enabled on the server
2018-01-08 00:08:17 +01:00
slawkens1
087988dde3 * fixed getBoolean function when boolean is passed 2018-01-08 00:01:03 +01:00
slawkens1
2dddb853f2 * fixed installation 2018-01-07 23:22:25 +01:00
slawkens1
a92355181f * fixed othire default column value (#26) 2018-01-07 23:21:09 +01:00
slawkens1
2085f7e128 * fixed warning in highscores when vocation doesn't exist 2018-01-07 12:06:00 +01:00
slawkens1
de7366e9a9 * fixed some php notice when there are no players online on TFS 1.x 2018-01-07 12:03:37 +01:00
slawkens1
7ab1c1170f * fixed saving custom vocations in admin panel (#36) 2018-01-07 11:57:26 +01:00
slawkens1
792770e5e2 * fixed some typos
* changes account.management to use buttons defined in template
2018-01-06 23:43:59 +01:00
Sławek
dece42c155 Set theme jekyll-theme-slate 2018-01-06 19:13:11 +01:00
slawkens1
1025fad0e6 * cache $db->hasTable and $db->hasColumn functions
* changed tableExist and fieldExist to $db->hasTable(table) +
$db->hasColumn(table, column)
* new configurable: database_log - can log database queries and show in
website source when logged as super admin
* removed debug_level configurable, enabled by default when logged on
super admin
* added OTS_Account:getCountry()
* added posibility to load OTS_Player partially, and without skills
* (internal) changed depracated $ots->createObject() functions with
their OTS_ equivalents
* (internal) removed unused code
2018-01-06 05:44:33 +01:00
slawkens1
31537687c1 * immediately reload config.lua when there's change in config.server_path detected 2018-01-06 03:07:17 +01:00
slawkens1
9c281511fa * added "Edit" option for admins in characters page 2018-01-06 01:52:59 +01:00
slawkens1
544375378f * show user avatar (outfit) in forum posts
* show user position (group) in forum posts
* replaced forum actions links (move, remove, edit, quote) with images
* redirect directly to the thread on user login (on new reply)
* fixed account login redirect with special chars (like '&' and '?')
2018-01-06 01:46:36 +01:00
slawkens1
c2574235ea * forum: show image in full screen on click
* do not expand the whole site cause of big posted forum images, instead
show a small image and allow full size on click
2018-01-05 23:48:08 +01:00
slawkens1
0533b8c946 * some fixes regarding latest commit 2018-01-05 23:42:30 +01:00
slawkens1
5475bd6b5f * dont add extra <br/> to the TinyMCE news forum posts 2018-01-05 21:44:19 +01:00
slawkens
2e4321872a * fixed othire account creating/installation
* fixed unexpected error logging about email fail
* added max_execution_time to the install finish step
2018-01-05 09:30:27 +01:00
slawkens1
515790b1a0 * fixed table name players -> players_online 2018-01-05 00:36:02 +01:00
slawkens
35c9ffcdca * update TODO 2018-01-04 16:29:18 +01:00
slawkens1
920c8a936f * some small fix regarding highscores vocation box 2018-01-04 00:29:03 +01:00
slawkens1
6863ba4883 * fixed displaying article_text when it was empty saved 2018-01-04 00:09:02 +01:00
slawkens1
2f49413867 * update TODO 2018-01-03 23:50:15 +01:00
slawkens1
854560b2f5 * added news preview function (news, ticker, article)
* update TODO
2018-01-03 23:49:46 +01:00
slawkens1
4a948b8ba2 * save detected country on create account in session
* warning about leaving news page with changes
2018-01-03 22:03:56 +01:00
slawkens1
01c0d021b2 * added player status to tibiacom top 5 highscores box
* fix when there are no changelogs or highscores yet
2018-01-03 21:27:47 +01:00
slawkens1
3e49ef42a2 * fiedx bug on othire with config.account_premium_days
* fixed getPremDays and isPremium functions (newest 11.x engines are
bugged when it comes to PACC, its not fault of MyAAC)
2018-01-03 21:03:05 +01:00
slawkens
efb1775aff Updated TODO 2018-01-03 17:19:18 +01:00
slawkens1
2a1f1c3cd9 * update to 0.8.0-dev
* added some features into TODO file, that will be most probably
available in 0.8 release
2018-01-03 01:09:09 +01:00
slawkens1
3c4ab10b36 Merge branch 'master' of https://github.com/slawkens/myaac 2018-01-03 01:07:31 +01:00
slawkens1
1c94169182 * fixed bug on TFS 1.x when online_afk is enabled 2018-01-03 01:07:26 +01:00
slawkens
53ab7af8dc * small fix regarding getTopPlayers function which was ignoring $limit variable 2018-01-02 10:23:04 +01:00
slawkens1
8d173d369d * added ico to the list of ignored files 2017-12-28 15:51:33 +01:00
slawkens1
4535687b48 * automatically generate plain mail from html 2017-12-26 22:30:52 +01:00
slawkens1
c415cf5ffb * php 7.x APCu cache support 2017-12-26 21:47:53 +01:00
slawkens1
a95c93cd5b * update item_images_url config to 1092
*  for backward support new require constants will be used for semantic
versioning: myaac_, php_, database_
* updated TODO
2017-12-26 20:55:43 +01:00
slawkens1
62443257fc * semantic versioning support for plugins
* add support for defining max myaac version in plugin.json file
* you can now require other plugin to be installed before yours
* added German translation
* fixed faq containing html code
2017-12-26 16:47:52 +01:00
slawkens1
60a8317115 * add some notice to the user that installing step "Import Schema" will take some time 2017-12-25 23:19:32 +01:00
slawkens1
73ed384215 * don't show error indicators on first time load - createaccount page 2017-12-25 23:15:42 +01:00
slawkens1
c4a1f7df5f * check user IP on install to prevent install by random user 2017-12-25 23:03:00 +01:00
slawkens1
8b4eccc064 * updated Twig to the latest version in 1.x series (v1.35.0) 2017-12-25 13:02:46 +01:00
slawkens1
6528a4a60c * ask user for timezone on install
* remember status of the installation
* moved clients list to the new file
* verify if client and timezone is correct on install
2017-12-25 12:40:41 +01:00
slawkens1
4d690992ac * switch to 0.7.5-dev
* fix when config.local.php doesn't exist
* fix when reinstalling aac with samples already installed
* some optimisations to installation script
* forgot to fclose on config.local.php
2017-12-24 13:00:14 +01:00
352 changed files with 7939 additions and 3221 deletions

View File

@@ -1,3 +1,42 @@
[0.7.7 - 08.01.2018]
* important fix for servers with promotion column (caused player.vocation to be resetted when saving player, for example: on change name, accept invite to guild, leave guild)
* immediately reload config.lua when there's change in config.server_path detected
* added new forum option: "Enable HTML" (only for moderators)
* fixed othire default column value (#26)
* fixed saving custom vocations in admin panel (#36)
* fixed warning in highscores when vocation doesn't exist
* fixed characters page - config.characters.frags "Notice: Use of undefined constant"
* fixed getBoolean function when boolean is passed
* fixed empty success message on leave guild
* fixed displaying premium account days
* function OTS_Account:getPremDays will now return -1 if there's freePremium configurable enabled on the server
* fixed tr bgcolor in characters view (Frags) (#38)
* fixed some warning in guild show
* fixed PHP warning about country not existing on online and characters pages
* fixed forum bbcode parsing
* don't add extra <br/> to the TinyMCE news forum posts
* (internal) using $player->getVocationName() where possible instead of older method
[0.7.6 - 05.01.2017]
* fixed othire account creating/installation
* fixed table name players -> players_online
* fixed unexpected error logging about email fail
* added max_execution_time to the install finish step
* some small fix regarding highscores vocation box
[0.7.5 - 04.01.2017]
* fixed bug on othire with config.account_premium_days
* fixed bug on TFS 1.x when online_afk is enabled
* warning about leaving news page with changes
* added player status to tibiacom top 5 highscores box
* save detected country on create account in session
* fixed getPremDays and isPremium functions (newest 11.x engines are bugged when it comes to PACC, its not fault of MyAAC)
* fix when there are no changelogs or highscores yet
* small fix regarding getTopPlayers function which was ignoring $limit variable
* fixed news adding when type != ARTICLE
* fixed template path finding
* fixed displaying article_text when it was empty saved
[0.7.4 - 24.12.2017]
* fixed mysql fatal error on tibiacom template - top 5 box
* fixed displaying of level percent bar on tibian signature

35
TODO
View File

@@ -2,28 +2,42 @@
0.*
* support duplicated vocation names with different ids
* plugins: option to define custom requirements check in json file, to check if system meets the requirement
* add support for defining max myaac version in plugin.json file
* cache Menus in templates
* don't show error indicators on first time load - createaccount page
* update Twig to the latest version from 1.x branch
* semantic versioning support for plugins (github.com/composer/semver)
* add some notice to the user that installing step "Import Schema" will take some time
* check user IP on installing to prevent install by random user
* sandbox for plugins, don't install when requirements are not passed
* add changelog management interface
* plugins require:
* php extension
* database table or column
* kathrine tickets - show/hide
* highscores - by balance
* admin panel Menus:
* open in external window (_blank option)
* color of the link
* should the link blink?
* cache:
* hooks
* Menus in templates
* move highscores to twig
* migrations: option to downgrade the database
* hooks: login + logout
* create account: create character
1.0:
* i18n support (issue #1 on github)
* New Admin Panel layout and interface
* add changelog management interface
* most preferably: https://adminlte.io/
* move all pages administration to this panel (like faq, forum, newses)
* remove tibiacom template, and include it as a plugin
2.0
* remove gesior backward support
* remove compat functions
* remove $template['link_*']
* folder restructure:
* var/ (for logs, cache and data), config/, bin, public/ (for index and images and other public content), system/ (for php files and classess)
* rename templates to layouts as templates is meant to be used for twig templates
* change gifts_system to shop_system configurable
* move most used options in system/templates dir to separate directories (more transparent)
* move database fields to separate tables without modifing the OTServ schema (myaac_accounts, myaac_players)
At any time between (version not specified):
* better news archive with search function (like on tibia.com)
@@ -31,7 +45,8 @@ At any time between (version not specified):
* update account.management page to be more realistic (like on tibia.com)
* update guilds page to be more realistic (like on tibia.com)
* possibility to add extra cache engines with plugins
* preferably configurable (enable/disable) forum TinyMCE editor
* new cache engine - plain php, is good with pure php 7.0+ and opcache
* preferably configurable (enable/disable) forum TinyMCE editor
* OTAdmin support in Admin Panel
* database towns table support for TFS 1.3
* two factor authentication for TFS 1.x

1
_config.yml Normal file
View File

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

View File

@@ -26,8 +26,8 @@
session_start();
define('MYAAC', true);
define('MYAAC_VERSION', '0.7.4');
define('DATABASE_VERSION', 20);
define('MYAAC_VERSION', '0.8.0-dev');
define('DATABASE_VERSION', 21);
define('TABLE_PREFIX', 'myaac_');
define('START_TIME', microtime(true));
define('MYAAC_OS', (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') ? 'WINDOWS' : (strtoupper(PHP_OS) == 'DARWIN' ? 'MAC' : 'LINUX'));
@@ -46,6 +46,7 @@ define('FLAG_CONTENT_GALLERY', 512);
define('FLAG_CONTENT_VIDEOS', 1024);
define('FLAG_CONTENT_FAQ', 2048);
define('FLAG_CONTENT_MENUS', 4096);
define('FLAG_CONTENT_PLAYERS', 8192);
// news
define('NEWS', 1);

View File

@@ -46,8 +46,6 @@ $config = array(
// footer
'footer' => ''/*'<br/>Your Server &copy; 2016. All rights reserved.'*/,
'debug_level' => 0, // 0 - disabled, 1 - show load time, 2 - show db query counter, 3 - both, 4 - memory usage, 5 - load time & memory usage, 6 - queries & memory usage, 7 - all
'language' => 'en', // default language (currently only 'en' available)
'language_allow_change' => false,
@@ -56,7 +54,7 @@ $config = array(
'views_counter' => true,
// cache system. by default file cache is used
'cache_engine' => 'auto', // apc, eaccelerator, xcache, file, auto, or blank to disable.
'cache_engine' => 'auto', // apc, apcu, eaccelerator, xcache, file, auto, or blank to disable.
'cache_prefix' => 'myaac_', // have to be unique if running more MyAAC instances on the same server (except file system cache)
// database details (leave blank for auto detect from config.lua)
@@ -65,6 +63,7 @@ $config = array(
'database_user' => '',
'database_password' => '',
'database_name' => '',
'database_log' => false, // should database queries be logged and displayed in the page source? They will be included at the end of the .html source of the page
// multiworld system (only TFS 0.3)
'multiworld' => false, // use multiworld system?
@@ -75,7 +74,7 @@ $config = array(
// images
'outfit_images_url' => 'http://outfit-images.ots.me/outfit.php', // set to animoutfit.php for animated outfit
'item_images_url' => 'http://item-images.ots.me/960/', // set to images/items if you host your own items in images folder
'item_images_url' => 'http://item-images.ots.me/1092/', // set to images/items if you host your own items in images folder
// account
'account_management' => true, // disable if you're using other method to manage users (fe. tfs account manager)
@@ -98,7 +97,7 @@ $config = array(
'mail_address' => 'no-reply@your-server.org', // server e-mail address (from:)
'mail_admin' => 'your-address@your-server.org', // admin email address, where mails from contact form will be sent
'mail_signature' => array( // signature that will be included at the end of every message sent using _mail function
'plain' => ''/*'--\nMy Server,\nhttp://www.myserver.com'*/,
'plain' => ""/*"--\nMy Server,\nhttp://www.myserver.com"*/,
'html' => ''/*'<br/>My Server,\n<a href="http://www.myserver.com">myserver.com</a>'*/
),
'smtp_enabled' => false, // send by smtp or mail function (set false if use mail function)

Binary file not shown.

After

Width:  |  Height:  |  Size: 530 B

BIN
images/loading_spinner.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

View File

@@ -51,12 +51,14 @@ if(preg_match("/^[A-Za-z0-9-_%\'+]+\.png$/i", $uri)) {
include(TOOLS . 'signature/index.php');
exit();
}
else if(preg_match("/^(.*)\.(gif|jpg|png|jpeg|tiff|bmp|css|js|less|map|html|php|zip|rar|gz)$/i", $_SERVER['REQUEST_URI'])) {
else if(preg_match("/^(.*)\.(gif|jpg|png|jpeg|tiff|bmp|css|js|less|map|html|php|zip|rar|gz|ttf|woff|ico)$/i", $_SERVER['REQUEST_URI'])) {
header("HTTP/1.0 404 Not Found");
exit;
}
require_once(BASE . 'config.local.php');
if(file_exists(BASE . 'config.local.php'))
require_once(BASE . 'config.local.php');
if(file_exists(BASE . 'install') && (!isset($config['installed']) || !$config['installed']))
{
header('Location: ' . BASE_URL . 'install/');
@@ -176,21 +178,17 @@ if(fetchDatabaseConfig('database_version', $tmp)) { // we got version
$tmp = (int)$tmp;
if($tmp < DATABASE_VERSION) { // import if older
for($i = $tmp + 1; $i <= DATABASE_VERSION; $i++) {
$file = SYSTEM . 'migrations/' . $i . '.php';
if(file_exists($file)) {
require($file);
require(SYSTEM . 'migrations/' . $i . '.php');
updateDatabaseConfig('database_version', $i);
}
}
updateDatabaseConfig('database_version', DATABASE_VERSION);
}
}
else { // register first version
registerDatabaseConfig('database_version', 0);
for($i = 1; $i <= DATABASE_VERSION; $i++) {
require(SYSTEM . 'migrations/' . $i . '.php');
updateDatabaseConfig('database_version', $i);
}
registerDatabaseConfig('database_version', DATABASE_VERSION);
}
// event system
@@ -422,14 +420,17 @@ else
}
echo '<!-- MyAAC ' . MYAAC_VERSION . ' :: http://www.my-aac.org/ -->' . "\n";
if(($config['debug_level'] & 1) == 1)
echo '<!-- Generated in :: ' . round(microtime(true) - START_TIME, 4) . ' -->';
if(superAdmin()) {
echo '<!-- Generated in: ' . round(microtime(true) - START_TIME, 4) . 'ms -->';
echo PHP_EOL . '<!-- Queries done: ' . $db->queries() . ' -->';
if(function_exists('memory_get_peak_usage')) {
echo PHP_EOL . '<!-- Peak memory usage: ' . convert_bytes(memory_get_peak_usage(true)) . ' -->';
}
if(($config['debug_level'] & 2) == 2)
echo "\n" . '<!-- Queries done :: ' . $db->queries() . ' -->';
if(($config['debug_level'] & 4) == 4 && function_exists('memory_get_peak_usage'))
echo "\n" . '<!-- Peak memory usage: ' . convert_bytes(memory_get_peak_usage(true)) . ' -->';
if($config['database_log']) {
echo PHP_EOL . '<!-- Database Queries Done by MyAAC:' . PHP_EOL . $db->getLog() . '-->';
}
}
$hooks->trigger(HOOK_FINISH);
?>

View File

@@ -6,17 +6,17 @@ if(!isset($_SESSION['var_server_path'])) {
$error = true;
}
$config['server_path'] = $_SESSION['var_server_path'];
// take care of trailing slash at the end
if($config['server_path'][strlen($config['server_path']) - 1] != '/')
$config['server_path'] = $_SESSION['var_server_path'];
// take care of trailing slash at the end
if($config['server_path'][strlen($config['server_path']) - 1] != '/')
$config['server_path'] .= '/';
if((!isset($error) || !$error) && !file_exists($config['server_path'] . 'config.lua')) {
error($locale['step_database_error_config']);
$error = true;
}
}
if(!isset($error) || !$error) {
if(!isset($error) || !$error) {
$config['lua'] = load_config_lua($config['server_path'] . 'config.lua');
if(isset($config['lua']['sqlType'])) // tfs 0.3
$config['database_type'] = $config['lua']['sqlType'];
@@ -37,5 +37,5 @@ if((!isset($error) || !$error) && !file_exists($config['server_path'] . 'config.
error($locale['step_database_error_only_mysql']);
$error = true;
}
}
}
?>

View File

@@ -5,8 +5,8 @@ require(SYSTEM . 'libs/pot/OTS.php');
$ots = POT::getInstance();
require(SYSTEM . 'database.php');
if(tableExist('accounts'))
define('USE_ACCOUNT_NAME', fieldExist('name', 'accounts'));
if($db->hasTable('accounts'))
define('USE_ACCOUNT_NAME', $db->hasColumn('accounts', 'name'));
else
define('USE_ACCOUNT_NAME', false);
?>

View File

@@ -109,6 +109,7 @@ CREATE TABLE `myaac_forum`
`post_text` text NOT NULL,
`post_topic` varchar(255) NOT NULL DEFAULT '',
`post_smile` tinyint(1) NOT NULL default '0',
`post_html` tinyint(1) NOT NULL default '0',
`post_date` int(20) NOT NULL default '0',
`last_edit_aid` int(20) NOT NULL default '0',
`edit_date` int(20) NOT NULL default '0',

View File

@@ -5,7 +5,10 @@ require('../common.php');
require(SYSTEM . 'functions.php');
require(BASE . 'install/includes/functions.php');
require(BASE . 'install/includes/locale.php');
require(BASE . 'config.local.php');
require(SYSTEM . 'clients.conf.php');
if(file_exists(BASE . 'config.local.php'))
require(BASE . 'config.local.php');
// twig
require_once LIBS . 'Twig/Autoloader.php';
@@ -17,45 +20,100 @@ $twig = new Twig_Environment($twig_loader, array(
'auto_reload' => true
));
if(isset($_POST['vars']))
{
foreach($_POST['vars'] as $key => $value)
$_SESSION['var_' . $key] = $value;
}
// step
// load installation status
$step = isset($_POST['step']) ? $_POST['step'] : 'welcome';
$install_status = array();
if(file_exists(CACHE . 'install.txt')) {
$install_status = unserialize(file_get_contents(CACHE . 'install.txt'));
if(!isset($_POST['step'])) {
$step = isset($install_status['step']) ? $install_status['step'] : '';
}
}
if(isset($_POST['vars']))
{
foreach($_POST['vars'] as $key => $value) {
$_SESSION['var_' . $key] = $value;
$install_status[$key] = $value;
}
}
else {
foreach($install_status as $key => $value) {
$_SESSION['var_' . $key] = $value;
}
}
if($step == 'finish' && (!isset($config['installed']) || !$config['installed'])) {
$step = 'welcome';
}
// step verify
$steps = array(1 => 'welcome', 2 => 'license', 3 => 'requirements', 4 => 'config', 5 => 'database', 6 => 'admin', 7 => 'finish');
if(!in_array($step, $steps)) // check if step is valid
die('ERROR: Unknown step.');
$install_status['step'] = $step;
$errors = array();
if($step == 'database')
{
foreach($_POST['vars'] as $key => $value)
{
if($key != 'usage' && empty($value))
{
if($step == 'database') {
foreach($_SESSION as $key => $value) {
if(strpos($key, 'var_') === false || strpos($key, 'account') !== false || strpos($key, 'password') !== false) {
continue;
}
$key = str_replace('var_', '', $key);
if($key != 'usage' && empty($value)) {
$errors[] = $locale['please_fill_all'];
break;
}
else if($key == 'mail_admin' && !Validator::email($value))
{
else if($key == 'server_path') {
$config['server_path'] = $value;
// take care of trailing slash at the end
if($config['server_path'][strlen($config['server_path']) - 1] != '/') {
$config['server_path'] .= '/';
}
if(!file_exists($config['server_path'] . 'config.lua')) {
$errors[] = $locale['step_database_error_config'];
break;
}
}
else if($key == 'mail_admin' && !Validator::email($value)) {
$errors[] = $locale['step_config_mail_admin_error'];
break;
}
else if($key == 'mail_address' && !Validator::email($value))
{
else if($key == 'mail_address' && !Validator::email($value)) {
$errors[] = $locale['step_config_mail_address_error'];
break;
}
else if($key == 'timezone' && !in_array($value, DateTimeZone::listIdentifiers())) {
$errors[] = $locale['step_config_timezone_error'];
break;
}
else if($key == 'client' && !in_array($value, $config['clients'])) {
$errors[] = $locale['step_config_client_error'];
break;
}
}
if(!empty($errors)) {
$step = 'config';
}
}
else if($step == 'admin') {
$config_failed = true;
if(file_exists(BASE . 'config.local.php') && isset($config['installed']) && $config['installed'] && isset($_SESSION['saved'])) {
$config_failed = false;
}
if($config_failed) {
$step = 'database';
}
}
else if($step == 'finish') {
// password
$password = $_SESSION['var_password'];
@@ -89,16 +147,43 @@ else if($step == 'finish') {
}
}
if(empty($errors)) {
file_put_contents(CACHE . 'install.txt', serialize($install_status));
}
$error = false;
clearstatcache();
if(is_writable(CACHE) && (MYAAC_OS != 'WINDOWS' || win_is_writable(CACHE))) {
if(!file_exists(BASE . 'install/ip.txt')) {
$content = warning('AAC installation is disabled. To enable it make file <b>ip.txt</b> in install/ directory and put there your IP.<br/>
Your IP is:<br /><b>' . $_SERVER['REMOTE_ADDR'] . '</b>', true);
}
else {
$file_content = trim(file_get_contents(BASE . 'install/ip.txt'));
$allow = false;
$listIP = preg_split('/\s+/', $file_content);
foreach($listIP as $ip) {
if($_SERVER['REMOTE_ADDR'] == $ip) {
$allow = true;
}
}
if(!$allow)
{
$content = warning('In file <b>install/ip.txt</b> must be your IP!<br/>
In file is:<br /><b>' . nl2br($file_content) . '</b><br/>
Your IP is:<br /><b>' . $_SERVER['REMOTE_ADDR'] . '</b>', true);
}
else {
ob_start();
$step_id = array_search($step, $steps);
require('steps/' . $step_id . '-' . $step . '.php');
$content = ob_get_contents();
ob_end_clean();
}
}
}
else {
$content = error(file_get_contents(BASE . 'install/includes/twig_error.html'), true);

3
install/ip.txt Normal file
View File

@@ -0,0 +1,3 @@
127.0.0.1
127.0.0.2
::1

View File

@@ -23,7 +23,7 @@ $failed = false;
// start validating
version_check($locale['step_requirements_php_version'], (PHP_VERSION_ID >= 50300), PHP_VERSION);
foreach(array('config.local.php', 'images/guilds', 'images/houses', 'images/gallery') as $value)
foreach(array('images/guilds', 'images/houses', 'images/gallery') as $value)
{
$perms = (int) substr(decoct(fileperms(BASE . $value)), 2);
version_check($locale['step_requirements_write_perms'] . ': ' . $value, $perms >= 660);

View File

@@ -1,74 +1,8 @@
<?php
defined('MYAAC') or die('Direct access not allowed!');
$clients_list = array(
710,
740,
750,
760,
770,
772,
780,
7920,
800,
810,
821,
822,
831,
840,
841,
842,
850,
852,
853,
854,
855,
857,
860,
870,
900,
910,
920,
930,
940,
942,
944,
946,
950,
952,
953,
954,
960,
970,
980,
1000,
1010,
1021,
1031,
1034,
1041,
1050,
1053,
1054,
1058,
1075,
1077,
1079,
1080,
1090,
1093,
1094,
1095,
1096,
1097,
1098,
1100,
);
$clients = array();
foreach($clients_list as $client) {
foreach($config['clients'] as $client) {
$client_version = (string)($client / 100);
if(strpos($client_version, '.') == false)
$client_version .= '.0';
@@ -78,6 +12,7 @@ foreach($clients_list as $client) {
echo $twig->render('install.config.html.twig', array(
'clients' => $clients,
'timezones' => DateTimeZone::listIdentifiers(),
'locale' => $locale,
'session' => $_SESSION,
'errors' => isset($errors) ? $errors : null,

View File

@@ -13,6 +13,12 @@ if(!isset($_SESSION['var_server_path'])) {
if(!$error) {
$content = "<?php";
$content .= PHP_EOL;
$content .= '// place for your configuration directives, so you can later easily update myaac';
$content .= PHP_EOL;
$content .= '$config[\'installed\'] = true;';
$content .= PHP_EOL;
$content .= '$config[\'mail_enabled\'] = true;';
$content .= PHP_EOL;
foreach($_SESSION as $key => $value)
{
if(strpos($key, 'var_') !== false)
@@ -21,14 +27,14 @@ if(!$error) {
{
$value = str_replace("\\", "/", $value);
if($value[strlen($value) - 1] != '/')
$value .= "/";
$value .= '/';
}
if($key == 'var_usage') {
$content .= '$config[\'anonymous_usage_statistics\'] = ' . ((int)$value == 1 ? 'true' : 'false') . ';';
$content .= PHP_EOL;
}
else if($key != 'var_account' && $key != 'var_account_id' && $key != 'var_password') {
else if($key != 'var_account' && $key != 'var_account_id' && $key != 'var_password' && $key != 'var_step') {
$content .= '$config[\'' . str_replace('var_', '', $key) . '\'] = \'' . $value . '\';';
$content .= PHP_EOL;
}
@@ -41,192 +47,12 @@ if(!$error) {
success($locale['step_database_importing']);
require(BASE . 'install/includes/database.php');
if(!tableExist('accounts')) {
$locale['step_database_error_table'] = str_replace('$TABLE$', 'accounts', $locale['step_database_error_table']);
error($locale['step_database_error_table']);
$error = true;
}
else if(!tableExist('players')) {
$locale['step_database_error_table'] = str_replace('$TABLE$', 'players', $locale['step_database_error_table']);
error($locale['step_database_error_table']);
$error = true;
}
else if(!tableExist('guilds')) {
$locale['step_database_error_table'] = str_replace('$TABLE$', 'guilds', $locale['step_database_error_table']);
error($locale['step_database_error_table']);
$error = true;
}
if(tableExist(TABLE_PREFIX . 'account_actions')) {
$locale['step_database_error_table_exist'] = str_replace('$TABLE$', TABLE_PREFIX . 'account_actions', $locale['step_database_error_table_exist']);
warning($locale['step_database_error_table_exist']);
}
else if(!$error) {
// import schema
try {
$db->query(file_get_contents(BASE . 'install/includes/schema.sql'));
}
catch(PDOException $error_) {
error($locale['step_database_error_schema'] . ' ' . $error_);
$error = true;
}
echo $twig->render('install.installer.html.twig', array(
'url' => 'tools/5-database.php',
'message' => $locale['loading_spinner']
));
if(!$error) {
registerDatabaseConfig('database_version', DATABASE_VERSION);
$locale['step_database_success_schema'] = str_replace('$PREFIX$', TABLE_PREFIX, $locale['step_database_success_schema']);
success($locale['step_database_success_schema']);
}
}
if(!$error) {
if(fieldExist('key', 'accounts')) {
if(query("ALTER TABLE `accounts` MODIFY `key` VARCHAR(64) NOT NULL DEFAULT '';"))
success($locale['step_database_modifying_field'] . ' accounts.key...');
}
else {
if(query("ALTER TABLE `accounts` ADD `key` VARCHAR(64) NOT NULL DEFAULT '' AFTER `email`;"))
success($locale['step_database_adding_field'] . ' accounts.key...');
}
if(!fieldExist('blocked', 'accounts')) {
if(query("ALTER TABLE `accounts` ADD `blocked` TINYINT(1) NOT NULL DEFAULT FALSE COMMENT 'internal usage' AFTER `key`;"))
success($locale['step_database_adding_field'] . ' accounts.blocked...');
}
if(!fieldExist('created', 'accounts')) {
if(query("ALTER TABLE `accounts` ADD `created` INT(11) NOT NULL DEFAULT 0 AFTER `" . (fieldExist('group_id', 'accounts') ? 'group_id' : 'blocked') . "`;"))
success($locale['step_database_adding_field'] . ' accounts.created...');
}
if(!fieldExist('rlname', 'accounts')) {
if(query("ALTER TABLE `accounts` ADD `rlname` VARCHAR(255) NOT NULL DEFAULT '' AFTER `created`;"))
success($locale['step_database_adding_field'] . ' accounts.rlname...');
}
if(!fieldExist('location', 'accounts')) {
if(query("ALTER TABLE `accounts` ADD `location` VARCHAR(255) NOT NULL DEFAULT '' AFTER `rlname`;"))
success($locale['step_database_adding_field'] . ' accounts.location...');
}
if(!fieldExist('country', 'accounts')) {
if(query("ALTER TABLE `accounts` ADD `country` VARCHAR(3) NOT NULL DEFAULT '' AFTER `location`;"))
success($locale['step_database_adding_field'] . ' accounts.country...');
}
if(fieldExist('page_lastday', 'accounts')) {
if(query("ALTER TABLE `accounts` CHANGE `page_lastday` `web_lastlogin` INT(11) NOT NULL DEFAULT 0;")) {
$tmp = str_replace('$FIELD$', 'accounts.page_lastday', $locale['step_database_changing_field']);
$tmp = str_replace('$FIELD_NEW$', 'accounts.web_lastlogin', $tmp);
success($tmp);
}
}
else if(!fieldExist('web_lastlogin', 'accounts')) {
if(query("ALTER TABLE `accounts` ADD `web_lastlogin` INT(11) NOT NULL DEFAULT 0 AFTER `country`;"))
success($locale['step_database_adding_field'] . ' accounts.web_lastlogin...');
}
if(!fieldExist('web_flags', 'accounts')) {
if(query("ALTER TABLE `accounts` ADD `web_flags` INT(11) NOT NULL DEFAULT 0 AFTER `web_lastlogin`;"))
success($locale['step_database_adding_field'] . ' accounts.web_flags...');
}
if(!fieldExist('email_hash', 'accounts')) {
if(query("ALTER TABLE `accounts` ADD `email_hash` VARCHAR(32) NOT NULL DEFAULT '' AFTER `web_flags`;"))
success($locale['step_database_adding_field'] . ' accounts.email_hash...');
}
if(!fieldExist('email_verified', 'accounts')) {
if(query("ALTER TABLE `accounts` ADD `email_verified` TINYINT(1) NOT NULL DEFAULT 0 AFTER `email_hash`;"))
success($locale['step_database_adding_field'] . ' accounts.email_verified...');
}
if(!fieldExist('email_new', 'accounts')) {
if(query("ALTER TABLE `accounts` ADD `email_new` VARCHAR(255) NOT NULL DEFAULT '' AFTER `email_hash`;"))
success($locale['step_database_adding_field'] . ' accounts.email_new...');
}
if(!fieldExist('email_new_time', 'accounts')) {
if(query("ALTER TABLE `accounts` ADD `email_new_time` INT(11) NOT NULL DEFAULT 0 AFTER `email_new`;"))
success($locale['step_database_adding_field'] . ' accounts.email_new_time...');
}
if(!fieldExist('email_code', 'accounts')) {
if(query("ALTER TABLE `accounts` ADD `email_code` VARCHAR(255) NOT NULL DEFAULT '' AFTER `email_new_time`;"))
success($locale['step_database_adding_field'] . ' accounts.email_code...');
}
if(fieldExist('next_email', 'accounts')) {
if(!fieldExist('email_next', 'accounts')) {
if(query("ALTER TABLE `accounts` CHANGE `next_email` `email_next` INT(11) NOT NULL DEFAULT 0;")) {
$tmp = str_replace('$FIELD$', 'accounts.next_email', $locale['step_database_changing_field']);
$tmp = str_replace('$FIELD_NEW$', 'accounts.email_next', $tmp);
success($tmp);
}
}
}
else if(!fieldExist('email_next', 'accounts')) {
if(query("ALTER TABLE `accounts` ADD `email_next` INT(11) NOT NULL DEFAULT 0 AFTER `email_code`;"))
success($locale['step_database_adding_field'] . ' accounts.email_next...');
}
if(!fieldExist('premium_points', 'accounts')) {
if(query("ALTER TABLE `accounts` ADD `premium_points` INT(11) NOT NULL DEFAULT 0 AFTER `email_next`;"))
success($locale['step_database_adding_field'] . ' accounts.premium_points...');
}
if(!fieldExist('description', 'guilds')) {
if(query("ALTER TABLE `guilds` ADD `description` TEXT NOT NULL;"))
success($locale['step_database_adding_field'] . ' guilds.description...');
}
if(fieldExist('logo_gfx_name', 'guilds')) {
if(query("ALTER TABLE `guilds` CHANGE `logo_gfx_name` `logo_name` VARCHAR( 255 ) NOT NULL DEFAULT 'default.gif';")) {
$tmp = str_replace('$FIELD$', 'guilds.logo_gfx_name', $locale['step_database_changing_field']);
$tmp = str_replace('$FIELD_NEW$', 'guilds.logo_name', $tmp);
success($tmp);
}
}
else if(!fieldExist('logo_name', 'guilds')) {
if(query("ALTER TABLE `guilds` ADD `logo_name` VARCHAR( 255 ) NOT NULL DEFAULT 'default.gif';"))
success($locale['step_database_adding_field'] . ' guilds.logo_name...');
}
if(!fieldExist('created', 'players')) {
if(query("ALTER TABLE `players` ADD `created` INT(11) NOT NULL DEFAULT 0;"))
success($locale['step_database_adding_field'] . ' players.created...');
}
if(!fieldExist('deleted', 'players') && !fieldExist('deletion', 'players')) {
if(query("ALTER TABLE `players` ADD `deleted` TINYINT(1) NOT NULL DEFAULT 0;"))
success($locale['step_database_adding_field'] . ' players.comment...');
}
if(fieldExist('hide_char', 'players')) {
if(!fieldExist('hidden', 'players')) {
if(query("ALTER TABLE `players` CHANGE `hide_char` `hidden` TINYINT(1) NOT NULL DEFAULT 0;")) {
$tmp = str_replace('$FIELD$', 'players.hide_char', $locale['step_database_changing_field']);
$tmp = str_replace('$FIELD_NEW$', 'players.hidden', $tmp);
success($tmp);
}
}
}
else if(!fieldExist('hidden', 'players')) {
if(query("ALTER TABLE `players` ADD `hidden` TINYINT(1) NOT NULL DEFAULT 0;"))
success($locale['step_database_adding_field'] . ' players.hidden...');
}
if(!fieldExist('comment', 'players')) {
if(query("ALTER TABLE `players` ADD `comment` TEXT NOT NULL;"))
success($locale['step_database_adding_field'] . ' players.comment...');
}
}
if(!$error && (!isset($_SESSION['saved']))) {
$content .= '$config[\'installed\'] = true;';
$content .= PHP_EOL;
$content .= '$config[\'mail_enabled\'] = true;';
$content .= PHP_EOL;
if(!Validator::email($_SESSION['var_mail_admin'])) {
error($locale['step_config_mail_admin_error']);
$error = true;
@@ -243,16 +69,21 @@ if(!$error) {
$content .= '$config[\'session_prefix\'] = \'myaac_' . generateRandomString(8, true, false, true, false) . '_\';';
$content .= PHP_EOL;
$content .= '$config[\'cache_prefix\'] = \'myaac_' . generateRandomString(8, true, false, true, false) . '_\';';
$content .= PHP_EOL;
$file = fopen(BASE . 'config.local.php', 'a+');
if($file) {
$saved = true;
if(!$error) {
$saved = file_put_contents(BASE . 'config.local.php', $content);
}
if($saved) {
if(!$error) {
fwrite($file, $content);
$_SESSION['saved'] = true;
}
}
else {
$_SESSION['config_content'] = $content;
unset($_SESSION['saved']);
$locale['step_database_error_file'] = str_replace('$FILE$', '<b>' . BASE . 'config.local.php</b>', $locale['step_database_error_file']);
warning($locale['step_database_error_file'] . '<br/>
<textarea cols="70" rows="10">' . $content . '</textarea>');

View File

@@ -1,6 +1,7 @@
<?php
defined('MYAAC') or die('Direct access not allowed!');
ini_set('max_execution_time', 300);
if(isset($config['installed']) && $config['installed'] && !isset($_SESSION['saved'])) {
warning($locale['already_installed']);
}
@@ -14,7 +15,7 @@ else {
$password = $_SESSION['var_password'];
$config_salt_enabled = fieldExist('salt', 'accounts');
$config_salt_enabled = $db->hasColumn('accounts', 'salt');
if($config_salt_enabled)
{
$salt = generateRandomString(10, false, true, true);
@@ -76,9 +77,9 @@ else {
$account_used->setCustomField('web_flags', FLAG_ADMIN + FLAG_SUPER_ADMIN);
$account_used->setCustomField('country', 'us');
if(fieldExist('group_id', 'accounts'))
if($db->hasColumn('accounts', 'group_id'))
$account_used->setCustomField('group_id', $groups->getHighestId());
if(fieldExist('type', 'accounts'))
if($db->hasColumn('accounts', 'type'))
$account_used->setCustomField('type', 5);
if(!$player_db->isLoaded())
@@ -114,103 +115,10 @@ else {
}
}
$deleted = 'deleted';
if(fieldExist('deletion', 'players'))
$deleted = 'deletion';
$insert_into_players = "INSERT INTO `players` (`id`, `name`, `group_id`, `account_id`, `level`, `vocation`, `health`, `healthmax`, `experience`, `lookbody`, `lookfeet`, `lookhead`, `looklegs`, `looktype`, `maglevel`, `mana`, `manamax`, `manaspent`, `soul`, `town_id`, `posx`, `posy`, `posz`, `conditions`, `cap`, `sex`, `lastlogin`, `lastip`, `save`, `lastlogout`, `balance`, `$deleted`, `created`, `hidden`, `comment`) VALUES ";
$success = true;
$highscores_ignored_ids = array();
$query = $db->query('SELECT `id` FROM `players` WHERE `name` = ' . $db->quote('Rook Sample'));
if($query->rowCount() == 0) {
if(!query($insert_into_players . "(null, 'Rook Sample', 1, " . getSession('account') . ", 1, 0, 150, 150, 4200, 118, 114, 38, 57, 130, 0, 0, 0, 0, 100, 1, 1000, 1000, 7, '', 400, 1, 1255179613, 2453925456, 1, 1255179614, 0, 0, UNIX_TIMESTAMP(), 1, '');"))
$success = false;
else {
$highscores_ignored_ids[] = $db->lastInsertId();
}
}
$query = $db->query('SELECT `id` FROM `players` WHERE `name` = ' . $db->quote('Sorcerer Sample'));
if($query->rowCount() == 0) {
if(!query($insert_into_players . "(null, 'Sorcerer Sample', 1, " . getSession('account') . ", 8, 1, 185, 185, 4200, 118, 114, 38, 57, 130, 0, 35, 35, 0, 100, 1, 1000, 1000, 7, '', 470, 1, 1255179571, 2453925456, 1, 1255179612, 0, 0, UNIX_TIMESTAMP(), 1, '');"))
$success = false;
else {
$highscores_ignored_ids[] = $db->lastInsertId();
}
}
$query = $db->query('SELECT `id` FROM `players` WHERE `name` = ' . $db->quote('Druid Sample'));
if($query->rowCount() == 0) {
if(!query($insert_into_players . "(null, 'Druid Sample', 1, " . getSession('account') . ", 8, 2, 185, 185, 4200, 118, 114, 38, 57, 130, 0, 35, 35, 0, 100, 1, 1000, 1000, 7, '', 470, 1, 1255179655, 2453925456, 1, 1255179658, 0, 0, UNIX_TIMESTAMP(), 1, '');"))
$success = false;
else {
$highscores_ignored_ids[] = $db->lastInsertId();
}
}
$query = $db->query('SELECT `id` FROM `players` WHERE `name` = ' . $db->quote('Paladin Sample'));
if($query->rowCount() == 0) {
if(!query($insert_into_players . "(null, 'Paladin Sample', 1, " . getSession('account') . ", 8, 3, 185, 185, 4200, 118, 114, 38, 57, 129, 0, 35, 35, 0, 100, 1, 1000, 1000, 7, '', 470, 1, 1255179854, 2453925456, 1, 1255179858, 0, 0, UNIX_TIMESTAMP(), 1, '');"))
$success = false;
else {
$highscores_ignored_ids[] = $db->lastInsertId();
}
}
$query = $db->query('SELECT `id` FROM `players` WHERE `name` = ' . $db->quote('Knight Sample'));
if($query->rowCount() == 0) {
if(!query($insert_into_players . "(null, 'Knight Sample', 1, " . getSession('account') . ", 8, 4, 185, 185, 4200, 118, 114, 38, 57, 131, 0, 35, 35, 0, 100, 1, 1000, 1000, 7, '', 470, 1, 1255179620, 2453925456, 1, 1255179654, 0, 0, UNIX_TIMESTAMP(), 1, '');"))
$success = false;
else {
$highscores_ignored_ids[] = $db->lastInsertId();
}
}
if($success) {
success($locale['step_database_imported_players']);
}
require(LIBS . 'creatures.php');
if(Creatures::loadFromXML()) {
success($locale['step_database_loaded_monsters']);
if(Creatures::getMonstersList()->hasErrors()) {
$locale['step_database_error_monsters'] = str_replace('$LOG$', 'system/logs/error.log', $locale['step_database_error_monsters']);
warning($locale['step_database_error_monsters']);
}
}
else {
error(Creatures::getLastError());
}
require(LIBS . 'spells.php');
if(Spells::loadFromXML()) {
success($locale['step_database_loaded_spells']);
}
else {
error(Spells::getLastError());
}
$content = PHP_EOL;
$content .= '$config[\'highscores_ids_hidden\'] = array(' . implode(', ', $highscores_ignored_ids) . ');';
$content .= PHP_EOL;
$file = fopen(BASE . 'config.local.php', 'a+');
if($file) {
fwrite($file, $content);
}
else {
$locale['step_database_error_file'] = str_replace('$FILE$', '<b>' . BASE . 'config.local.php</b>', $locale['step_database_error_file']);
warning($locale['step_database_error_file'] . '<br/>
<textarea cols="70" rows="10">' . $content . '</textarea>');
}
$locale['step_finish_desc'] = str_replace('$ADMIN_PANEL$', generateLink(ADMIN_URL, $locale['step_finish_admin_panel'], true), $locale['step_finish_desc']);
$locale['step_finish_desc'] = str_replace('$HOMEPAGE$', generateLink(BASE_URL, $locale['step_finish_homepage'], true), $locale['step_finish_desc']);
$locale['step_finish_desc'] = str_replace('$LINK$', generateLink('http://my-aac.org', 'http://my-aac.org', true), $locale['step_finish_desc']);
success($locale['step_finish_desc']);
echo $twig->render('install.installer.html.twig', array(
'url' => 'tools/7-finish.php',
'message' => $locale['importing_spinner']
));
if(!isset($_SESSION['installed'])) {
file_get_contents('http://my-aac.org/report_install.php?v=' . MYAAC_VERSION . '&b=' . urlencode(BASE_URL));
@@ -222,6 +130,9 @@ else {
unset($_SESSION[$key]);
}
unset($_SESSION['saved']);
if(file_exists(CACHE . 'install.txt')) {
unlink(CACHE . 'install.txt');
}
}
}
?>

View File

@@ -3,6 +3,8 @@
<meta http-equiv="Content-Type" content="text/html; charset=<?php echo $locale['encoding']; ?>" />
<title>MyAAC - <?php echo $locale['installation']; ?></title>
<link rel="stylesheet" type="text/css" href="template/style.css" />
<script type="text/javascript" src="<?php echo BASE_URL; ?>tools/jquery.js"></script>
</head>
<body>
<div id="wrapper">

View File

@@ -0,0 +1,208 @@
<?php
require_once('../../common.php');
require(SYSTEM . 'functions.php');
require(BASE . 'install/includes/functions.php');
require(BASE . 'install/includes/locale.php');
$error = false;
require(BASE . 'install/includes/config.php');
ini_set('max_execution_time', 300);
ob_implicit_flush();
ob_end_flush();
if(!$error) {
require(BASE . 'install/includes/database.php');
}
if(!$db->hasTable('accounts')) {
$locale['step_database_error_table'] = str_replace('$TABLE$', 'accounts', $locale['step_database_error_table']);
error($locale['step_database_error_table']);
$error = true;
}
else if(!$db->hasTable('players')) {
$locale['step_database_error_table'] = str_replace('$TABLE$', 'players', $locale['step_database_error_table']);
error($locale['step_database_error_table']);
$error = true;
}
else if(!$db->hasTable('guilds')) {
$locale['step_database_error_table'] = str_replace('$TABLE$', 'guilds', $locale['step_database_error_table']);
error($locale['step_database_error_table']);
$error = true;
}
if($db->hasTable(TABLE_PREFIX . 'account_actions')) {
$locale['step_database_error_table_exist'] = str_replace('$TABLE$', TABLE_PREFIX . 'account_actions', $locale['step_database_error_table_exist']);
warning($locale['step_database_error_table_exist']);
}
else if(!$error) {
// import schema
try {
$db->query(file_get_contents(BASE . 'install/includes/schema.sql'));
registerDatabaseConfig('database_version', DATABASE_VERSION);
$locale['step_database_success_schema'] = str_replace('$PREFIX$', TABLE_PREFIX, $locale['step_database_success_schema']);
success($locale['step_database_success_schema']);
}
catch(PDOException $error_) {
error($locale['step_database_error_schema'] . ' ' . $error_);
$error = true;
}
}
if($error) {
return;
}
if($db->hasColumn('accounts', 'key')) {
if(query("ALTER TABLE `accounts` MODIFY `key` VARCHAR(64) NOT NULL DEFAULT '';"))
success($locale['step_database_modifying_field'] . ' accounts.key...');
}
else {
if(query("ALTER TABLE `accounts` ADD `key` VARCHAR(64) NOT NULL DEFAULT '' AFTER `email`;"))
success($locale['step_database_adding_field'] . ' accounts.key...');
}
if(!$db->hasColumn('accounts', 'blocked')) {
if(query("ALTER TABLE `accounts` ADD `blocked` TINYINT(1) NOT NULL DEFAULT FALSE COMMENT 'internal usage' AFTER `key`;"))
success($locale['step_database_adding_field'] . ' accounts.blocked...');
}
if(!$db->hasColumn('accounts', 'created')) {
if(query("ALTER TABLE `accounts` ADD `created` INT(11) NOT NULL DEFAULT 0 AFTER `" . ($db->hasColumn('accounts', 'group_id') ? 'group_id' : 'blocked') . "`;"))
success($locale['step_database_adding_field'] . ' accounts.created...');
}
if(!$db->hasColumn('accounts', 'rlname')) {
if(query("ALTER TABLE `accounts` ADD `rlname` VARCHAR(255) NOT NULL DEFAULT '' AFTER `created`;"))
success($locale['step_database_adding_field'] . ' accounts.rlname...');
}
if(!$db->hasColumn('accounts', 'location')) {
if(query("ALTER TABLE `accounts` ADD `location` VARCHAR(255) NOT NULL DEFAULT '' AFTER `rlname`;"))
success($locale['step_database_adding_field'] . ' accounts.location...');
}
if(!$db->hasColumn('accounts', 'country')) {
if(query("ALTER TABLE `accounts` ADD `country` VARCHAR(3) NOT NULL DEFAULT '' AFTER `location`;"))
success($locale['step_database_adding_field'] . ' accounts.country...');
}
if($db->hasColumn('accounts', 'page_lastday')) {
if(query("ALTER TABLE `accounts` CHANGE `page_lastday` `web_lastlogin` INT(11) NOT NULL DEFAULT 0;")) {
$tmp = str_replace('$FIELD$', 'accounts.page_lastday', $locale['step_database_changing_field']);
$tmp = str_replace('$FIELD_NEW$', 'accounts.web_lastlogin', $tmp);
success($tmp);
}
}
else if(!$db->hasColumn('accounts', 'web_lastlogin')) {
if(query("ALTER TABLE `accounts` ADD `web_lastlogin` INT(11) NOT NULL DEFAULT 0 AFTER `country`;"))
success($locale['step_database_adding_field'] . ' accounts.web_lastlogin...');
}
if(!$db->hasColumn('accounts', 'web_flags')) {
if(query("ALTER TABLE `accounts` ADD `web_flags` INT(11) NOT NULL DEFAULT 0 AFTER `web_lastlogin`;"))
success($locale['step_database_adding_field'] . ' accounts.web_flags...');
}
if(!$db->hasColumn('accounts', 'email_hash')) {
if(query("ALTER TABLE `accounts` ADD `email_hash` VARCHAR(32) NOT NULL DEFAULT '' AFTER `web_flags`;"))
success($locale['step_database_adding_field'] . ' accounts.email_hash...');
}
if(!$db->hasColumn('accounts', 'email_verified')) {
if(query("ALTER TABLE `accounts` ADD `email_verified` TINYINT(1) NOT NULL DEFAULT 0 AFTER `email_hash`;"))
success($locale['step_database_adding_field'] . ' accounts.email_verified...');
}
if(!$db->hasColumn('accounts', 'email_new')) {
if(query("ALTER TABLE `accounts` ADD `email_new` VARCHAR(255) NOT NULL DEFAULT '' AFTER `email_hash`;"))
success($locale['step_database_adding_field'] . ' accounts.email_new...');
}
if(!$db->hasColumn('accounts', 'email_new_time')) {
if(query("ALTER TABLE `accounts` ADD `email_new_time` INT(11) NOT NULL DEFAULT 0 AFTER `email_new`;"))
success($locale['step_database_adding_field'] . ' accounts.email_new_time...');
}
if(!$db->hasColumn('accounts', 'email_code')) {
if(query("ALTER TABLE `accounts` ADD `email_code` VARCHAR(255) NOT NULL DEFAULT '' AFTER `email_new_time`;"))
success($locale['step_database_adding_field'] . ' accounts.email_code...');
}
if($db->hasColumn('accounts', 'next_email')) {
if(!$db->hasColumn('accounts', 'email_next')) {
if(query("ALTER TABLE `accounts` CHANGE `next_email` `email_next` INT(11) NOT NULL DEFAULT 0;")) {
$tmp = str_replace('$FIELD$', 'accounts.next_email', $locale['step_database_changing_field']);
$tmp = str_replace('$FIELD_NEW$', 'accounts.email_next', $tmp);
success($tmp);
}
}
}
else if(!$db->hasColumn('accounts', 'email_next')) {
if(query("ALTER TABLE `accounts` ADD `email_next` INT(11) NOT NULL DEFAULT 0 AFTER `email_code`;"))
success($locale['step_database_adding_field'] . ' accounts.email_next...');
}
if(!$db->hasColumn('accounts', 'premium_points')) {
if(query("ALTER TABLE `accounts` ADD `premium_points` INT(11) NOT NULL DEFAULT 0 AFTER `email_next`;"))
success($locale['step_database_adding_field'] . ' accounts.premium_points...');
}
if(!$db->hasColumn('guilds', 'description')) {
if(query("ALTER TABLE `guilds` ADD `description` TEXT NOT NULL;"))
success($locale['step_database_adding_field'] . ' guilds.description...');
}
if($db->hasColumn('guilds', 'logo_gfx_name')) {
if(query("ALTER TABLE `guilds` CHANGE `logo_gfx_name` `logo_name` VARCHAR( 255 ) NOT NULL DEFAULT 'default.gif';")) {
$tmp = str_replace('$FIELD$', 'guilds.logo_gfx_name', $locale['step_database_changing_field']);
$tmp = str_replace('$FIELD_NEW$', 'guilds.logo_name', $tmp);
success($tmp);
}
}
else if(!$db->hasColumn('guilds', 'logo_name')) {
if(query("ALTER TABLE `guilds` ADD `logo_name` VARCHAR( 255 ) NOT NULL DEFAULT 'default.gif';"))
success($locale['step_database_adding_field'] . ' guilds.logo_name...');
}
if(!$db->hasColumn('players', 'created')) {
if(query("ALTER TABLE `players` ADD `created` INT(11) NOT NULL DEFAULT 0;"))
success($locale['step_database_adding_field'] . ' players.created...');
}
if(!$db->hasColumn('players', 'deleted') && !$db->hasColumn('players', 'deletion')) {
if(query("ALTER TABLE `players` ADD `deleted` TINYINT(1) NOT NULL DEFAULT 0;"))
success($locale['step_database_adding_field'] . ' players.comment...');
}
if($db->hasColumn('players', 'hide_char')) {
if(!$db->hasColumn('players', 'hidden')) {
if(query("ALTER TABLE `players` CHANGE `hide_char` `hidden` TINYINT(1) NOT NULL DEFAULT 0;")) {
$tmp = str_replace('$FIELD$', 'players.hide_char', $locale['step_database_changing_field']);
$tmp = str_replace('$FIELD_NEW$', 'players.hidden', $tmp);
success($tmp);
}
}
}
else if(!$db->hasColumn('players', 'hidden')) {
if(query("ALTER TABLE `players` ADD `hidden` TINYINT(1) NOT NULL DEFAULT 0;"))
success($locale['step_database_adding_field'] . ' players.hidden...');
}
if(!$db->hasColumn('players', 'comment')) {
if(query("ALTER TABLE `players` ADD `comment` TEXT NOT NULL;"))
success($locale['step_database_adding_field'] . ' players.comment...');
}
if($db->hasColumn('players', 'rank_id')) {
if(query("ALTER TABLE players MODIFY `rank_id` INT(11) NOT NULL DEFAULT 0;"))
success($locale['step_database_modifying_field'] . ' players.rank_id...');
if($db->hasColumn('players', 'guildnick')) {
if(query("ALTER TABLE players MODIFY `guildnick` VARCHAR(255) NOT NULL DEFAULT '';")) {
success($locale['step_database_modifying_field'] . ' players.guildnick...');
}
}
}

View File

@@ -0,0 +1,92 @@
<?php
require_once('../../common.php');
require(SYSTEM . 'functions.php');
require(BASE . 'install/includes/functions.php');
require(BASE . 'install/includes/locale.php');
ini_set('max_execution_time', 300);
ob_implicit_flush();
ob_end_flush();
if(isset($config['installed']) && $config['installed'] && !isset($_SESSION['saved'])) {
warning($locale['already_installed']);
return;
}
require(SYSTEM . 'init.php');
$deleted = 'deleted';
if($db->hasColumn('players', 'deletion'))
$deleted = 'deletion';
$time = time();
function insert_sample_if_not_exist($p) {
global $db, $success, $deleted, $time;
$query = $db->query('SELECT `id` FROM `players` WHERE `name` = ' . $db->quote($p['name']));
if($query->rowCount() == 0) {
if(!query("INSERT INTO `players` (`id`, `name`, `group_id`, `account_id`, `level`, `vocation`, `health`, `healthmax`, `experience`, `lookbody`, `lookfeet`, `lookhead`, `looklegs`, `looktype`, `maglevel`, `mana`, `manamax`, `manaspent`, `soul`, `town_id`, `posx`, `posy`, `posz`, `conditions`, `cap`, `sex`, `lastlogin`, `lastip`, `save`, `lastlogout`, `balance`, `$deleted`, `created`, `hidden`, `comment`) VALUES (null, " . $db->quote($p['name']) . ", 1, " . getSession('account') . ", " . $p['level'] . ", " . $p['vocation_id'] . ", " . $p['health'] . ", " . $p['healthmax'] . ", " . $p['experience'] . ", 118, 114, 38, 57, " . $p['looktype'] . ", 0, " . $p['mana'] . ", " . $p['manamax'] . ", 0, " . $p['soul'] . ", 1, 1000, 1000, 7, '', " . $p['cap'] . ", 1, " . $time . ", 2130706433, 1, " . $time . ", 0, 0, " . $time . ", 1, '');"))
$success = false;
}
}
$success = true;
insert_sample_if_not_exist(array('name' => 'Rook Sample', 'level' => 1, 'vocation_id' => 0, 'health' => 150, 'healthmax' => 150, 'experience' => 0, 'looktype' => 130, 'mana' => 0, 'manamax' => 0, 'soul' => 100, 'cap' => 400));
insert_sample_if_not_exist(array('name' => 'Sorcerer Sample', 'level' => 8, 'vocation_id' => 1, 'health' => 185, 'healthmax' => 185, 'experience' => 4200, 'looktype' => 130, 'mana' => 35, 'manamax' => 35, 'soul' => 100, 'cap' => 470));
insert_sample_if_not_exist(array('name' => 'Druid Sample', 'level' => 8, 'vocation_id' => 2, 'health' => 185, 'healthmax' => 185, 'experience' => 4200, 'looktype' => 130, 'mana' => 35, 'manamax' => 35, 'soul' => 100, 'cap' => 470));
insert_sample_if_not_exist(array('name' => 'Paladin Sample', 'level' => 8, 'vocation_id' => 3, 'health' => 185, 'healthmax' => 185, 'experience' => 4200, 'looktype' => 129, 'mana' => 35, 'manamax' => 35, 'soul' => 100, 'cap' => 470));
insert_sample_if_not_exist(array('name' => 'Knight Sample', 'level' => 8, 'vocation_id' => 4, 'health' => 185, 'healthmax' => 185, 'experience' => 4200, 'looktype' => 131, 'mana' => 35, 'manamax' => 35, 'soul' => 100, 'cap' => 470));
if($success) {
success($locale['step_database_imported_players']);
}
require(LIBS . 'items.php');
if(Items::loadFromXML())
success($locale['step_database_loaded_items']);
else
error(Items::getError());
require(LIBS . 'weapons.php');
if(Weapons::loadFromXML())
success($locale['step_database_loaded_weapons']);
else
error(Weapons::getError());
require(LIBS . 'creatures.php');
if(Creatures::loadFromXML()) {
success($locale['step_database_loaded_monsters']);
if(Creatures::getMonstersList()->hasErrors()) {
$locale['step_database_error_monsters'] = str_replace('$LOG$', 'system/logs/error.log', $locale['step_database_error_monsters']);
warning($locale['step_database_error_monsters']);
}
}
else {
error(Creatures::getLastError());
}
require(LIBS . 'spells.php');
if(Spells::loadFromXML()) {
success($locale['step_database_loaded_spells']);
}
else {
error(Spells::getLastError());
}
// update config.highscores_ids_hidden
require_once(SYSTEM . 'migrations/20.php');
$database_migration_20 = true;
$content = '';
if(!databaseMigration20($content)) {
$locale['step_database_error_file'] = str_replace('$FILE$', '<b>' . BASE . 'config.local.php</b>', $locale['step_database_error_file']);
warning($locale['step_database_error_file'] . '<br/>
<textarea cols="70" rows="10">' . $content . '</textarea>');
}
$locale['step_finish_desc'] = str_replace('$ADMIN_PANEL$', generateLink(str_replace('tools/', '',ADMIN_URL), $locale['step_finish_admin_panel'], true), $locale['step_finish_desc']);
$locale['step_finish_desc'] = str_replace('$HOMEPAGE$', generateLink(str_replace('tools/', '', BASE_URL), $locale['step_finish_homepage'], true), $locale['step_finish_desc']);
$locale['step_finish_desc'] = str_replace('$LINK$', generateLink('http://my-aac.org', 'http://my-aac.org', true), $locale['step_finish_desc']);
success($locale['step_finish_desc']);

View File

@@ -0,0 +1,40 @@
function performInstall(url) {
var lastResponseLength = false;
var lastId = 1;
var ajaxRequest = $.ajax({
type: 'get',
url: url,
data: {},
dataType: 'html',
processData: false,
xhrFields: {
// Getting on progress streaming response
onprogress: function (e) {
var progressResponse;
var response = e.currentTarget.response;
progressResponse = response;
if (lastResponseLength === false) {
progressResponse = response;
lastResponseLength = response.length;
}
else {
progressResponse = response.substring(lastResponseLength);
lastResponseLength = response.length;
}
$('<div id="success-' + (lastId + 1) + '">' + progressResponse + '</div>').insertAfter("#success-" + lastId);
lastId = lastId + 1;
}
}
});
// On completed
ajaxRequest.done(function(data) {
$('#spinner').hide();
});
// On failed
ajaxRequest.fail(function(error){
console.log('Error: ', error);
$('<span class="error">Error while doing AJAX request. Please refresh the page.</span>').insertAfter("#success-" + lastId);
});
}

View File

@@ -6,13 +6,21 @@
"contact": "nobody@example.org",
"require": {
"myaac": "0.4.3",
"php": "5.2.0"
"myaac_": ">=0.7,<1.0", // support for defining versions like in composer (since 0.8.0)
"php": "5.2.0",
"php_": ">5.4,<7.0", // support for defining versions like in composer (since 0.8.0)
"database": "21"
},
"install": "plugins/example/install.php",
"uninstall": [
"plugins/example.json",
"plugins/example/install.php",
"plugins/example/before.php"
"plugins/example-directory",
"templates/other-directory"
/***
this is example of multi line comment
1. list example
2. something
****/
],
"hooks": {
"Example Hook": {

View File

@@ -29,7 +29,7 @@ if(Plugins::install($path_to_file)) {
echo 'WARNING: ' . $warning;
}
$info = Plugins::getPluginInfo();
$info = Plugins::getPlugin();
echo (isset($info['name']) ? $info['name'] . ' p' : 'P') . 'lugin has been successfully installed.';
}
else

78
system/clients.conf.php Normal file
View File

@@ -0,0 +1,78 @@
<?php
/**
* List of clients
*
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2017 MyAAC
* @link http://my-aac.org
*/
defined('MYAAC') or die('Direct access not allowed!');
$config['clients'] = array(
710,
740,
750,
760,
770,
772,
780,
792,
800,
810,
821,
822,
831,
840,
841,
842,
850,
852,
853,
854,
855,
857,
860,
870,
900,
910,
920,
930,
940,
942,
944,
946,
950,
952,
953,
954,
960,
970,
980,
1000,
1010,
1021,
1031,
1034,
1041,
1050,
1053,
1054,
1058,
1075,
1077,
1079,
1080,
1090,
1093,
1094,
1095,
1096,
1097,
1098,
1100,
);
?>

View File

@@ -60,4 +60,16 @@ function check_guild_name($name, &$errors = '') {
function news_place() {
return tickers();
}
function tableExist($table)
{
global $db;
return $db->hasTable($table);
}
function fieldExist($field, $table)
{
global $db;
return $db->hasColumn($table, $field);
}
?>

View File

@@ -76,13 +76,17 @@ defined('MYAAC') or die('Direct access not allowed!');
if(isset($config['lua']['useMD5Passwords']) && getBoolean($config['lua']['useMD5Passwords']))
$config['database_encryption'] = 'md5';
if(!isset($config['database_log'])) {
$config['database_log'] = false;
}
try {
$ots->connect(POT::DB_MYSQL,
array(
$ots->connect(array(
'host' => $config['database_host'],
'user' => $config['database_user'],
'password' => $config['database_password'],
'database' => $config['database_name']
'database' => $config['database_name'],
'log' => $config['database_log']
)
);
}

View File

@@ -69,7 +69,7 @@ function getPlayerLink($name, $generate = true)
if(is_numeric($name))
{
$player = $ots->createObject('Player');
$player = new OTS_Player();
$player->load(intval($name));
if($player->isLoaded())
$name = $player->getName();
@@ -156,6 +156,10 @@ function getFlagImage($country)
if(!isset($config['countries']))
require(SYSTEM . 'countries.conf.php');
if(!isset($config['countries'][$country])) {
return '';
}
return '<img src="images/flags/' . $country . '.gif" title="' . $config['countries'][$country]. '"/>';
}
@@ -167,7 +171,9 @@ function getFlagImage($country)
*/
function getBoolean($v)
{
if(!$v || !isset($v[0])) return false;
if(is_bool($v)) {
return $v;
}
if(is_numeric($v))
return intval($v) > 0;
@@ -302,22 +308,6 @@ function encrypt($str)
return $str;
}
function tableExist($table)
{
global $db, $config;
$query = $db->query("SELECT `TABLE_NAME` FROM `information_schema`.`tables` WHERE `TABLE_SCHEMA` = " . $db->quote($config['database_name']) . " AND `TABLE_NAME` = " . $db->quote($table) . ";");
return $query->rowCount() > 0;
}
function fieldExist($field, $table)
{
global $db;
if(count($db->query("SHOW COLUMNS FROM `" . $table . "` LIKE '" . $field . "'")->fetchAll()))
return true;
return false;
}
//delete player with name
function delete_player($name)
{
@@ -376,9 +366,9 @@ function delete_guild($id)
global $db, $ots;
foreach($rank_list as $rank_in_guild) {
if(tableExist('guild_members'))
if($db->hasTable('guild_members'))
$players_with_rank = $db->query('SELECT `players`.`id` as `id`, `guild_members`.`rank_id` as `rank_id` FROM `players`, `guild_members` WHERE `guild_members`.`rank_id` = ' . $rank_in_guild->getId() . ' AND `players`.`id` = `guild_members`.`player_id` ORDER BY `name`;');
else if(tableExist('guild_membership'))
else if($db->hasTable('guild_membership'))
$players_with_rank = $db->query('SELECT `players`.`id` as `id`, `guild_membership`.`rank_id` as `rank_id` FROM `players`, `guild_membership` WHERE `guild_membership`.`rank_id` = ' . $rank_in_guild->getId() . ' AND `players`.`id` = `guild_membership`.`player_id` ORDER BY `name`;');
else
$players_with_rank = $db->query('SELECT `id`, `rank_id` FROM `players` WHERE `rank_id` = ' . $rank_in_guild->getId() . ' AND `deleted` = 0;');
@@ -386,7 +376,7 @@ function delete_guild($id)
$players_with_rank_number = $players_with_rank->rowCount();
if($players_with_rank_number > 0) {
foreach($players_with_rank as $result) {
$player = $ots->createObject('Player');
$player = new OTS_Player();
$player->load($result['id']);
if(!$player->isLoaded())
continue;
@@ -563,7 +553,7 @@ function getCreatureName($killer, $showStatus = false, $extendedInfo = false)
if(is_numeric($killer))
{
$player = $ots->createObject('Player');
$player = new OTS_Player();
$player->load($killer);
if($player->isLoaded())
{
@@ -573,7 +563,7 @@ function getCreatureName($killer, $showStatus = false, $extendedInfo = false)
$str .= '<font color="'.($player->isOnline() ? 'green' : 'red').'">' . $player->getName() . '</font></b></a>';
if($extendedInfo) {
$str .= '<br><small>'.$player->getLevel().' '.$config['vocations'][$player->getVocation()].'</small>';
$str .= '<br><small>'.$player->getLevel().' '.$player->getVocationName().'</small>';
}
return $str;
}
@@ -816,9 +806,9 @@ function _mail($to, $subject, $body, $altBody = '', $add_html_tags = true)
$signature_html = $config['mail_signature']['html'];
if($add_html_tags && isset($body[0]))
$body = '<html><head></head><body>' . $body . '<br/><br/>' . $signature_html . '</body></html>';
$tmp_body = '<html><head></head><body>' . $body . '<br/><br/>' . $signature_html . '</body></html>';
else
$body .= '<br/><br/>' . $signature_html;
$tmp_body .= '<br/><br/>' . $signature_html;
if($config['smtp_enabled'])
{
@@ -839,7 +829,7 @@ function _mail($to, $subject, $body, $altBody = '', $add_html_tags = true)
$mailer->FromName = $config['lua']['serverName'];
$mailer->Subject = $subject;
$mailer->AddAddress($to);
$mailer->Body = $body;
$mailer->Body = $tmp_body;
$signature_plain = '';
if(isset($config['mail_signature']['plain']))
@@ -847,6 +837,9 @@ function _mail($to, $subject, $body, $altBody = '', $add_html_tags = true)
if(isset($altBody[0]))
$mailer->AltBody = $altBody . $signature_plain;
else { // automatically generate plain html
$mailer->AltBody = strip_tags(preg_replace('/<a(.*)href="([^"]*)"(.*)>/','$2', $body)) . "\n" . $signature_plain;
}
return $mailer->Send();
}
@@ -968,10 +961,18 @@ function getTopPlayers($limit = 5) {
if($fetch_from_db)
{
$deleted = 'deleted';
if(fieldExist('deletion', 'players'))
if($db->hasColumn('players', 'deletion'))
$deleted = 'deletion';
$players = $db->query('SELECT `name`, `level`, `experience` FROM `players` WHERE `group_id` < ' . $config['highscores_groups_hidden'] . ' AND `id` NOT IN (' . implode(', ', $config['highscores_ids_hidden']) . ') AND `' . $deleted . '` = 0 AND `account_id` != 1 ORDER BY `experience` DESC LIMIT 5')->fetchAll();
$is_tfs10 = $db->hasTable('players_online');
$players = $db->query('SELECT `id`, `name`, `level`, `experience`' . ($is_tfs10 ? '' : ', `online`') . ' FROM `players` WHERE `group_id` < ' . $config['highscores_groups_hidden'] . ' AND `id` NOT IN (' . implode(', ', $config['highscores_ids_hidden']) . ') AND `' . $deleted . '` = 0 AND `account_id` != 1 ORDER BY `experience` DESC LIMIT ' . (int)$limit)->fetchAll();
if($is_tfs10) {
foreach($players as &$player) {
$query = $db->query('SELECT `player_id` FROM `players_online` WHERE `player_id` = ' . $player['id']);
$player['online'] = ($query->rowCount() > 0 ? 1 : 0);
}
}
$i = 0;
foreach($players as &$player) {

View File

@@ -8,14 +8,14 @@
* @link http://my-aac.org
*/
defined('MYAAC') or die('Direct access not allowed!');
// load configuration
require_once(BASE . 'config.php');
if(file_exists(BASE . 'config.local.php')) // user customizations
require(BASE . 'config.local.php');
if(!isset($config['installed']) || !$config['installed']) {
header('Location: ' . BASE_URL);
die('AAC has not been installed yet or there was error during installation. Please install again.');
die('MyAAC has not been installed yet or there was error during installation. Please install again.');
}
date_default_timezone_set($config['date_timezone']);
@@ -38,7 +38,8 @@ Twig_Autoloader::register();
$twig_loader = new Twig_Loader_Filesystem(SYSTEM . 'templates');
$twig = new Twig_Environment($twig_loader, array(
'cache' => CACHE . 'twig/',
'auto_reload' => true
'auto_reload' => true,
//'debug' => true
));
$function = new Twig_SimpleFunction('getStyle', function ($i) {
@@ -87,21 +88,26 @@ if(isset($_REQUEST))
}
// load otserv config file
$tmp = '';
if($cache->enabled() && $cache->fetch('config_lua', $tmp)) {
$config_lua_reload = true;
if($cache->enabled()) {
$tmp = null;
if($cache->fetch('server_path', $tmp) && $tmp == $config['server_path']) {
$tmp = null;
if($cache->fetch('config_lua', $tmp) && $tmp) {
$config['lua'] = unserialize($tmp);
/*if(isset($config['lua']['myaac'][0])) {
foreach($config['lua']['myaac'] as $key => $value)
$config[$key] = $value;
}*/
$config_lua_reload = false;
}
}
}
else
{
if($config_lua_reload) {
$config['lua'] = load_config_lua($config['server_path'] . 'config.lua');
// cache config
if($cache->enabled())
if($cache->enabled()) {
$cache->set('config_lua', serialize($config['lua']), 120);
$cache->set('server_path', $config['server_path']);
}
}
unset($tmp);
@@ -158,7 +164,7 @@ require_once(SYSTEM . 'libs/pot/OTS.php');
$ots = POT::getInstance();
require_once(SYSTEM . 'database.php');
define('USE_ACCOUNT_NAME', fieldExist('name', 'accounts'));
define('USE_ACCOUNT_NAME', $db->hasColumn('accounts', 'name'));
// load vocation names
$tmp = '';
if($cache->enabled() && $cache->fetch('vocations', $tmp)) {

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -13,13 +13,15 @@
* Autoloads Twig classes.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @deprecated since 1.21 and will be removed in 2.0. Use Composer instead. 2.0.
*/
class Twig_Autoloader
{
/**
* Registers Twig_Autoloader as an SPL autoloader.
*
* @param bool $prepend Whether to prepend the autoloader or not.
* @param bool $prepend whether to prepend the autoloader or not
*/
public static function register($prepend = false)
{
@@ -33,7 +35,7 @@ class Twig_Autoloader
/**
* Handles autoloading of classes.
*
* @param string $class A class name.
* @param string $class a class name
*/
public static function autoload($class)
{

View File

@@ -16,9 +16,6 @@
*/
abstract class Twig_BaseNodeVisitor implements Twig_NodeVisitorInterface
{
/**
* {@inheritdoc}
*/
final public function enterNode(Twig_NodeInterface $node, Twig_Environment $env)
{
if (!$node instanceof Twig_Node) {
@@ -28,9 +25,6 @@ abstract class Twig_BaseNodeVisitor implements Twig_NodeVisitorInterface
return $this->doEnterNode($node, $env);
}
/**
* {@inheritdoc}
*/
final public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env)
{
if (!$node instanceof Twig_Node) {
@@ -43,9 +37,6 @@ abstract class Twig_BaseNodeVisitor implements Twig_NodeVisitorInterface
/**
* Called before child nodes are visited.
*
* @param Twig_Node $node The node to visit
* @param Twig_Environment $env The Twig environment instance
*
* @return Twig_Node The modified node
*/
abstract protected function doEnterNode(Twig_Node $node, Twig_Environment $env);
@@ -53,10 +44,11 @@ abstract class Twig_BaseNodeVisitor implements Twig_NodeVisitorInterface
/**
* Called after child nodes are visited.
*
* @param Twig_Node $node The node to visit
* @param Twig_Environment $env The Twig environment instance
*
* @return Twig_Node|false The modified node or false if the node must be removed
*/
abstract protected function doLeaveNode(Twig_Node $node, Twig_Environment $env);
}
class_alias('Twig_BaseNodeVisitor', 'Twig\NodeVisitor\AbstractNodeVisitor', false);
class_exists('Twig_Environment');
class_exists('Twig_Node');

View File

@@ -0,0 +1,93 @@
<?php
/*
* This file is part of Twig.
*
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* Implements a cache on the filesystem.
*
* @author Andrew Tch <andrew@noop.lv>
*/
class Twig_Cache_Filesystem implements Twig_CacheInterface
{
const FORCE_BYTECODE_INVALIDATION = 1;
private $directory;
private $options;
/**
* @param $directory string The root cache directory
* @param $options int A set of options
*/
public function __construct($directory, $options = 0)
{
$this->directory = rtrim($directory, '\/').'/';
$this->options = $options;
}
public function generateKey($name, $className)
{
$hash = hash('sha256', $className);
return $this->directory.$hash[0].$hash[1].'/'.$hash.'.php';
}
public function load($key)
{
if (file_exists($key)) {
@include_once $key;
}
}
public function write($key, $content)
{
$dir = dirname($key);
if (!is_dir($dir)) {
if (false === @mkdir($dir, 0777, true)) {
if (PHP_VERSION_ID >= 50300) {
clearstatcache(true, $dir);
}
if (!is_dir($dir)) {
throw new RuntimeException(sprintf('Unable to create the cache directory (%s).', $dir));
}
}
} elseif (!is_writable($dir)) {
throw new RuntimeException(sprintf('Unable to write in the cache directory (%s).', $dir));
}
$tmpFile = tempnam($dir, basename($key));
if (false !== @file_put_contents($tmpFile, $content) && @rename($tmpFile, $key)) {
@chmod($key, 0666 & ~umask());
if (self::FORCE_BYTECODE_INVALIDATION == ($this->options & self::FORCE_BYTECODE_INVALIDATION)) {
// Compile cached file into bytecode cache
if (function_exists('opcache_invalidate')) {
opcache_invalidate($key, true);
} elseif (function_exists('apc_compile_file')) {
apc_compile_file($key);
}
}
return;
}
throw new RuntimeException(sprintf('Failed to write cache file "%s".', $key));
}
public function getTimestamp($key)
{
if (!file_exists($key)) {
return 0;
}
return (int) @filemtime($key);
}
}
class_alias('Twig_Cache_Filesystem', 'Twig\Cache\FilesystemCache', false);

View File

@@ -0,0 +1,40 @@
<?php
/*
* This file is part of Twig.
*
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* Implements a no-cache strategy.
*
* @final
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class Twig_Cache_Null implements Twig_CacheInterface
{
public function generateKey($name, $className)
{
return '';
}
public function write($key, $content)
{
}
public function load($key)
{
}
public function getTimestamp($key)
{
return 0;
}
}
class_alias('Twig_Cache_Null', 'Twig\Cache\NullCache', false);

View File

@@ -0,0 +1,58 @@
<?php
/*
* This file is part of Twig.
*
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* Interface implemented by cache classes.
*
* It is highly recommended to always store templates on the filesystem to
* benefit from the PHP opcode cache. This interface is mostly useful if you
* need to implement a custom strategy for storing templates on the filesystem.
*
* @author Andrew Tch <andrew@noop.lv>
*/
interface Twig_CacheInterface
{
/**
* Generates a cache key for the given template class name.
*
* @param string $name The template name
* @param string $className The template class name
*
* @return string
*/
public function generateKey($name, $className);
/**
* Writes the compiled template to cache.
*
* @param string $key The cache key
* @param string $content The template representation as a PHP class
*/
public function write($key, $content);
/**
* Loads a template from the cache.
*
* @param string $key The cache key
*/
public function load($key);
/**
* Returns the modification timestamp of a key.
*
* @param string $key The cache key
*
* @return int
*/
public function getTimestamp($key);
}
class_alias('Twig_CacheInterface', 'Twig\Cache\CacheInterface', false);

View File

@@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -21,31 +21,30 @@ class Twig_Compiler implements Twig_CompilerInterface
protected $source;
protected $indentation;
protected $env;
protected $debugInfo;
protected $debugInfo = array();
protected $sourceOffset;
protected $sourceLine;
protected $filename;
/**
* Constructor.
*
* @param Twig_Environment $env The twig environment instance
*/
public function __construct(Twig_Environment $env)
{
$this->env = $env;
$this->debugInfo = array();
}
/**
* @deprecated since 1.25 (to be removed in 2.0)
*/
public function getFilename()
{
@trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), E_USER_DEPRECATED);
return $this->filename;
}
/**
* Returns the environment instance related to this compiler.
*
* @return Twig_Environment The environment instance
* @return Twig_Environment
*/
public function getEnvironment()
{
@@ -68,7 +67,7 @@ class Twig_Compiler implements Twig_CompilerInterface
* @param Twig_NodeInterface $node The node to compile
* @param int $indentation The current indentation
*
* @return Twig_Compiler The current compiler instance
* @return $this
*/
public function compile(Twig_NodeInterface $node, $indentation = 0)
{
@@ -81,7 +80,8 @@ class Twig_Compiler implements Twig_CompilerInterface
$this->indentation = $indentation;
if ($node instanceof Twig_Node_Module) {
$this->filename = $node->getAttribute('filename');
// to be removed in 2.0
$this->filename = $node->getTemplateName();
}
$node->compile($this);
@@ -92,7 +92,7 @@ class Twig_Compiler implements Twig_CompilerInterface
public function subcompile(Twig_NodeInterface $node, $raw = true)
{
if (false === $raw) {
$this->addIndentation();
$this->source .= str_repeat(' ', $this->indentation * 4);
}
$node->compile($this);
@@ -105,7 +105,7 @@ class Twig_Compiler implements Twig_CompilerInterface
*
* @param string $string The string
*
* @return Twig_Compiler The current compiler instance
* @return $this
*/
public function raw($string)
{
@@ -117,14 +117,13 @@ class Twig_Compiler implements Twig_CompilerInterface
/**
* Writes a string to the compiled code by adding indentation.
*
* @return Twig_Compiler The current compiler instance
* @return $this
*/
public function write()
{
$strings = func_get_args();
foreach ($strings as $string) {
$this->addIndentation();
$this->source .= $string;
$this->source .= str_repeat(' ', $this->indentation * 4).$string;
}
return $this;
@@ -133,10 +132,14 @@ class Twig_Compiler implements Twig_CompilerInterface
/**
* Appends an indentation to the current PHP code after compilation.
*
* @return Twig_Compiler The current compiler instance
* @return $this
*
* @deprecated since 1.27 (to be removed in 2.0).
*/
public function addIndentation()
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use write(\'\') instead.', E_USER_DEPRECATED);
$this->source .= str_repeat(' ', $this->indentation * 4);
return $this;
@@ -147,7 +150,7 @@ class Twig_Compiler implements Twig_CompilerInterface
*
* @param string $value The string
*
* @return Twig_Compiler The current compiler instance
* @return $this
*/
public function string($value)
{
@@ -161,12 +164,12 @@ class Twig_Compiler implements Twig_CompilerInterface
*
* @param mixed $value The value to convert
*
* @return Twig_Compiler The current compiler instance
* @return $this
*/
public function repr($value)
{
if (is_int($value) || is_float($value)) {
if (false !== $locale = setlocale(LC_NUMERIC, 0)) {
if (false !== $locale = setlocale(LC_NUMERIC, '0')) {
setlocale(LC_NUMERIC, 'C');
}
@@ -202,28 +205,28 @@ class Twig_Compiler implements Twig_CompilerInterface
/**
* Adds debugging information.
*
* @param Twig_NodeInterface $node The related twig node
*
* @return Twig_Compiler The current compiler instance
* @return $this
*/
public function addDebugInfo(Twig_NodeInterface $node)
{
if ($node->getLine() != $this->lastLine) {
$this->write(sprintf("// line %d\n", $node->getLine()));
if ($node->getTemplateLine() != $this->lastLine) {
$this->write(sprintf("// line %d\n", $node->getTemplateLine()));
// when mbstring.func_overload is set to 2
// mb_substr_count() replaces substr_count()
// but they have different signatures!
if (((int) ini_get('mbstring.func_overload')) & 2) {
@trigger_error('Support for having "mbstring.func_overload" different from 0 is deprecated version 1.29 and will be removed in 2.0.', E_USER_DEPRECATED);
// this is much slower than the "right" version
$this->sourceLine += mb_substr_count(mb_substr($this->source, $this->sourceOffset), "\n");
} else {
$this->sourceLine += substr_count($this->source, "\n", $this->sourceOffset);
}
$this->sourceOffset = strlen($this->source);
$this->debugInfo[$this->sourceLine] = $node->getLine();
$this->debugInfo[$this->sourceLine] = $node->getTemplateLine();
$this->lastLine = $node->getLine();
$this->lastLine = $node->getTemplateLine();
}
return $this;
@@ -241,7 +244,7 @@ class Twig_Compiler implements Twig_CompilerInterface
*
* @param int $step The number of indentation to add
*
* @return Twig_Compiler The current compiler instance
* @return $this
*/
public function indent($step = 1)
{
@@ -255,7 +258,7 @@ class Twig_Compiler implements Twig_CompilerInterface
*
* @param int $step The number of indentation to remove
*
* @return Twig_Compiler The current compiler instance
* @return $this
*
* @throws LogicException When trying to outdent too much so the indentation would become negative
*/
@@ -263,7 +266,7 @@ class Twig_Compiler implements Twig_CompilerInterface
{
// can't outdent by more steps than the current indentation level
if ($this->indentation < $step) {
throw new LogicException('Unable to call outdent() as the indentation would become negative');
throw new LogicException('Unable to call outdent() as the indentation would become negative.');
}
$this->indentation -= $step;
@@ -276,3 +279,6 @@ class Twig_Compiler implements Twig_CompilerInterface
return sprintf('__internal_%s', hash('sha256', uniqid(mt_rand(), true), false));
}
}
class_alias('Twig_Compiler', 'Twig\Compiler', false);
class_exists('Twig_Node');

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -21,9 +21,7 @@ interface Twig_CompilerInterface
/**
* Compiles a node.
*
* @param Twig_NodeInterface $node The node to compile
*
* @return Twig_CompilerInterface The current compiler instance
* @return $this
*/
public function compile(Twig_NodeInterface $node);

View File

@@ -0,0 +1,39 @@
<?php
/*
* This file is part of Twig.
*
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Psr\Container\ContainerInterface;
/**
* Lazily loads Twig runtime implementations from a PSR-11 container.
*
* Note that the runtime services MUST use their class names as identifiers.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Robin Chalas <robin.chalas@gmail.com>
*/
class Twig_ContainerRuntimeLoader implements Twig_RuntimeLoaderInterface
{
private $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public function load($class)
{
if ($this->container->has($class)) {
return $this->container->get($class);
}
}
}
class_alias('Twig_ContainerRuntimeLoader', 'Twig\RuntimeLoader\ContainerRuntimeLoader', false);

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -25,8 +25,8 @@
* and line number) yourself by passing them to the constructor. If some or all
* these information are not available from where you throw the exception, then
* this class will guess them automatically (when the line number is set to -1
* and/or the filename is set to null). As this is a costly operation, this
* can be disabled by passing false for both the filename and the line number
* and/or the name is set to null). As this is a costly operation, this
* can be disabled by passing false for both the name and the line number
* when creating a new instance of this class.
*
* @author Fabien Potencier <fabien@symfony.com>
@@ -34,29 +34,43 @@
class Twig_Error extends Exception
{
protected $lineno;
// to be renamed to name in 2.0
protected $filename;
protected $rawMessage;
protected $previous;
private $sourcePath;
private $sourceCode;
/**
* Constructor.
*
* Set both the line number and the filename to false to
* Set both the line number and the name to false to
* disable automatic guessing of the original template name
* and line number.
*
* Set the line number to -1 to enable its automatic guessing.
* Set the filename to null to enable its automatic guessing.
* Set the name to null to enable its automatic guessing.
*
* By default, automatic guessing is enabled.
*
* @param string $message The error message
* @param int $lineno The template line where the error occurred
* @param string $filename The template file name where the error occurred
* @param Twig_Source|string|null $source The source context where the error occurred
* @param Exception $previous The previous exception
*/
public function __construct($message, $lineno = -1, $filename = null, Exception $previous = null)
public function __construct($message, $lineno = -1, $source = null, Exception $previous = null)
{
if (null === $source) {
$name = null;
} elseif (!$source instanceof Twig_Source) {
// for compat with the Twig C ext., passing the template name as string is accepted
$name = $source;
} else {
$name = $source->getName();
$this->sourceCode = $source->getCode();
$this->sourcePath = $source->getPath();
}
if (PHP_VERSION_ID < 50300) {
$this->previous = $previous;
parent::__construct('');
@@ -65,9 +79,9 @@ class Twig_Error extends Exception
}
$this->lineno = $lineno;
$this->filename = $filename;
$this->filename = $name;
if (-1 === $this->lineno || null === $this->filename) {
if (-1 === $lineno || null === $name || null === $this->sourcePath) {
$this->guessTemplateInfo();
}
@@ -87,23 +101,62 @@ class Twig_Error extends Exception
}
/**
* Gets the filename where the error occurred.
* Gets the logical name where the error occurred.
*
* @return string The filename
* @return string The name
*
* @deprecated since 1.27 (to be removed in 2.0). Use getSourceContext() instead.
*/
public function getTemplateFile()
{
@trigger_error(sprintf('The "%s" method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', __METHOD__), E_USER_DEPRECATED);
return $this->filename;
}
/**
* Sets the filename where the error occurred.
* Sets the logical name where the error occurred.
*
* @param string $filename The filename
* @param string $name The name
*
* @deprecated since 1.27 (to be removed in 2.0). Use setSourceContext() instead.
*/
public function setTemplateFile($filename)
public function setTemplateFile($name)
{
$this->filename = $filename;
@trigger_error(sprintf('The "%s" method is deprecated since version 1.27 and will be removed in 2.0. Use setSourceContext() instead.', __METHOD__), E_USER_DEPRECATED);
$this->filename = $name;
$this->updateRepr();
}
/**
* Gets the logical name where the error occurred.
*
* @return string The name
*
* @deprecated since 1.29 (to be removed in 2.0). Use getSourceContext() instead.
*/
public function getTemplateName()
{
@trigger_error(sprintf('The "%s" method is deprecated since version 1.29 and will be removed in 2.0. Use getSourceContext() instead.', __METHOD__), E_USER_DEPRECATED);
return $this->filename;
}
/**
* Sets the logical name where the error occurred.
*
* @param string $name The name
*
* @deprecated since 1.29 (to be removed in 2.0). Use setSourceContext() instead.
*/
public function setTemplateName($name)
{
@trigger_error(sprintf('The "%s" method is deprecated since version 1.29 and will be removed in 2.0. Use setSourceContext() instead.', __METHOD__), E_USER_DEPRECATED);
$this->filename = $name;
$this->sourceCode = $this->sourcePath = null;
$this->updateRepr();
}
@@ -130,6 +183,32 @@ class Twig_Error extends Exception
$this->updateRepr();
}
/**
* Gets the source context of the Twig template where the error occurred.
*
* @return Twig_Source|null
*/
public function getSourceContext()
{
return $this->filename ? new Twig_Source($this->sourceCode, $this->filename, $this->sourcePath) : null;
}
/**
* Sets the source context of the Twig template where the error occurred.
*/
public function setSourceContext(Twig_Source $source = null)
{
if (null === $source) {
$this->sourceCode = $this->filename = $this->sourcePath = null;
} else {
$this->sourceCode = $source->getCode();
$this->filename = $source->getName();
$this->sourcePath = $source->getPath();
}
$this->updateRepr();
}
public function guess()
{
$this->guessTemplateInfo();
@@ -155,23 +234,45 @@ class Twig_Error extends Exception
throw new BadMethodCallException(sprintf('Method "Twig_Error::%s()" does not exist.', $method));
}
public function appendMessage($rawMessage)
{
$this->rawMessage .= $rawMessage;
$this->updateRepr();
}
/**
* @internal
*/
protected function updateRepr()
{
$this->message = $this->rawMessage;
if ($this->sourcePath && $this->lineno > 0) {
$this->file = $this->sourcePath;
$this->line = $this->lineno;
return;
}
$dot = false;
if ('.' === substr($this->message, -1)) {
$this->message = substr($this->message, 0, -1);
$dot = true;
}
$questionMark = false;
if ('?' === substr($this->message, -1)) {
$this->message = substr($this->message, 0, -1);
$questionMark = true;
}
if ($this->filename) {
if (is_string($this->filename) || (is_object($this->filename) && method_exists($this->filename, '__toString'))) {
$filename = sprintf('"%s"', $this->filename);
$name = sprintf('"%s"', $this->filename);
} else {
$filename = json_encode($this->filename);
$name = json_encode($this->filename);
}
$this->message .= sprintf(' in %s', $filename);
$this->message .= sprintf(' in %s', $name);
}
if ($this->lineno && $this->lineno >= 0) {
@@ -181,8 +282,15 @@ class Twig_Error extends Exception
if ($dot) {
$this->message .= '.';
}
if ($questionMark) {
$this->message .= '?';
}
}
/**
* @internal
*/
protected function guessTemplateInfo()
{
$template = null;
@@ -205,11 +313,18 @@ class Twig_Error extends Exception
}
}
// update template filename
// update template name
if (null !== $template && null === $this->filename) {
$this->filename = $template->getTemplateName();
}
// update template path if any
if (null !== $template && null === $this->sourcePath) {
$src = $template->getSourceContext();
$this->sourceCode = $src->getCode();
$this->sourcePath = $src->getPath();
}
if (null === $template || $this->lineno > -1) {
return;
}
@@ -217,11 +332,6 @@ class Twig_Error extends Exception
$r = new ReflectionObject($template);
$file = $r->getFileName();
// hhvm has a bug where eval'ed files comes out as the current directory
if (is_dir($file)) {
$file = '';
}
$exceptions = array($e = $this);
while (($e instanceof self || method_exists($e, 'getPrevious')) && $e = $e->getPrevious()) {
$exceptions[] = $e;
@@ -248,3 +358,6 @@ class Twig_Error extends Exception
}
}
}
class_alias('Twig_Error', 'Twig\Error\Error', false);
class_exists('Twig_Source');

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -24,8 +24,17 @@
*/
class Twig_Error_Loader extends Twig_Error
{
public function __construct($message, $lineno = -1, $filename = null, Exception $previous = null)
public function __construct($message, $lineno = -1, $source = null, Exception $previous = null)
{
parent::__construct($message, false, false, $previous);
if (PHP_VERSION_ID < 50300) {
$this->previous = $previous;
Exception::__construct('');
} else {
Exception::__construct('', 0, $previous);
}
$this->appendMessage($message);
$this->setTemplateLine(false);
}
}
class_alias('Twig_Error_Loader', 'Twig\Error\LoaderError', false);

View File

@@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -18,3 +18,5 @@
class Twig_Error_Runtime extends Twig_Error
{
}
class_alias('Twig_Error_Runtime', 'Twig\Error\RuntimeError', false);

View File

@@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -17,4 +17,39 @@
*/
class Twig_Error_Syntax extends Twig_Error
{
/**
* Tweaks the error message to include suggestions.
*
* @param string $name The original name of the item that does not exist
* @param array $items An array of possible items
*/
public function addSuggestions($name, array $items)
{
if (!$alternatives = self::computeAlternatives($name, $items)) {
return;
}
$this->appendMessage(sprintf(' Did you mean "%s"?', implode('", "', $alternatives)));
}
/**
* @internal
*
* To be merged with the addSuggestions() method in 2.0.
*/
public static function computeAlternatives($name, $items)
{
$alternatives = array();
foreach ($items as $item) {
$lev = levenshtein($name, $item);
if ($lev <= strlen($name) / 3 || false !== strpos($item, $name)) {
$alternatives[$item] = $lev;
}
}
asort($alternatives);
return array_keys($alternatives);
}
}
class_alias('Twig_Error_Syntax', 'Twig\Error\SyntaxError', false);

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -27,3 +27,5 @@ interface Twig_ExistsLoaderInterface
*/
public function exists($name);
}
class_alias('Twig_ExistsLoaderInterface', 'Twig\Loader\ExistsLoaderInterface', false);

View File

@@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -19,6 +19,8 @@
* @see http://en.wikipedia.org/wiki/Operator-precedence_parser
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @internal
*/
class Twig_ExpressionParser
{
@@ -29,11 +31,23 @@ class Twig_ExpressionParser
protected $unaryOperators;
protected $binaryOperators;
public function __construct(Twig_Parser $parser, array $unaryOperators, array $binaryOperators)
private $env;
public function __construct(Twig_Parser $parser, $env = null)
{
$this->parser = $parser;
$this->unaryOperators = $unaryOperators;
$this->binaryOperators = $binaryOperators;
if ($env instanceof Twig_Environment) {
$this->env = $env;
$this->unaryOperators = $env->getUnaryOperators();
$this->binaryOperators = $env->getBinaryOperators();
} else {
@trigger_error('Passing the operators as constructor arguments to '.__METHOD__.' is deprecated since version 1.27. Pass the environment instead.', E_USER_DEPRECATED);
$this->env = $parser->getEnvironment();
$this->unaryOperators = func_get_arg(1);
$this->binaryOperators = func_get_arg(2);
}
}
public function parseExpression($precedence = 0)
@@ -44,7 +58,11 @@ class Twig_ExpressionParser
$op = $this->binaryOperators[$token->getValue()];
$this->parser->getStream()->next();
if (isset($op['callable'])) {
if ('is not' === $token->getValue()) {
$expr = $this->parseNotTestExpression($expr);
} elseif ('is' === $token->getValue()) {
$expr = $this->parseTestExpression($expr);
} elseif (isset($op['callable'])) {
$expr = call_user_func($op['callable'], $this->parser, $expr);
} else {
$expr1 = $this->parseExpression(self::OPERATOR_LEFT === $op['associativity'] ? $op['precedence'] + 1 : $op['precedence']);
@@ -171,7 +189,7 @@ class Twig_ExpressionParser
$negClass = 'Twig_Node_Expression_Unary_Neg';
$posClass = 'Twig_Node_Expression_Unary_Pos';
if (!(in_array($ref->getName(), array($negClass, $posClass)) || $ref->isSubclassOf($negClass) || $ref->isSubclassOf($posClass))) {
throw new Twig_Error_Syntax(sprintf('Unexpected unary operator "%s"', $token->getValue()), $token->getLine(), $this->parser->getFilename());
throw new Twig_Error_Syntax(sprintf('Unexpected unary operator "%s".', $token->getValue()), $token->getLine(), $this->parser->getStream()->getSourceContext());
}
$this->parser->getStream()->next();
@@ -187,7 +205,7 @@ class Twig_ExpressionParser
} elseif ($token->test(Twig_Token::PUNCTUATION_TYPE, '{')) {
$node = $this->parseHashExpression();
} else {
throw new Twig_Error_Syntax(sprintf('Unexpected token "%s" of value "%s"', Twig_Token::typeToEnglish($token->getType()), $token->getValue()), $token->getLine(), $this->parser->getFilename());
throw new Twig_Error_Syntax(sprintf('Unexpected token "%s" of value "%s".', Twig_Token::typeToEnglish($token->getType()), $token->getValue()), $token->getLine(), $this->parser->getStream()->getSourceContext());
}
}
@@ -216,7 +234,7 @@ class Twig_ExpressionParser
$expr = array_shift($nodes);
foreach ($nodes as $node) {
$expr = new Twig_Node_Expression_Binary_Concat($expr, $node, $node->getLine());
$expr = new Twig_Node_Expression_Binary_Concat($expr, $node, $node->getTemplateLine());
}
return $expr;
@@ -278,7 +296,7 @@ class Twig_ExpressionParser
} else {
$current = $stream->getCurrent();
throw new Twig_Error_Syntax(sprintf('A hash key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "%s" of value "%s"', Twig_Token::typeToEnglish($current->getType()), $current->getValue()), $current->getLine(), $this->parser->getFilename());
throw new Twig_Error_Syntax(sprintf('A hash key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "%s" of value "%s".', Twig_Token::typeToEnglish($current->getType()), $current->getValue()), $current->getLine(), $stream->getSourceContext());
}
$stream->expect(Twig_Token::PUNCTUATION_TYPE, ':', 'A hash key must be followed by a colon (:)');
@@ -317,20 +335,25 @@ class Twig_ExpressionParser
case 'parent':
$this->parseArguments();
if (!count($this->parser->getBlockStack())) {
throw new Twig_Error_Syntax('Calling "parent" outside a block is forbidden', $line, $this->parser->getFilename());
throw new Twig_Error_Syntax('Calling "parent" outside a block is forbidden.', $line, $this->parser->getStream()->getSourceContext());
}
if (!$this->parser->getParent() && !$this->parser->hasTraits()) {
throw new Twig_Error_Syntax('Calling "parent" on a template that does not extend nor "use" another template is forbidden', $line, $this->parser->getFilename());
throw new Twig_Error_Syntax('Calling "parent" on a template that does not extend nor "use" another template is forbidden.', $line, $this->parser->getStream()->getSourceContext());
}
return new Twig_Node_Expression_Parent($this->parser->peekBlockStack(), $line);
case 'block':
return new Twig_Node_Expression_BlockReference($this->parseArguments()->getNode(0), false, $line);
$args = $this->parseArguments();
if (count($args) < 1) {
throw new Twig_Error_Syntax('The "block" function takes one argument (the block name).', $line, $this->parser->getStream()->getSourceContext());
}
return new Twig_Node_Expression_BlockReference($args->getNode(0), count($args) > 1 ? $args->getNode(1) : null, $line);
case 'attribute':
$args = $this->parseArguments();
if (count($args) < 2) {
throw new Twig_Error_Syntax('The "attribute" function takes at least two arguments (the variable and the attributes)', $line, $this->parser->getFilename());
throw new Twig_Error_Syntax('The "attribute" function takes at least two arguments (the variable and the attributes).', $line, $this->parser->getStream()->getSourceContext());
}
return new Twig_Node_Expression_GetAttr($args->getNode(0), $args->getNode(1), count($args) > 2 ? $args->getNode(2) : null, Twig_Template::ANY_CALL, $line);
@@ -373,24 +396,24 @@ class Twig_ExpressionParser
$arg = new Twig_Node_Expression_Constant($token->getValue(), $lineno);
if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
$type = Twig_TemplateInterface::METHOD_CALL;
$type = Twig_Template::METHOD_CALL;
foreach ($this->parseArguments() as $n) {
$arguments->addElement($n);
}
}
} else {
throw new Twig_Error_Syntax('Expected name or number', $lineno, $this->parser->getFilename());
throw new Twig_Error_Syntax('Expected name or number.', $lineno, $stream->getSourceContext());
}
if ($node instanceof Twig_Node_Expression_Name && null !== $this->parser->getImportedSymbol('template', $node->getAttribute('name'))) {
if (!$arg instanceof Twig_Node_Expression_Constant) {
throw new Twig_Error_Syntax(sprintf('Dynamic macro names are not supported (called on "%s")', $node->getAttribute('name')), $token->getLine(), $this->parser->getFilename());
throw new Twig_Error_Syntax(sprintf('Dynamic macro names are not supported (called on "%s").', $node->getAttribute('name')), $token->getLine(), $stream->getSourceContext());
}
$name = $arg->getAttribute('value');
if ($this->parser->isReservedMacroName($name)) {
throw new Twig_Error_Syntax(sprintf('"%s" cannot be called as macro as it is a reserved keyword', $name), $token->getLine(), $this->parser->getFilename());
throw new Twig_Error_Syntax(sprintf('"%s" cannot be called as macro as it is a reserved keyword.', $name), $token->getLine(), $stream->getSourceContext());
}
$node = new Twig_Node_Expression_MethodCall($node, 'get'.$name, $arguments, $lineno);
@@ -500,7 +523,7 @@ class Twig_ExpressionParser
$name = null;
if ($namedArguments && $token = $stream->nextIf(Twig_Token::OPERATOR_TYPE, '=')) {
if (!$value instanceof Twig_Node_Expression_Name) {
throw new Twig_Error_Syntax(sprintf('A parameter name must be a string, "%s" given', get_class($value)), $token->getLine(), $this->parser->getFilename());
throw new Twig_Error_Syntax(sprintf('A parameter name must be a string, "%s" given.', get_class($value)), $token->getLine(), $stream->getSourceContext());
}
$name = $value->getAttribute('name');
@@ -508,7 +531,7 @@ class Twig_ExpressionParser
$value = $this->parsePrimaryExpression();
if (!$this->checkConstantExpression($value)) {
throw new Twig_Error_Syntax(sprintf('A default value for an argument must be a constant (a boolean, a string, a number, or an array).'), $token->getLine(), $this->parser->getFilename());
throw new Twig_Error_Syntax(sprintf('A default value for an argument must be a constant (a boolean, a string, a number, or an array).'), $token->getLine(), $stream->getSourceContext());
}
} else {
$value = $this->parseExpression();
@@ -536,15 +559,17 @@ class Twig_ExpressionParser
public function parseAssignmentExpression()
{
$stream = $this->parser->getStream();
$targets = array();
while (true) {
$token = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE, null, 'Only variables can be assigned to');
if (in_array($token->getValue(), array('true', 'false', 'none'))) {
throw new Twig_Error_Syntax(sprintf('You cannot assign a value to "%s"', $token->getValue()), $token->getLine(), $this->parser->getFilename());
$token = $stream->expect(Twig_Token::NAME_TYPE, null, 'Only variables can be assigned to');
$value = $token->getValue();
if (in_array(strtolower($value), array('true', 'false', 'none', 'null'))) {
throw new Twig_Error_Syntax(sprintf('You cannot assign a value to "%s".', $value), $token->getLine(), $stream->getSourceContext());
}
$targets[] = new Twig_Node_Expression_AssignName($token->getValue(), $token->getLine());
$targets[] = new Twig_Node_Expression_AssignName($value, $token->getLine());
if (!$this->parser->getStream()->nextIf(Twig_Token::PUNCTUATION_TYPE, ',')) {
if (!$stream->nextIf(Twig_Token::PUNCTUATION_TYPE, ',')) {
break;
}
}
@@ -565,17 +590,96 @@ class Twig_ExpressionParser
return new Twig_Node($targets);
}
protected function getFunctionNodeClass($name, $line)
private function parseNotTestExpression(Twig_NodeInterface $node)
{
$env = $this->parser->getEnvironment();
if (false === $function = $env->getFunction($name)) {
$message = sprintf('The function "%s" does not exist', $name);
if ($alternatives = $env->computeAlternatives($name, array_keys($env->getFunctions()))) {
$message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives));
return new Twig_Node_Expression_Unary_Not($this->parseTestExpression($node), $this->parser->getCurrentToken()->getLine());
}
throw new Twig_Error_Syntax($message, $line, $this->parser->getFilename());
private function parseTestExpression(Twig_NodeInterface $node)
{
$stream = $this->parser->getStream();
list($name, $test) = $this->getTest($node->getTemplateLine());
$class = $this->getTestNodeClass($test);
$arguments = null;
if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
$arguments = $this->parser->getExpressionParser()->parseArguments(true);
}
return new $class($node, $name, $arguments, $this->parser->getCurrentToken()->getLine());
}
private function getTest($line)
{
$stream = $this->parser->getStream();
$name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
if ($test = $this->env->getTest($name)) {
return array($name, $test);
}
if ($stream->test(Twig_Token::NAME_TYPE)) {
// try 2-words tests
$name = $name.' '.$this->parser->getCurrentToken()->getValue();
if ($test = $this->env->getTest($name)) {
$stream->next();
return array($name, $test);
}
}
$e = new Twig_Error_Syntax(sprintf('Unknown "%s" test.', $name), $line, $stream->getSourceContext());
$e->addSuggestions($name, array_keys($this->env->getTests()));
throw $e;
}
private function getTestNodeClass($test)
{
if ($test instanceof Twig_SimpleTest && $test->isDeprecated()) {
$stream = $this->parser->getStream();
$message = sprintf('Twig Test "%s" is deprecated', $test->getName());
if (!is_bool($test->getDeprecatedVersion())) {
$message .= sprintf(' since version %s', $test->getDeprecatedVersion());
}
if ($test->getAlternative()) {
$message .= sprintf('. Use "%s" instead', $test->getAlternative());
}
$src = $stream->getSourceContext();
$message .= sprintf(' in %s at line %d.', $src->getPath() ? $src->getPath() : $src->getName(), $stream->getCurrent()->getLine());
@trigger_error($message, E_USER_DEPRECATED);
}
if ($test instanceof Twig_SimpleTest) {
return $test->getNodeClass();
}
return $test instanceof Twig_Test_Node ? $test->getClass() : 'Twig_Node_Expression_Test';
}
protected function getFunctionNodeClass($name, $line)
{
if (false === $function = $this->env->getFunction($name)) {
$e = new Twig_Error_Syntax(sprintf('Unknown "%s" function.', $name), $line, $this->parser->getStream()->getSourceContext());
$e->addSuggestions($name, array_keys($this->env->getFunctions()));
throw $e;
}
if ($function instanceof Twig_SimpleFunction && $function->isDeprecated()) {
$message = sprintf('Twig Function "%s" is deprecated', $function->getName());
if (!is_bool($function->getDeprecatedVersion())) {
$message .= sprintf(' since version %s', $function->getDeprecatedVersion());
}
if ($function->getAlternative()) {
$message .= sprintf('. Use "%s" instead', $function->getAlternative());
}
$src = $this->parser->getStream()->getSourceContext();
$message .= sprintf(' in %s at line %d.', $src->getPath() ? $src->getPath() : $src->getName(), $line);
@trigger_error($message, E_USER_DEPRECATED);
}
if ($function instanceof Twig_SimpleFunction) {
@@ -587,15 +691,25 @@ class Twig_ExpressionParser
protected function getFilterNodeClass($name, $line)
{
$env = $this->parser->getEnvironment();
if (false === $filter = $this->env->getFilter($name)) {
$e = new Twig_Error_Syntax(sprintf('Unknown "%s" filter.', $name), $line, $this->parser->getStream()->getSourceContext());
$e->addSuggestions($name, array_keys($this->env->getFilters()));
if (false === $filter = $env->getFilter($name)) {
$message = sprintf('The filter "%s" does not exist', $name);
if ($alternatives = $env->computeAlternatives($name, array_keys($env->getFilters()))) {
$message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives));
throw $e;
}
throw new Twig_Error_Syntax($message, $line, $this->parser->getFilename());
if ($filter instanceof Twig_SimpleFilter && $filter->isDeprecated()) {
$message = sprintf('Twig Filter "%s" is deprecated', $filter->getName());
if (!is_bool($filter->getDeprecatedVersion())) {
$message .= sprintf(' since version %s', $filter->getDeprecatedVersion());
}
if ($filter->getAlternative()) {
$message .= sprintf('. Use "%s" instead', $filter->getAlternative());
}
$src = $this->parser->getStream()->getSourceContext();
$message .= sprintf(' in %s at line %d.', $src->getPath() ? $src->getPath() : $src->getName(), $line);
@trigger_error($message, E_USER_DEPRECATED);
}
if ($filter instanceof Twig_SimpleFilter) {
@@ -623,3 +737,5 @@ class Twig_ExpressionParser
return true;
}
}
class_alias('Twig_ExpressionParser', 'Twig\ExpressionParser', false);

View File

@@ -3,91 +3,67 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
abstract class Twig_Extension implements Twig_ExtensionInterface
{
/**
* Initializes the runtime environment.
*
* This is where you can load some file that contains filter functions for instance.
*
* @param Twig_Environment $environment The current Twig_Environment instance
* @deprecated since 1.23 (to be removed in 2.0), implement Twig_Extension_InitRuntimeInterface instead
*/
public function initRuntime(Twig_Environment $environment)
{
}
/**
* Returns the token parser instances to add to the existing list.
*
* @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances
*/
public function getTokenParsers()
{
return array();
}
/**
* Returns the node visitor instances to add to the existing list.
*
* @return Twig_NodeVisitorInterface[] An array of Twig_NodeVisitorInterface instances
*/
public function getNodeVisitors()
{
return array();
}
/**
* Returns a list of filters to add to the existing list.
*
* @return array An array of filters
*/
public function getFilters()
{
return array();
}
/**
* Returns a list of tests to add to the existing list.
*
* @return array An array of tests
*/
public function getTests()
{
return array();
}
/**
* Returns a list of functions to add to the existing list.
*
* @return array An array of functions
*/
public function getFunctions()
{
return array();
}
/**
* Returns a list of operators to add to the existing list.
*
* @return array An array of operators
*/
public function getOperators()
{
return array();
}
/**
* Returns a list of global variables to add to the existing list.
*
* @return array An array of global variables
* @deprecated since 1.23 (to be removed in 2.0), implement Twig_Extension_GlobalsInterface instead
*/
public function getGlobals()
{
return array();
}
/**
* @deprecated since 1.26 (to be removed in 2.0), not used anymore internally
*/
public function getName()
{
return get_class($this);
}
}
class_alias('Twig_Extension', 'Twig\Extension\AbstractExtension', false);
class_exists('Twig_Environment');

View File

@@ -1,18 +1,21 @@
<?php
if (!defined('ENT_SUBSTITUTE')) {
// use 0 as hhvm does not support several flags yet
define('ENT_SUBSTITUTE', 0);
define('ENT_SUBSTITUTE', 8);
}
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* @final
*/
class Twig_Extension_Core extends Twig_Extension
{
protected $dateFormats = array('F j, Y H:i', '%d days');
@@ -95,9 +98,9 @@ class Twig_Extension_Core extends Twig_Extension
/**
* Sets the default format to be used by the number_format filter.
*
* @param int $decimal The number of decimal places to use.
* @param string $decimalPoint The character(s) to use for the decimal point.
* @param string $thousandSep The character(s) to use for the thousands separator.
* @param int $decimal the number of decimal places to use
* @param string $decimalPoint the character(s) to use for the decimal point
* @param string $thousandSep the character(s) to use for the thousands separator
*/
public function setNumberFormat($decimal, $decimalPoint, $thousandSep)
{
@@ -114,11 +117,6 @@ class Twig_Extension_Core extends Twig_Extension
return $this->numberFormat;
}
/**
* Returns the token parser instance to add to the existing list.
*
* @return Twig_TokenParser[] An array of Twig_TokenParser instances
*/
public function getTokenParsers()
{
return array(
@@ -137,14 +135,10 @@ class Twig_Extension_Core extends Twig_Extension
new Twig_TokenParser_Flush(),
new Twig_TokenParser_Do(),
new Twig_TokenParser_Embed(),
new Twig_TokenParser_With(),
);
}
/**
* Returns a list of filters to add to the existing list.
*
* @return array An array of filters
*/
public function getFilters()
{
$filters = array(
@@ -152,7 +146,7 @@ class Twig_Extension_Core extends Twig_Extension
new Twig_SimpleFilter('date', 'twig_date_format_filter', array('needs_environment' => true)),
new Twig_SimpleFilter('date_modify', 'twig_date_modify_filter', array('needs_environment' => true)),
new Twig_SimpleFilter('format', 'sprintf'),
new Twig_SimpleFilter('replace', 'strtr'),
new Twig_SimpleFilter('replace', 'twig_replace_filter'),
new Twig_SimpleFilter('number_format', 'twig_number_format_filter', array('needs_environment' => true)),
new Twig_SimpleFilter('abs', 'abs'),
new Twig_SimpleFilter('round', 'twig_round'),
@@ -168,7 +162,7 @@ class Twig_Extension_Core extends Twig_Extension
new Twig_SimpleFilter('upper', 'strtoupper'),
new Twig_SimpleFilter('lower', 'strtolower'),
new Twig_SimpleFilter('striptags', 'strip_tags'),
new Twig_SimpleFilter('trim', 'trim'),
new Twig_SimpleFilter('trim', 'twig_trim_filter'),
new Twig_SimpleFilter('nl2br', 'nl2br', array('pre_escape' => 'html', 'is_safe' => array('html'))),
// array helpers
@@ -202,11 +196,6 @@ class Twig_Extension_Core extends Twig_Extension
return $filters;
}
/**
* Returns a list of global functions to add to the existing list.
*
* @return array An array of global functions
*/
public function getFunctions()
{
return array(
@@ -222,22 +211,17 @@ class Twig_Extension_Core extends Twig_Extension
);
}
/**
* Returns a list of tests to add to the existing list.
*
* @return array An array of tests
*/
public function getTests()
{
return array(
new Twig_SimpleTest('even', null, array('node_class' => 'Twig_Node_Expression_Test_Even')),
new Twig_SimpleTest('odd', null, array('node_class' => 'Twig_Node_Expression_Test_Odd')),
new Twig_SimpleTest('defined', null, array('node_class' => 'Twig_Node_Expression_Test_Defined')),
new Twig_SimpleTest('sameas', null, array('node_class' => 'Twig_Node_Expression_Test_Sameas')),
new Twig_SimpleTest('sameas', null, array('node_class' => 'Twig_Node_Expression_Test_Sameas', 'deprecated' => '1.21', 'alternative' => 'same as')),
new Twig_SimpleTest('same as', null, array('node_class' => 'Twig_Node_Expression_Test_Sameas')),
new Twig_SimpleTest('none', null, array('node_class' => 'Twig_Node_Expression_Test_Null')),
new Twig_SimpleTest('null', null, array('node_class' => 'Twig_Node_Expression_Test_Null')),
new Twig_SimpleTest('divisibleby', null, array('node_class' => 'Twig_Node_Expression_Test_Divisibleby')),
new Twig_SimpleTest('divisibleby', null, array('node_class' => 'Twig_Node_Expression_Test_Divisibleby', 'deprecated' => '1.21', 'alternative' => 'divisible by')),
new Twig_SimpleTest('divisible by', null, array('node_class' => 'Twig_Node_Expression_Test_Divisibleby')),
new Twig_SimpleTest('constant', null, array('node_class' => 'Twig_Node_Expression_Test_Constant')),
new Twig_SimpleTest('empty', 'twig_test_empty'),
@@ -245,11 +229,6 @@ class Twig_Extension_Core extends Twig_Extension
);
}
/**
* Returns a list of operators to add to the existing list.
*
* @return array An array of operators
*/
public function getOperators()
{
return array(
@@ -283,78 +262,14 @@ class Twig_Extension_Core extends Twig_Extension
'/' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Div', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
'//' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_FloorDiv', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
'%' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mod', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
'is' => array('precedence' => 100, 'callable' => array($this, 'parseTestExpression'), 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
'is not' => array('precedence' => 100, 'callable' => array($this, 'parseNotTestExpression'), 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
'is' => array('precedence' => 100, 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
'is not' => array('precedence' => 100, 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
'**' => array('precedence' => 200, 'class' => 'Twig_Node_Expression_Binary_Power', 'associativity' => Twig_ExpressionParser::OPERATOR_RIGHT),
'??' => array('precedence' => 300, 'class' => 'Twig_Node_Expression_NullCoalesce', 'associativity' => Twig_ExpressionParser::OPERATOR_RIGHT),
),
);
}
public function parseNotTestExpression(Twig_Parser $parser, Twig_NodeInterface $node)
{
return new Twig_Node_Expression_Unary_Not($this->parseTestExpression($parser, $node), $parser->getCurrentToken()->getLine());
}
public function parseTestExpression(Twig_Parser $parser, Twig_NodeInterface $node)
{
$stream = $parser->getStream();
$name = $this->getTestName($parser, $node->getLine());
$class = $this->getTestNodeClass($parser, $name);
$arguments = null;
if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
$arguments = $parser->getExpressionParser()->parseArguments(true);
}
return new $class($node, $name, $arguments, $parser->getCurrentToken()->getLine());
}
protected function getTestName(Twig_Parser $parser, $line)
{
$stream = $parser->getStream();
$name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
$env = $parser->getEnvironment();
$testMap = $env->getTests();
if (isset($testMap[$name])) {
return $name;
}
if ($stream->test(Twig_Token::NAME_TYPE)) {
// try 2-words tests
$name = $name.' '.$parser->getCurrentToken()->getValue();
if (isset($testMap[$name])) {
$parser->getStream()->next();
return $name;
}
}
$message = sprintf('The test "%s" does not exist', $name);
if ($alternatives = $env->computeAlternatives($name, array_keys($testMap))) {
$message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives));
}
throw new Twig_Error_Syntax($message, $line, $parser->getFilename());
}
protected function getTestNodeClass(Twig_Parser $parser, $name)
{
$env = $parser->getEnvironment();
$testMap = $env->getTests();
if ($testMap[$name] instanceof Twig_SimpleTest) {
return $testMap[$name]->getNodeClass();
}
return $testMap[$name] instanceof Twig_Test_Node ? $testMap[$name]->getClass() : 'Twig_Node_Expression_Test';
}
/**
* Returns the name of the extension.
*
* @return string The extension name
*/
public function getName()
{
return 'core';
@@ -364,7 +279,7 @@ class Twig_Extension_Core extends Twig_Extension
/**
* Cycles over a value.
*
* @param ArrayAccess|array $values An array or an ArrayAccess instance
* @param ArrayAccess|array $values
* @param int $position The cycle position
*
* @return string The next value in the cycle
@@ -384,10 +299,10 @@ function twig_cycle($values, $position)
* - a random character from a string
* - a random integer between 0 and the integer parameter.
*
* @param Twig_Environment $env A Twig_Environment instance
* @param Traversable|array|int|string $values The values to pick a random item from
* @param Twig_Environment $env
* @param Traversable|array|int|float|string $values The values to pick a random item from
*
* @throws Twig_Error_Runtime When $values is an empty array (does not apply to an empty string which is returned as is).
* @throws Twig_Error_Runtime when $values is an empty array (does not apply to an empty string which is returned as is)
*
* @return mixed A random value from the given sequence
*/
@@ -408,7 +323,7 @@ function twig_random(Twig_Environment $env, $values = null)
return '';
}
if (null !== $charset = $env->getCharset()) {
if ('UTF-8' != $charset) {
if ('UTF-8' !== $charset) {
$values = twig_convert_encoding($values, 'UTF-8', $charset);
}
@@ -416,7 +331,7 @@ function twig_random(Twig_Environment $env, $values = null)
// split at all positions, but not after the start and not before the end
$values = preg_split('/(?<!^)(?!$)/u', $values);
if ('UTF-8' != $charset) {
if ('UTF-8' !== $charset) {
foreach ($values as $i => $value) {
$values[$i] = twig_convert_encoding($value, $charset, 'UTF-8');
}
@@ -444,7 +359,7 @@ function twig_random(Twig_Environment $env, $values = null)
* {{ post.published_at|date("m/d/Y") }}
* </pre>
*
* @param Twig_Environment $env A Twig_Environment instance
* @param Twig_Environment $env
* @param DateTime|DateTimeInterface|DateInterval|string $date A date
* @param string|null $format The target format, null to use the default
* @param DateTimeZone|string|null|false $timezone The target timezone, null to use the default, false to leave unchanged
@@ -454,7 +369,7 @@ function twig_random(Twig_Environment $env, $values = null)
function twig_date_format_filter(Twig_Environment $env, $date, $format = null, $timezone = null)
{
if (null === $format) {
$formats = $env->getExtension('core')->getDateFormat();
$formats = $env->getExtension('Twig_Extension_Core')->getDateFormat();
$format = $date instanceof DateInterval ? $formats[1] : $formats[0];
}
@@ -472,7 +387,7 @@ function twig_date_format_filter(Twig_Environment $env, $date, $format = null, $
* {{ post.published_at|date_modify("-1day")|date("m/d/Y") }}
* </pre>
*
* @param Twig_Environment $env A Twig_Environment instance
* @param Twig_Environment $env
* @param DateTime|string $date A date
* @param string $modifier A modifier string
*
@@ -498,7 +413,7 @@ function twig_date_modify_filter(Twig_Environment $env, $date, $modifier)
* {% endif %}
* </pre>
*
* @param Twig_Environment $env A Twig_Environment instance
* @param Twig_Environment $env
* @param DateTime|DateTimeInterface|string|null $date A date
* @param DateTimeZone|string|null|false $timezone The target timezone, null to use the default, false to leave unchanged
*
@@ -509,7 +424,7 @@ function twig_date_converter(Twig_Environment $env, $date = null, $timezone = nu
// determine the timezone
if (false !== $timezone) {
if (null === $timezone) {
$timezone = $env->getExtension('core')->getTimezone();
$timezone = $env->getExtension('Twig_Extension_Core')->getTimezone();
} elseif (!$timezone instanceof DateTimeZone) {
$timezone = new DateTimeZone($timezone);
}
@@ -529,12 +444,17 @@ function twig_date_converter(Twig_Environment $env, $date = null, $timezone = nu
return $date;
}
$asString = (string) $date;
if (ctype_digit($asString) || (!empty($asString) && '-' === $asString[0] && ctype_digit(substr($asString, 1)))) {
$date = '@'.$date;
if (null === $date || 'now' === $date) {
return new DateTime($date, false !== $timezone ? $timezone : $env->getExtension('Twig_Extension_Core')->getTimezone());
}
$asString = (string) $date;
if (ctype_digit($asString) || (!empty($asString) && '-' === $asString[0] && ctype_digit(substr($asString, 1)))) {
$date = new DateTime('@'.$date);
} else {
$date = new DateTime($date, $env->getExtension('Twig_Extension_Core')->getTimezone());
}
$date = new DateTime($date, $env->getExtension('core')->getTimezone());
if (false !== $timezone) {
$date->setTimezone($timezone);
}
@@ -542,6 +462,30 @@ function twig_date_converter(Twig_Environment $env, $date = null, $timezone = nu
return $date;
}
/**
* Replaces strings within a string.
*
* @param string $str String to replace in
* @param array|Traversable $from Replace values
* @param string|null $to Replace to, deprecated (@see http://php.net/manual/en/function.strtr.php)
*
* @return string
*/
function twig_replace_filter($str, $from, $to = null)
{
if ($from instanceof Traversable) {
$from = iterator_to_array($from);
} elseif (is_string($from) && is_string($to)) {
@trigger_error('Using "replace" with character by character replacement is deprecated since version 1.22 and will be removed in Twig 2.0', E_USER_DEPRECATED);
return strtr($str, $from, $to);
} elseif (!is_array($from)) {
throw new Twig_Error_Runtime(sprintf('The "replace" filter expects an array or "Traversable" as replace values, got "%s".', is_object($from) ? get_class($from) : gettype($from)));
}
return strtr($str, $from);
}
/**
* Rounds a number.
*
@@ -571,17 +515,17 @@ function twig_round($value, $precision = 0, $method = 'common')
* be used. Supplying any of the parameters will override the defaults set in the
* environment object.
*
* @param Twig_Environment $env A Twig_Environment instance
* @param Twig_Environment $env
* @param mixed $number A float/int/string of the number to format
* @param int $decimal The number of decimal points to display.
* @param string $decimalPoint The character(s) to use for the decimal point.
* @param string $thousandSep The character(s) to use for the thousands separator.
* @param int $decimal the number of decimal points to display
* @param string $decimalPoint the character(s) to use for the decimal point
* @param string $thousandSep the character(s) to use for the thousands separator
*
* @return string The formatted number
*/
function twig_number_format_filter(Twig_Environment $env, $number, $decimal = null, $decimalPoint = null, $thousandSep = null)
{
$defaults = $env->getExtension('core')->getNumberFormat();
$defaults = $env->getExtension('Twig_Extension_Core')->getNumberFormat();
if (null === $decimal) {
$decimal = $defaults[0];
}
@@ -621,7 +565,7 @@ if (PHP_VERSION_ID < 50300) {
/**
* JSON encodes a variable.
*
* @param mixed $value The value to encode.
* @param mixed $value the value to encode
* @param int $options Not used on PHP 5.2.x
*
* @return mixed The JSON encoded value
@@ -640,7 +584,7 @@ if (PHP_VERSION_ID < 50300) {
/**
* JSON encodes a variable.
*
* @param mixed $value The value to encode.
* @param mixed $value the value to encode
* @param int $options Bitmask consisting of JSON_HEX_QUOT, JSON_HEX_TAG, JSON_HEX_AMP, JSON_HEX_APOS, JSON_NUMERIC_CHECK, JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, JSON_FORCE_OBJECT
*
* @return mixed The JSON encoded value
@@ -675,15 +619,23 @@ function _twig_markup2string(&$value)
* {# items now contains { 'apple': 'fruit', 'orange': 'fruit', 'peugeot': 'car' } #}
* </pre>
*
* @param array $arr1 An array
* @param array $arr2 An array
* @param array|Traversable $arr1 An array
* @param array|Traversable $arr2 An array
*
* @return array The merged array
*/
function twig_array_merge($arr1, $arr2)
{
if (!is_array($arr1) || !is_array($arr2)) {
throw new Twig_Error_Runtime(sprintf('The merge filter only works with arrays or hashes; %s and %s given.', gettype($arr1), gettype($arr2)));
if ($arr1 instanceof Traversable) {
$arr1 = iterator_to_array($arr1);
} elseif (!is_array($arr1)) {
throw new Twig_Error_Runtime(sprintf('The merge filter only works with arrays or "Traversable", got "%s" as first argument.', gettype($arr1)));
}
if ($arr2 instanceof Traversable) {
$arr2 = iterator_to_array($arr2);
} elseif (!is_array($arr2)) {
throw new Twig_Error_Runtime(sprintf('The merge filter only works with arrays or "Traversable", got "%s" as second argument.', gettype($arr2)));
}
return array_merge($arr1, $arr2);
@@ -692,7 +644,7 @@ function twig_array_merge($arr1, $arr2)
/**
* Slices a variable.
*
* @param Twig_Environment $env A Twig_Environment instance
* @param Twig_Environment $env
* @param mixed $item A variable
* @param int $start Start of the slice
* @param int $length Size of the slice
@@ -703,7 +655,7 @@ function twig_array_merge($arr1, $arr2)
function twig_slice(Twig_Environment $env, $item, $start, $length = null, $preserveKeys = false)
{
if ($item instanceof Traversable) {
if ($item instanceof IteratorAggregate) {
while ($item instanceof IteratorAggregate) {
$item = $item->getIterator();
}
@@ -734,7 +686,7 @@ function twig_slice(Twig_Environment $env, $item, $start, $length = null, $prese
/**
* Returns the first element of the item.
*
* @param Twig_Environment $env A Twig_Environment instance
* @param Twig_Environment $env
* @param mixed $item A variable
*
* @return mixed The first element of the item
@@ -749,7 +701,7 @@ function twig_first(Twig_Environment $env, $item)
/**
* Returns the last element of the item.
*
* @param Twig_Environment $env A Twig_Environment instance
* @param Twig_Environment $env
* @param mixed $item A variable
*
* @return mixed The last element of the item
@@ -805,6 +757,7 @@ function twig_join_filter($value, $glue = '')
* {# returns [aa, bb, cc] #}
* </pre>
*
* @param Twig_Environment $env
* @param string $value A string
* @param string $delimiter The delimiter
* @param int $limit The limit
@@ -841,6 +794,9 @@ function twig_split_filter(Twig_Environment $env, $value, $delimiter, $limit = n
// The '_default' filter is used internally to avoid using the ternary operator
// which costs a lot for big contexts (before PHP 5.4). So, on average,
// a function call is cheaper.
/**
* @internal
*/
function _twig_default_filter($value, $default = '')
{
if (twig_test_empty($value)) {
@@ -867,8 +823,28 @@ function _twig_default_filter($value, $default = '')
*/
function twig_get_array_keys_filter($array)
{
if (is_object($array) && $array instanceof Traversable) {
return array_keys(iterator_to_array($array));
if ($array instanceof Traversable) {
while ($array instanceof IteratorAggregate) {
$array = $array->getIterator();
}
if ($array instanceof Iterator) {
$keys = array();
$array->rewind();
while ($array->valid()) {
$keys[] = $array->key();
$array->next();
}
return $keys;
}
$keys = array();
foreach ($array as $key => $item) {
$keys[] = $key;
}
return $keys;
}
if (!is_array($array)) {
@@ -881,7 +857,7 @@ function twig_get_array_keys_filter($array)
/**
* Reverses a variable.
*
* @param Twig_Environment $env A Twig_Environment instance
* @param Twig_Environment $env
* @param array|Traversable|string $item An array, a Traversable instance, or a string
* @param bool $preserveKeys Whether to preserve key or not
*
@@ -889,7 +865,7 @@ function twig_get_array_keys_filter($array)
*/
function twig_reverse_filter(Twig_Environment $env, $item, $preserveKeys = false)
{
if (is_object($item) && $item instanceof Traversable) {
if ($item instanceof Traversable) {
return array_reverse(iterator_to_array($item), $preserveKeys);
}
@@ -900,7 +876,7 @@ function twig_reverse_filter(Twig_Environment $env, $item, $preserveKeys = false
if (null !== $charset = $env->getCharset()) {
$string = (string) $item;
if ('UTF-8' != $charset) {
if ('UTF-8' !== $charset) {
$item = twig_convert_encoding($string, 'UTF-8', $charset);
}
@@ -908,7 +884,7 @@ function twig_reverse_filter(Twig_Environment $env, $item, $preserveKeys = false
$string = implode('', array_reverse($matches[0]));
if ('UTF-8' != $charset) {
if ('UTF-8' !== $charset) {
$string = twig_convert_encoding($string, $charset, 'UTF-8');
}
@@ -921,18 +897,26 @@ function twig_reverse_filter(Twig_Environment $env, $item, $preserveKeys = false
/**
* Sorts an array.
*
* @param array $array
* @param array|Traversable $array
*
* @return array
*/
function twig_sort_filter($array)
{
if ($array instanceof Traversable) {
$array = iterator_to_array($array);
} elseif (!is_array($array)) {
throw new Twig_Error_Runtime(sprintf('The sort filter only works with arrays or "Traversable", got "%s".', gettype($array)));
}
asort($array);
return $array;
}
/* used internally */
/**
* @internal
*/
function twig_in_filter($value, $compare)
{
if (is_array($compare)) {
@@ -940,17 +924,56 @@ function twig_in_filter($value, $compare)
} elseif (is_string($compare) && (is_string($value) || is_int($value) || is_float($value))) {
return '' === $value || false !== strpos($compare, (string) $value);
} elseif ($compare instanceof Traversable) {
return in_array($value, iterator_to_array($compare, false), is_object($value) || is_resource($value));
if (is_object($value) || is_resource($value)) {
foreach ($compare as $item) {
if ($item === $value) {
return true;
}
}
} else {
foreach ($compare as $item) {
if ($item == $value) {
return true;
}
}
}
return false;
}
return false;
}
/**
* Returns a trimmed string.
*
* @return string
*
* @throws Twig_Error_Runtime When an invalid trimming side is used (not a string or not 'left', 'right', or 'both')
*/
function twig_trim_filter($string, $characterMask = null, $side = 'both')
{
if (null === $characterMask) {
$characterMask = " \t\n\r\0\x0B";
}
switch ($side) {
case 'both':
return trim($string, $characterMask);
case 'left':
return ltrim($string, $characterMask);
case 'right':
return rtrim($string, $characterMask);
default:
throw new Twig_Error_Runtime('Trimming side must be "left", "right" or "both".');
}
}
/**
* Escapes a string.
*
* @param Twig_Environment $env A Twig_Environment instance
* @param string $string The value to be escaped
* @param Twig_Environment $env
* @param mixed $string The value to be escaped
* @param string $strategy The escaping strategy
* @param string $charset The charset
* @param bool $autoescape Whether the function is called by the auto-escaping feature (true) or by the developer (false)
@@ -966,7 +989,7 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html',
if (!is_string($string)) {
if (is_object($string) && method_exists($string, '__toString')) {
$string = (string) $string;
} else {
} elseif (in_array($strategy, array('html', 'js', 'css', 'html_attr', 'url'))) {
return $string;
}
}
@@ -982,13 +1005,7 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html',
// Using a static variable to avoid initializing the array
// each time the function is called. Moving the declaration on the
// top of the function slow downs other escaping strategies.
static $htmlspecialcharsCharsets;
if (null === $htmlspecialcharsCharsets) {
if (defined('HHVM_VERSION')) {
$htmlspecialcharsCharsets = array('utf-8' => true, 'UTF-8' => true);
} else {
$htmlspecialcharsCharsets = array(
static $htmlspecialcharsCharsets = array(
'ISO-8859-1' => true, 'ISO8859-1' => true,
'ISO-8859-15' => true, 'ISO8859-15' => true,
'utf-8' => true, 'UTF-8' => true,
@@ -1004,8 +1021,6 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html',
'EUC-JP' => true, 'EUCJP' => true,
'ISO8859-5' => true, 'ISO-8859-5' => true, 'MACROMAN' => true,
);
}
}
if (isset($htmlspecialcharsCharsets[$charset])) {
return htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE, $charset);
@@ -1026,51 +1041,51 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html',
case 'js':
// escape all non-alphanumeric characters
// into their \xHH or \uHHHH representations
if ('UTF-8' != $charset) {
if ('UTF-8' !== $charset) {
$string = twig_convert_encoding($string, 'UTF-8', $charset);
}
if (0 == strlen($string) ? false : (1 == preg_match('/^./su', $string) ? false : true)) {
if (0 == strlen($string) ? false : 1 !== preg_match('/^./su', $string)) {
throw new Twig_Error_Runtime('The string to escape is not a valid UTF-8 string.');
}
$string = preg_replace_callback('#[^a-zA-Z0-9,\._]#Su', '_twig_escape_js_callback', $string);
if ('UTF-8' != $charset) {
if ('UTF-8' !== $charset) {
$string = twig_convert_encoding($string, $charset, 'UTF-8');
}
return $string;
case 'css':
if ('UTF-8' != $charset) {
if ('UTF-8' !== $charset) {
$string = twig_convert_encoding($string, 'UTF-8', $charset);
}
if (0 == strlen($string) ? false : (1 == preg_match('/^./su', $string) ? false : true)) {
if (0 == strlen($string) ? false : 1 !== preg_match('/^./su', $string)) {
throw new Twig_Error_Runtime('The string to escape is not a valid UTF-8 string.');
}
$string = preg_replace_callback('#[^a-zA-Z0-9]#Su', '_twig_escape_css_callback', $string);
if ('UTF-8' != $charset) {
if ('UTF-8' !== $charset) {
$string = twig_convert_encoding($string, $charset, 'UTF-8');
}
return $string;
case 'html_attr':
if ('UTF-8' != $charset) {
if ('UTF-8' !== $charset) {
$string = twig_convert_encoding($string, 'UTF-8', $charset);
}
if (0 == strlen($string) ? false : (1 == preg_match('/^./su', $string) ? false : true)) {
if (0 == strlen($string) ? false : 1 !== preg_match('/^./su', $string)) {
throw new Twig_Error_Runtime('The string to escape is not a valid UTF-8 string.');
}
$string = preg_replace_callback('#[^a-zA-Z0-9,\.\-_]#Su', '_twig_escape_html_attr_callback', $string);
if ('UTF-8' != $charset) {
if ('UTF-8' !== $charset) {
$string = twig_convert_encoding($string, $charset, 'UTF-8');
}
@@ -1087,7 +1102,7 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html',
static $escapers;
if (null === $escapers) {
$escapers = $env->getExtension('core')->getEscapers();
$escapers = $env->getExtension('Twig_Extension_Core')->getEscapers();
}
if (isset($escapers[$strategy])) {
@@ -1100,7 +1115,9 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html',
}
}
/* used internally */
/**
* @internal
*/
function twig_escape_filter_is_safe(Twig_Node $filterArgs)
{
foreach ($filterArgs as $arg) {
@@ -1142,8 +1159,13 @@ function _twig_escape_js_callback($matches)
// \uHHHH
$char = twig_convert_encoding($char, 'UTF-16BE', 'UTF-8');
$char = strtoupper(bin2hex($char));
return '\\u'.strtoupper(substr('0000'.bin2hex($char), -4));
if (4 >= strlen($char)) {
return sprintf('\u%04s', $char);
}
return sprintf('\u%04s\u%04s', substr($char, 0, -4), substr($char, -4));
}
function _twig_escape_css_callback($matches)
@@ -1226,27 +1248,43 @@ if (function_exists('mb_get_info')) {
/**
* Returns the length of a variable.
*
* @param Twig_Environment $env A Twig_Environment instance
* @param Twig_Environment $env
* @param mixed $thing A variable
*
* @return int The length of the value
*/
function twig_length_filter(Twig_Environment $env, $thing)
{
return is_scalar($thing) ? mb_strlen($thing, $env->getCharset()) : count($thing);
if (null === $thing) {
return 0;
}
if (is_scalar($thing)) {
return mb_strlen($thing, $env->getCharset());
}
if (is_object($thing) && method_exists($thing, '__toString') && !$thing instanceof \Countable) {
return mb_strlen((string) $thing, $env->getCharset());
}
if ($thing instanceof \Countable || is_array($thing)) {
return count($thing);
}
return 1;
}
/**
* Converts a string to uppercase.
*
* @param Twig_Environment $env A Twig_Environment instance
* @param Twig_Environment $env
* @param string $string A string
*
* @return string The uppercased string
*/
function twig_upper_filter(Twig_Environment $env, $string)
{
if (null !== ($charset = $env->getCharset())) {
if (null !== $charset = $env->getCharset()) {
return mb_strtoupper($string, $charset);
}
@@ -1256,14 +1294,14 @@ if (function_exists('mb_get_info')) {
/**
* Converts a string to lowercase.
*
* @param Twig_Environment $env A Twig_Environment instance
* @param Twig_Environment $env
* @param string $string A string
*
* @return string The lowercased string
*/
function twig_lower_filter(Twig_Environment $env, $string)
{
if (null !== ($charset = $env->getCharset())) {
if (null !== $charset = $env->getCharset()) {
return mb_strtolower($string, $charset);
}
@@ -1273,14 +1311,14 @@ if (function_exists('mb_get_info')) {
/**
* Returns a titlecased string.
*
* @param Twig_Environment $env A Twig_Environment instance
* @param Twig_Environment $env
* @param string $string A string
*
* @return string The titlecased string
*/
function twig_title_string_filter(Twig_Environment $env, $string)
{
if (null !== ($charset = $env->getCharset())) {
if (null !== $charset = $env->getCharset()) {
return mb_convert_case($string, MB_CASE_TITLE, $charset);
}
@@ -1290,16 +1328,15 @@ if (function_exists('mb_get_info')) {
/**
* Returns a capitalized string.
*
* @param Twig_Environment $env A Twig_Environment instance
* @param Twig_Environment $env
* @param string $string A string
*
* @return string The capitalized string
*/
function twig_capitalize_string_filter(Twig_Environment $env, $string)
{
if (null !== ($charset = $env->getCharset())) {
return mb_strtoupper(mb_substr($string, 0, 1, $charset), $charset).
mb_strtolower(mb_substr($string, 1, mb_strlen($string, $charset), $charset), $charset);
if (null !== $charset = $env->getCharset()) {
return mb_strtoupper(mb_substr($string, 0, 1, $charset), $charset).mb_strtolower(mb_substr($string, 1, mb_strlen($string, $charset), $charset), $charset);
}
return ucfirst(strtolower($string));
@@ -1310,20 +1347,36 @@ else {
/**
* Returns the length of a variable.
*
* @param Twig_Environment $env A Twig_Environment instance
* @param Twig_Environment $env
* @param mixed $thing A variable
*
* @return int The length of the value
*/
function twig_length_filter(Twig_Environment $env, $thing)
{
return is_scalar($thing) ? strlen($thing) : count($thing);
if (null === $thing) {
return 0;
}
if (is_scalar($thing)) {
return strlen($thing);
}
if (is_object($thing) && method_exists($thing, '__toString') && !$thing instanceof \Countable) {
return strlen((string) $thing);
}
if ($thing instanceof \Countable || is_array($thing)) {
return count($thing);
}
return 1;
}
/**
* Returns a titlecased string.
*
* @param Twig_Environment $env A Twig_Environment instance
* @param Twig_Environment $env
* @param string $string A string
*
* @return string The titlecased string
@@ -1336,7 +1389,7 @@ else {
/**
* Returns a capitalized string.
*
* @param Twig_Environment $env A Twig_Environment instance
* @param Twig_Environment $env
* @param string $string A string
*
* @return string The capitalized string
@@ -1347,7 +1400,9 @@ else {
}
}
/* used internally */
/**
* @internal
*/
function twig_ensure_traversable($seq)
{
if ($seq instanceof Traversable || is_array($seq)) {
@@ -1377,6 +1432,10 @@ function twig_test_empty($value)
return 0 == count($value);
}
if (is_object($value) && method_exists($value, '__toString')) {
return '' === (string) $value;
}
return '' === $value || false === $value || null === $value || array() === $value;
}
@@ -1420,8 +1479,8 @@ function twig_include(Twig_Environment $env, $context, $template, $variables = a
$variables = array_merge($context, $variables);
}
if ($isSandboxed = $sandboxed && $env->hasExtension('sandbox')) {
$sandbox = $env->getExtension('sandbox');
if ($isSandboxed = $sandboxed && $env->hasExtension('Twig_Extension_Sandbox')) {
$sandbox = $env->getExtension('Twig_Extension_Sandbox');
if (!$alreadySandboxed = $sandbox->isSandboxed()) {
$sandbox->enableSandbox();
}
@@ -1438,6 +1497,18 @@ function twig_include(Twig_Environment $env, $context, $template, $variables = a
throw $e;
}
} catch (Throwable $e) {
if ($isSandboxed && !$alreadySandboxed) {
$sandbox->disableSandbox();
}
throw $e;
} catch (Exception $e) {
if ($isSandboxed && !$alreadySandboxed) {
$sandbox->disableSandbox();
}
throw $e;
}
if ($isSandboxed && !$alreadySandboxed) {
@@ -1450,6 +1521,7 @@ function twig_include(Twig_Environment $env, $context, $template, $variables = a
/**
* Returns a template content without rendering it.
*
* @param Twig_Environment $env
* @param string $name The template name
* @param bool $ignoreMissing Whether to ignore missing templates or not
*
@@ -1457,8 +1529,13 @@ function twig_include(Twig_Environment $env, $context, $template, $variables = a
*/
function twig_source(Twig_Environment $env, $name, $ignoreMissing = false)
{
$loader = $env->getLoader();
try {
return $env->getLoader()->getSource($name);
if (!$loader instanceof Twig_SourceContextLoaderInterface) {
return $loader->getSource($name);
} else {
return $loader->getSourceContext($name)->getCode();
}
} catch (Twig_Error_Loader $e) {
if (!$ignoreMissing) {
throw $e;
@@ -1483,6 +1560,23 @@ function twig_constant($constant, $object = null)
return constant($constant);
}
/**
* Checks if a constant exists.
*
* @param string $constant The name of the constant
* @param null|object $object The object to get the constant from
*
* @return bool
*/
function twig_constant_is_defined($constant, $object = null)
{
if (null !== $object) {
$constant = get_class($object).'::'.$constant;
}
return defined($constant);
}
/**
* Batches item.
*
@@ -1514,3 +1608,5 @@ function twig_array_batch($items, $size, $fill = null)
return $result;
}
class_alias('Twig_Extension_Core', 'Twig\Extension\CoreExtension', false);

View File

@@ -3,18 +3,17 @@
/*
* This file is part of Twig.
*
* (c) 2011 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* @final
*/
class Twig_Extension_Debug extends Twig_Extension
{
/**
* Returns a list of global functions to add to the existing list.
*
* @return array An array of global functions
*/
public function getFunctions()
{
// dump is safe if var_dump is overridden by xdebug
@@ -24,7 +23,7 @@ class Twig_Extension_Debug extends Twig_Extension
// false means that it was not set (and the default is on) or it explicitly enabled
// xdebug.overload_var_dump produces HTML only when html_errors is also enabled
&& (false === ini_get('html_errors') || ini_get('html_errors'))
|| 'cli' === php_sapi_name()
|| 'cli' === PHP_SAPI
;
return array(
@@ -32,11 +31,6 @@ class Twig_Extension_Debug extends Twig_Extension
);
}
/**
* Returns the name of the extension.
*
* @return string The extension name
*/
public function getName()
{
return 'debug';
@@ -69,3 +63,5 @@ function twig_var_dump(Twig_Environment $env, $context)
return ob_get_clean();
}
class_alias('Twig_Extension_Debug', 'Twig\Extension\DebugExtension', false);

View File

@@ -3,45 +3,39 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* @final
*/
class Twig_Extension_Escaper extends Twig_Extension
{
protected $defaultStrategy;
/**
* @param string|false|callable $defaultStrategy An escaping strategy
*
* @see setDefaultStrategy()
*/
public function __construct($defaultStrategy = 'html')
{
$this->setDefaultStrategy($defaultStrategy);
}
/**
* Returns the token parser instances to add to the existing list.
*
* @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances
*/
public function getTokenParsers()
{
return array(new Twig_TokenParser_AutoEscape());
}
/**
* Returns the node visitor instances to add to the existing list.
*
* @return Twig_NodeVisitorInterface[] An array of Twig_NodeVisitorInterface instances
*/
public function getNodeVisitors()
{
return array(new Twig_NodeVisitor_Escaper());
}
/**
* Returns a list of filters to add to the existing list.
*
* @return array An array of filters
*/
public function getFilters()
{
return array(
@@ -53,18 +47,26 @@ class Twig_Extension_Escaper extends Twig_Extension
* Sets the default strategy to use when not defined by the user.
*
* The strategy can be a valid PHP callback that takes the template
* "filename" as an argument and returns the strategy to use.
* name as an argument and returns the strategy to use.
*
* @param mixed $defaultStrategy An escaping strategy
* @param string|false|callable $defaultStrategy An escaping strategy
*/
public function setDefaultStrategy($defaultStrategy)
{
// for BC
if (true === $defaultStrategy) {
@trigger_error('Using "true" as the default strategy is deprecated since version 1.21. Use "html" instead.', E_USER_DEPRECATED);
$defaultStrategy = 'html';
}
if ('filename' === $defaultStrategy) {
@trigger_error('Using "filename" as the default strategy is deprecated since version 1.27. Use "name" instead.', E_USER_DEPRECATED);
$defaultStrategy = 'name';
}
if ('name' === $defaultStrategy) {
$defaultStrategy = array('Twig_FileExtensionEscapingStrategy', 'guess');
}
@@ -74,26 +76,21 @@ class Twig_Extension_Escaper extends Twig_Extension
/**
* Gets the default strategy to use when not defined by the user.
*
* @param string $filename The template "filename"
* @param string $name The template name
*
* @return string The default strategy to use for the template
* @return string|false The default strategy to use for the template
*/
public function getDefaultStrategy($filename)
public function getDefaultStrategy($name)
{
// disable string callables to avoid calling a function named html or js,
// or any other upcoming escaping strategy
if (!is_string($this->defaultStrategy) && is_callable($this->defaultStrategy)) {
return call_user_func($this->defaultStrategy, $filename);
if (!is_string($this->defaultStrategy) && false !== $this->defaultStrategy) {
return call_user_func($this->defaultStrategy, $name);
}
return $this->defaultStrategy;
}
/**
* Returns the name of the extension.
*
* @return string The extension name
*/
public function getName()
{
return 'escaper';
@@ -111,3 +108,5 @@ function twig_raw_filter($string)
{
return $string;
}
class_alias('Twig_Extension_Escaper', 'Twig\Extension\EscaperExtension', false);

View File

@@ -0,0 +1,24 @@
<?php
/*
* This file is part of Twig.
*
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* Enables usage of the deprecated Twig_Extension::getGlobals() method.
*
* Explicitly implement this interface if you really need to implement the
* deprecated getGlobals() method in your extensions.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
interface Twig_Extension_GlobalsInterface
{
}
class_alias('Twig_Extension_GlobalsInterface', 'Twig\Extension\GlobalsInterface', false);

View File

@@ -0,0 +1,24 @@
<?php
/*
* This file is part of Twig.
*
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* Enables usage of the deprecated Twig_Extension::initRuntime() method.
*
* Explicitly implement this interface if you really need to implement the
* deprecated initRuntime() method in your extensions.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
interface Twig_Extension_InitRuntimeInterface
{
}
class_alias('Twig_Extension_InitRuntimeInterface', 'Twig\Extension\InitRuntimeInterface', false);

View File

@@ -3,11 +3,15 @@
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* @final
*/
class Twig_Extension_Optimizer extends Twig_Extension
{
protected $optimizers;
@@ -17,19 +21,15 @@ class Twig_Extension_Optimizer extends Twig_Extension
$this->optimizers = $optimizers;
}
/**
* {@inheritdoc}
*/
public function getNodeVisitors()
{
return array(new Twig_NodeVisitor_Optimizer($this->optimizers));
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'optimizer';
}
}
class_alias('Twig_Extension_Optimizer', 'Twig\Extension\OptimizerExtension', false);

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2015 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -11,11 +11,11 @@
class Twig_Extension_Profiler extends Twig_Extension
{
private $actives;
private $actives = array();
public function __construct(Twig_Profiler_Profile $profile)
{
$this->actives = array($profile);
$this->actives[] = $profile;
}
public function enter(Twig_Profiler_Profile $profile)
@@ -34,19 +34,16 @@ class Twig_Extension_Profiler extends Twig_Extension
}
}
/**
* {@inheritdoc}
*/
public function getNodeVisitors()
{
return array(new Twig_Profiler_NodeVisitor_Profiler($this->getName()));
return array(new Twig_Profiler_NodeVisitor_Profiler(get_class($this)));
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'profiler';
}
}
class_alias('Twig_Extension_Profiler', 'Twig\Extension\ProfilerExtension', false);
class_exists('Twig_Profiler_Profile');

View File

@@ -3,11 +3,15 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* @final
*/
class Twig_Extension_Sandbox extends Twig_Extension
{
protected $sandboxedGlobally;
@@ -20,21 +24,11 @@ class Twig_Extension_Sandbox extends Twig_Extension
$this->sandboxedGlobally = $sandboxed;
}
/**
* Returns the token parser instances to add to the existing list.
*
* @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances
*/
public function getTokenParsers()
{
return array(new Twig_TokenParser_Sandbox());
}
/**
* Returns the node visitor instances to add to the existing list.
*
* @return Twig_NodeVisitorInterface[] An array of Twig_NodeVisitorInterface instances
*/
public function getNodeVisitors()
{
return array(new Twig_NodeVisitor_Sandbox());
@@ -100,13 +94,10 @@ class Twig_Extension_Sandbox extends Twig_Extension
return $obj;
}
/**
* Returns the name of the extension.
*
* @return string The extension name
*/
public function getName()
{
return 'sandbox';
}
}
class_alias('Twig_Extension_Sandbox', 'Twig\Extension\SandboxExtension', false);

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2012 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -15,6 +15,8 @@
* This class is used by Twig_Environment as a staging area and must not be used directly.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @internal
*/
class Twig_Extension_Staging extends Twig_Extension
{
@@ -27,12 +29,13 @@ class Twig_Extension_Staging extends Twig_Extension
public function addFunction($name, $function)
{
if (isset($this->functions[$name])) {
@trigger_error(sprintf('Overriding function "%s" that is already registered is deprecated since version 1.30 and won\'t be possible anymore in 2.0.', $name), E_USER_DEPRECATED);
}
$this->functions[$name] = $function;
}
/**
* {@inheritdoc}
*/
public function getFunctions()
{
return $this->functions;
@@ -40,12 +43,13 @@ class Twig_Extension_Staging extends Twig_Extension
public function addFilter($name, $filter)
{
if (isset($this->filters[$name])) {
@trigger_error(sprintf('Overriding filter "%s" that is already registered is deprecated since version 1.30 and won\'t be possible anymore in 2.0.', $name), E_USER_DEPRECATED);
}
$this->filters[$name] = $filter;
}
/**
* {@inheritdoc}
*/
public function getFilters()
{
return $this->filters;
@@ -56,9 +60,6 @@ class Twig_Extension_Staging extends Twig_Extension
$this->visitors[] = $visitor;
}
/**
* {@inheritdoc}
*/
public function getNodeVisitors()
{
return $this->visitors;
@@ -66,12 +67,13 @@ class Twig_Extension_Staging extends Twig_Extension
public function addTokenParser(Twig_TokenParserInterface $parser)
{
$this->tokenParsers[] = $parser;
if (isset($this->tokenParsers[$parser->getTag()])) {
@trigger_error(sprintf('Overriding tag "%s" that is already registered is deprecated since version 1.30 and won\'t be possible anymore in 2.0.', $parser->getTag()), E_USER_DEPRECATED);
}
$this->tokenParsers[$parser->getTag()] = $parser;
}
/**
* {@inheritdoc}
*/
public function getTokenParsers()
{
return $this->tokenParsers;
@@ -82,9 +84,6 @@ class Twig_Extension_Staging extends Twig_Extension
$this->globals[$name] = $value;
}
/**
* {@inheritdoc}
*/
public function getGlobals()
{
return $this->globals;
@@ -92,22 +91,22 @@ class Twig_Extension_Staging extends Twig_Extension
public function addTest($name, $test)
{
if (isset($this->tests[$name])) {
@trigger_error(sprintf('Overriding test "%s" that is already registered is deprecated since version 1.30 and won\'t be possible anymore in 2.0.', $name), E_USER_DEPRECATED);
}
$this->tests[$name] = $test;
}
/**
* {@inheritdoc}
*/
public function getTests()
{
return $this->tests;
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'staging';
}
}
class_alias('Twig_Extension_Staging', 'Twig\Extension\StagingExtension', false);

View File

@@ -3,16 +3,17 @@
/*
* This file is part of Twig.
*
* (c) 2012 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* @final
*/
class Twig_Extension_StringLoader extends Twig_Extension
{
/**
* {@inheritdoc}
*/
public function getFunctions()
{
return array(
@@ -20,9 +21,6 @@ class Twig_Extension_StringLoader extends Twig_Extension
);
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'string_loader';
@@ -37,11 +35,13 @@ class Twig_Extension_StringLoader extends Twig_Extension
* </pre>
*
* @param Twig_Environment $env A Twig_Environment instance
* @param string $template A template as a string
* @param string $template A template as a string or object implementing __toString()
*
* @return Twig_Template A Twig_Template instance
* @return Twig_Template
*/
function twig_template_from_string(Twig_Environment $env, $template)
{
return $env->createTemplate($template);
return $env->createTemplate((string) $template);
}
class_alias('Twig_Extension_StringLoader', 'Twig\Extension\StringLoaderExtension', false);

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -21,49 +21,49 @@ interface Twig_ExtensionInterface
*
* This is where you can load some file that contains filter functions for instance.
*
* @param Twig_Environment $environment The current Twig_Environment instance
* @deprecated since 1.23 (to be removed in 2.0), implement Twig_Extension_InitRuntimeInterface instead
*/
public function initRuntime(Twig_Environment $environment);
/**
* Returns the token parser instances to add to the existing list.
*
* @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances
* @return Twig_TokenParserInterface[]
*/
public function getTokenParsers();
/**
* Returns the node visitor instances to add to the existing list.
*
* @return Twig_NodeVisitorInterface[] An array of Twig_NodeVisitorInterface instances
* @return Twig_NodeVisitorInterface[]
*/
public function getNodeVisitors();
/**
* Returns a list of filters to add to the existing list.
*
* @return array An array of filters
* @return Twig_SimpleFilter[]
*/
public function getFilters();
/**
* Returns a list of tests to add to the existing list.
*
* @return array An array of tests
* @return Twig_SimpleTest[]
*/
public function getTests();
/**
* Returns a list of functions to add to the existing list.
*
* @return array An array of functions
* @return Twig_SimpleFunction[]
*/
public function getFunctions();
/**
* Returns a list of operators to add to the existing list.
*
* @return array An array of operators
* @return array<array> First array of unary operators, second array of binary operators
*/
public function getOperators();
@@ -71,6 +71,8 @@ interface Twig_ExtensionInterface
* Returns a list of global variables to add to the existing list.
*
* @return array An array of global variables
*
* @deprecated since 1.23 (to be removed in 2.0), implement Twig_Extension_GlobalsInterface instead
*/
public function getGlobals();
@@ -78,6 +80,11 @@ interface Twig_ExtensionInterface
* Returns the name of the extension.
*
* @return string The extension name
*
* @deprecated since 1.26 (to be removed in 2.0), not used anymore internally
*/
public function getName();
}
class_alias('Twig_ExtensionInterface', 'Twig\Extension\ExtensionInterface', false);
class_exists('Twig_Environment');

View File

@@ -0,0 +1,39 @@
<?php
/*
* This file is part of Twig.
*
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* Lazy loads the runtime implementations for a Twig element.
*
* @author Robin Chalas <robin.chalas@gmail.com>
*/
class Twig_FactoryRuntimeLoader implements Twig_RuntimeLoaderInterface
{
private $map;
/**
* @param array $map An array where keys are class names and values factory callables
*/
public function __construct($map = array())
{
$this->map = $map;
}
public function load($class)
{
if (isset($this->map[$class])) {
$runtimeFactory = $this->map[$class];
return $runtimeFactory();
}
}
}
class_alias('Twig_FactoryRuntimeLoader', 'Twig\RuntimeLoader\FactoryRuntimeLoader', false);

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2015 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -13,7 +13,7 @@
* Default autoescaping strategy based on file names.
*
* This strategy sets the HTML as the default autoescaping strategy,
* but changes it based on the filename.
* but changes it based on the template name.
*
* Note that there is no runtime performance impact as the
* default autoescaping strategy is set at compilation time.
@@ -25,17 +25,23 @@ class Twig_FileExtensionEscapingStrategy
/**
* Guesses the best autoescaping strategy based on the file name.
*
* @param string $filename The template file name
* @param string $name The template name
*
* @return string The escaping strategy name to use
* @return string|false The escaping strategy name to use or false to disable
*/
public static function guess($filename)
public static function guess($name)
{
if (!preg_match('{\.(js|css|txt)(?:\.[^/\\\\]+)?$}', $filename, $match)) {
return 'html';
if (in_array(substr($name, -1), array('/', '\\'))) {
return 'html'; // return html for directories
}
switch ($match[1]) {
if ('.twig' === substr($name, -5)) {
$name = substr($name, 0, -5);
}
$extension = pathinfo($name, PATHINFO_EXTENSION);
switch ($extension) {
case 'js':
return 'js';
@@ -44,6 +50,11 @@ class Twig_FileExtensionEscapingStrategy
case 'txt':
return false;
default:
return 'html';
}
}
}
class_alias('Twig_FileExtensionEscapingStrategy', 'Twig\FileExtensionEscapingStrategy', false);

View File

@@ -3,12 +3,14 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
@trigger_error('The Twig_Filter class is deprecated since version 1.12 and will be removed in 2.0. Use Twig_SimpleFilter instead.', E_USER_DEPRECATED);
/**
* Represents a template filter.
*

View File

@@ -3,12 +3,14 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
@trigger_error('The Twig_Filter_Function class is deprecated since version 1.12 and will be removed in 2.0. Use Twig_SimpleFilter instead.', E_USER_DEPRECATED);
/**
* Represents a function template filter.
*

View File

@@ -3,12 +3,14 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
@trigger_error('The Twig_Filter_Method class is deprecated since version 1.12 and will be removed in 2.0. Use Twig_SimpleFilter instead.', E_USER_DEPRECATED);
/**
* Represents a method template filter.
*
@@ -35,6 +37,6 @@ class Twig_Filter_Method extends Twig_Filter
public function compile()
{
return sprintf('$this->env->getExtension(\'%s\')->%s', $this->extension->getName(), $this->method);
return sprintf('$this->env->getExtension(\'%s\')->%s', get_class($this->extension), $this->method);
}
}

View File

@@ -3,12 +3,14 @@
/*
* This file is part of Twig.
*
* (c) 2011 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
@trigger_error('The Twig_Filter_Node class is deprecated since version 1.12 and will be removed in 2.0. Use Twig_SimpleFilter instead.', E_USER_DEPRECATED);
/**
* Represents a template filter as a node.
*

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2012 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.

View File

@@ -3,12 +3,14 @@
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
@trigger_error('The Twig_Function class is deprecated since version 1.12 and will be removed in 2.0. Use Twig_SimpleFunction instead.', E_USER_DEPRECATED);
/**
* Represents a template function.
*

View File

@@ -3,13 +3,15 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2010 Arnaud Le Blanc
* (c) Fabien Potencier
* (c) Arnaud Le Blanc
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
@trigger_error('The Twig_Function_Function class is deprecated since version 1.12 and will be removed in 2.0. Use Twig_SimpleFunction instead.', E_USER_DEPRECATED);
/**
* Represents a function template function.
*

View File

@@ -3,13 +3,15 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2010 Arnaud Le Blanc
* (c) Fabien Potencier
* (c) Arnaud Le Blanc
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
@trigger_error('The Twig_Function_Method class is deprecated since version 1.12 and will be removed in 2.0. Use Twig_SimpleFunction instead.', E_USER_DEPRECATED);
/**
* Represents a method template function.
*
@@ -36,6 +38,6 @@ class Twig_Function_Method extends Twig_Function
public function compile()
{
return sprintf('$this->env->getExtension(\'%s\')->%s', $this->extension->getName(), $this->method);
return sprintf('$this->env->getExtension(\'%s\')->%s', get_class($this->extension), $this->method);
}
}

View File

@@ -3,12 +3,14 @@
/*
* This file is part of Twig.
*
* (c) 2011 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
@trigger_error('The Twig_Function_Node class is deprecated since version 1.12 and will be removed in 2.0. Use Twig_SimpleFunction instead.', E_USER_DEPRECATED);
/**
* Represents a template function as a node.
*

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2012 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.

View File

@@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
* (c) 2010 Arnaud Le Blanc
* (c) Fabien Potencier
* (c) Arnaud Le Blanc
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.

View File

@@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -26,6 +26,7 @@ class Twig_Lexer implements Twig_LexerInterface
protected $states;
protected $brackets;
protected $env;
// to be renamed to $name in 2.0 (where it is private)
protected $filename;
protected $options;
protected $regexes;
@@ -33,6 +34,8 @@ class Twig_Lexer implements Twig_LexerInterface
protected $positions;
protected $currentVarBlockLine;
private $source;
const STATE_DATA = 0;
const STATE_BLOCK = 1;
const STATE_VAR = 2;
@@ -72,11 +75,19 @@ class Twig_Lexer implements Twig_LexerInterface
);
}
/**
* {@inheritdoc}
*/
public function tokenize($code, $filename = null)
public function tokenize($code, $name = null)
{
if (!$code instanceof Twig_Source) {
@trigger_error(sprintf('Passing a string as the $code argument of %s() is deprecated since version 1.27 and will be removed in 2.0. Pass a Twig_Source instance instead.', __METHOD__), E_USER_DEPRECATED);
$this->source = new Twig_Source($code, $name);
} else {
$this->source = $code;
}
if (((int) ini_get('mbstring.func_overload')) & 2) {
@trigger_error('Support for having "mbstring.func_overload" different from 0 is deprecated version 1.29 and will be removed in 2.0.', E_USER_DEPRECATED);
}
if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
$mbEncoding = mb_internal_encoding();
mb_internal_encoding('ASCII');
@@ -84,8 +95,8 @@ class Twig_Lexer implements Twig_LexerInterface
$mbEncoding = null;
}
$this->code = str_replace(array("\r\n", "\r"), "\n", $code);
$this->filename = $filename;
$this->code = str_replace(array("\r\n", "\r"), "\n", $this->source->getCode());
$this->filename = $this->source->getName();
$this->cursor = 0;
$this->lineno = 1;
$this->end = strlen($this->code);
@@ -129,14 +140,14 @@ class Twig_Lexer implements Twig_LexerInterface
if (!empty($this->brackets)) {
list($expect, $lineno) = array_pop($this->brackets);
throw new Twig_Error_Syntax(sprintf('Unclosed "%s"', $expect), $lineno, $this->filename);
throw new Twig_Error_Syntax(sprintf('Unclosed "%s".', $expect), $lineno, $this->source);
}
if ($mbEncoding) {
mb_internal_encoding($mbEncoding);
}
return new Twig_TokenStream($this->tokens, $this->filename);
return new Twig_TokenStream($this->tokens, $this->source);
}
protected function lexData()
@@ -224,7 +235,7 @@ class Twig_Lexer implements Twig_LexerInterface
$this->moveCursor($match[0]);
if ($this->cursor >= $this->end) {
throw new Twig_Error_Syntax(sprintf('Unclosed "%s"', $this->state === self::STATE_BLOCK ? 'block' : 'variable'), $this->currentVarBlockLine, $this->filename);
throw new Twig_Error_Syntax(sprintf('Unclosed "%s".', $this->state === self::STATE_BLOCK ? 'block' : 'variable'), $this->currentVarBlockLine, $this->source);
}
}
@@ -256,12 +267,12 @@ class Twig_Lexer implements Twig_LexerInterface
// closing bracket
elseif (false !== strpos(')]}', $this->code[$this->cursor])) {
if (empty($this->brackets)) {
throw new Twig_Error_Syntax(sprintf('Unexpected "%s"', $this->code[$this->cursor]), $this->lineno, $this->filename);
throw new Twig_Error_Syntax(sprintf('Unexpected "%s".', $this->code[$this->cursor]), $this->lineno, $this->source);
}
list($expect, $lineno) = array_pop($this->brackets);
if ($this->code[$this->cursor] != strtr($expect, '([{', ')]}')) {
throw new Twig_Error_Syntax(sprintf('Unclosed "%s"', $expect), $lineno, $this->filename);
throw new Twig_Error_Syntax(sprintf('Unclosed "%s".', $expect), $lineno, $this->source);
}
}
@@ -281,14 +292,18 @@ class Twig_Lexer implements Twig_LexerInterface
}
// unlexable
else {
throw new Twig_Error_Syntax(sprintf('Unexpected character "%s"', $this->code[$this->cursor]), $this->lineno, $this->filename);
throw new Twig_Error_Syntax(sprintf('Unexpected character "%s".', $this->code[$this->cursor]), $this->lineno, $this->source);
}
}
protected function lexRawData($tag)
{
if ('raw' === $tag) {
@trigger_error(sprintf('Twig Tag "raw" is deprecated since version 1.21. Use "verbatim" instead in %s at line %d.', $this->filename, $this->lineno), E_USER_DEPRECATED);
}
if (!preg_match(str_replace('%s', $tag, $this->regexes['lex_raw_data']), $this->code, $match, PREG_OFFSET_CAPTURE, $this->cursor)) {
throw new Twig_Error_Syntax(sprintf('Unexpected end of file: Unclosed "%s" block', $tag), $this->lineno, $this->filename);
throw new Twig_Error_Syntax(sprintf('Unexpected end of file: Unclosed "%s" block.', $tag), $this->lineno, $this->source);
}
$text = substr($this->code, $this->cursor, $match[0][1] - $this->cursor);
@@ -304,7 +319,7 @@ class Twig_Lexer implements Twig_LexerInterface
protected function lexComment()
{
if (!preg_match($this->regexes['lex_comment'], $this->code, $match, PREG_OFFSET_CAPTURE, $this->cursor)) {
throw new Twig_Error_Syntax('Unclosed comment', $this->lineno, $this->filename);
throw new Twig_Error_Syntax('Unclosed comment.', $this->lineno, $this->source);
}
$this->moveCursor(substr($this->code, $this->cursor, $match[0][1] - $this->cursor).$match[0][0]);
@@ -323,7 +338,7 @@ class Twig_Lexer implements Twig_LexerInterface
} elseif (preg_match(self::REGEX_DQ_STRING_DELIM, $this->code, $match, null, $this->cursor)) {
list($expect, $lineno) = array_pop($this->brackets);
if ($this->code[$this->cursor] != '"') {
throw new Twig_Error_Syntax(sprintf('Unclosed "%s"', $expect), $lineno, $this->filename);
throw new Twig_Error_Syntax(sprintf('Unclosed "%s".', $expect), $lineno, $this->source);
}
$this->popState();
@@ -399,9 +414,11 @@ class Twig_Lexer implements Twig_LexerInterface
protected function popState()
{
if (0 === count($this->states)) {
throw new Exception('Cannot pop state without a previous state');
throw new Exception('Cannot pop state without a previous state.');
}
$this->state = array_pop($this->states);
}
}
class_alias('Twig_Lexer', 'Twig\Lexer', false);

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -21,12 +21,12 @@ interface Twig_LexerInterface
/**
* Tokenizes a source code.
*
* @param string $code The source code
* @param string $filename A unique identifier for the source code
* @param string|Twig_Source $code The source code
* @param string $name A unique identifier for the source code
*
* @return Twig_TokenStream A token stream instance
* @return Twig_TokenStream
*
* @throws Twig_Error_Syntax When the code is syntactically wrong
*/
public function tokenize($code, $filename = null);
public function tokenize($code, $name = null);
}

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -19,20 +19,18 @@
*
* This loader should only be used for unit testing.
*
* @final
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterface, Twig_SourceContextLoaderInterface
{
protected $templates = array();
/**
* Constructor.
*
* @param array $templates An array of templates (keys are the names, and values are the source code)
*
* @see Twig_Loader
*/
public function __construct(array $templates)
public function __construct(array $templates = array())
{
$this->templates = $templates;
}
@@ -48,11 +46,10 @@ class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
$this->templates[(string) $name] = $template;
}
/**
* {@inheritdoc}
*/
public function getSource($name)
{
@trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', get_class($this)), E_USER_DEPRECATED);
$name = (string) $name;
if (!isset($this->templates[$name])) {
throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name));
@@ -61,17 +58,21 @@ class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
return $this->templates[$name];
}
/**
* {@inheritdoc}
*/
public function getSourceContext($name)
{
$name = (string) $name;
if (!isset($this->templates[$name])) {
throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name));
}
return new Twig_Source($this->templates[$name], $name);
}
public function exists($name)
{
return isset($this->templates[(string) $name]);
}
/**
* {@inheritdoc}
*/
public function getCacheKey($name)
{
$name = (string) $name;
@@ -79,12 +80,9 @@ class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name));
}
return $this->templates[$name];
return $name.':'.$this->templates[$name];
}
/**
* {@inheritdoc}
*/
public function isFresh($name, $time)
{
$name = (string) $name;
@@ -95,3 +93,5 @@ class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
return true;
}
}
class_alias('Twig_Loader_Array', 'Twig\Loader\ArrayLoader', false);

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2011 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -12,17 +12,17 @@
/**
* Loads templates from other loaders.
*
* @final
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterface, Twig_SourceContextLoaderInterface
{
private $hasSourceCache = array();
protected $loaders = array();
/**
* Constructor.
*
* @param Twig_LoaderInterface[] $loaders An array of loader instances
* @param Twig_LoaderInterface[] $loaders
*/
public function __construct(array $loaders = array())
{
@@ -31,22 +31,16 @@ class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
}
}
/**
* Adds a loader instance.
*
* @param Twig_LoaderInterface $loader A Loader instance
*/
public function addLoader(Twig_LoaderInterface $loader)
{
$this->loaders[] = $loader;
$this->hasSourceCache = array();
}
/**
* {@inheritdoc}
*/
public function getSource($name)
{
@trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', get_class($this)), E_USER_DEPRECATED);
$exceptions = array();
foreach ($this->loaders as $loader) {
if ($loader instanceof Twig_ExistsLoaderInterface && !$loader->exists($name)) {
@@ -60,12 +54,31 @@ class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
}
}
throw new Twig_Error_Loader(sprintf('Template "%s" is not defined (%s).', $name, implode(', ', $exceptions)));
throw new Twig_Error_Loader(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : ''));
}
public function getSourceContext($name)
{
$exceptions = array();
foreach ($this->loaders as $loader) {
if ($loader instanceof Twig_ExistsLoaderInterface && !$loader->exists($name)) {
continue;
}
try {
if ($loader instanceof Twig_SourceContextLoaderInterface) {
return $loader->getSourceContext($name);
}
return new Twig_Source($loader->getSource($name), $name);
} catch (Twig_Error_Loader $e) {
$exceptions[] = $e->getMessage();
}
}
throw new Twig_Error_Loader(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : ''));
}
/**
* {@inheritdoc}
*/
public function exists($name)
{
$name = (string) $name;
@@ -84,7 +97,11 @@ class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
}
try {
if ($loader instanceof Twig_SourceContextLoaderInterface) {
$loader->getSourceContext($name);
} else {
$loader->getSource($name);
}
return $this->hasSourceCache[$name] = true;
} catch (Twig_Error_Loader $e) {
@@ -94,9 +111,6 @@ class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
return $this->hasSourceCache[$name] = false;
}
/**
* {@inheritdoc}
*/
public function getCacheKey($name)
{
$exceptions = array();
@@ -112,12 +126,9 @@ class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
}
}
throw new Twig_Error_Loader(sprintf('Template "%s" is not defined (%s).', $name, implode(' ', $exceptions)));
throw new Twig_Error_Loader(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : ''));
}
/**
* {@inheritdoc}
*/
public function isFresh($name, $time)
{
$exceptions = array();
@@ -133,6 +144,8 @@ class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
}
}
throw new Twig_Error_Loader(sprintf('Template "%s" is not defined (%s).', $name, implode(' ', $exceptions)));
throw new Twig_Error_Loader(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : ''));
}
}
class_alias('Twig_Loader_Chain', 'Twig\Loader\ChainLoader', false);

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -14,21 +14,28 @@
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderInterface, Twig_SourceContextLoaderInterface
{
/** Identifier of the main namespace. */
const MAIN_NAMESPACE = '__main__';
protected $paths = array();
protected $cache = array();
protected $errorCache = array();
private $rootPath;
/**
* Constructor.
*
* @param string|array $paths A path or an array of paths where to look for templates
* @param string|null $rootPath The root path common to all relative paths (null for getcwd())
*/
public function __construct($paths = array())
public function __construct($paths = array(), $rootPath = null)
{
$this->rootPath = (null === $rootPath ? getcwd() : $rootPath).DIRECTORY_SEPARATOR;
if (false !== $realPath = realpath($rootPath)) {
$this->rootPath = $realPath.DIRECTORY_SEPARATOR;
}
if ($paths) {
$this->setPaths($paths);
}
@@ -80,17 +87,18 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
* Adds a path where templates are stored.
*
* @param string $path A path where to look for templates
* @param string $namespace A path name
* @param string $namespace A path namespace
*
* @throws Twig_Error_Loader
*/
public function addPath($path, $namespace = self::MAIN_NAMESPACE)
{
// invalidate the cache
$this->cache = array();
$this->cache = $this->errorCache = array();
if (!is_dir($path)) {
throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path));
$checkPath = $this->isAbsolutePath($path) ? $path : $this->rootPath.$path;
if (!is_dir($checkPath)) {
throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist ("%s").', $path, $checkPath));
}
$this->paths[$namespace][] = rtrim($path, '/\\');
@@ -100,17 +108,18 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
* Prepends a path where templates are stored.
*
* @param string $path A path where to look for templates
* @param string $namespace A path name
* @param string $namespace A path namespace
*
* @throws Twig_Error_Loader
*/
public function prependPath($path, $namespace = self::MAIN_NAMESPACE)
{
// invalidate the cache
$this->cache = array();
$this->cache = $this->errorCache = array();
if (!is_dir($path)) {
throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path));
$checkPath = $this->isAbsolutePath($path) ? $path : $this->rootPath.$path;
if (!is_dir($checkPath)) {
throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist ("%s").', $path, $checkPath));
}
$path = rtrim($path, '/\\');
@@ -122,25 +131,31 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
}
}
/**
* {@inheritdoc}
*/
public function getSource($name)
{
@trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', get_class($this)), E_USER_DEPRECATED);
return file_get_contents($this->findTemplate($name));
}
/**
* {@inheritdoc}
*/
public function getCacheKey($name)
public function getSourceContext($name)
{
return $this->findTemplate($name);
$path = $this->findTemplate($name);
return new Twig_Source(file_get_contents($path), $name, $path);
}
public function getCacheKey($name)
{
$path = $this->findTemplate($name);
$len = strlen($this->rootPath);
if (0 === strncmp($this->rootPath, $path, $len)) {
return substr($path, $len);
}
return $path;
}
/**
* {@inheritdoc}
*/
public function exists($name)
{
$name = $this->normalizeName($name);
@@ -150,17 +165,14 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
}
try {
$this->findTemplate($name);
return true;
return false !== $this->findTemplate($name, false);
} catch (Twig_Error_Loader $exception) {
@trigger_error(sprintf('In %s::findTemplate(), you must accept a second argument that when set to "false" returns "false" instead of throwing an exception. Not supporting this argument is deprecated since version 1.27.', get_class($this)), E_USER_DEPRECATED);
return false;
}
}
/**
* {@inheritdoc}
*/
public function isFresh($name, $time)
{
return filemtime($this->findTemplate($name)) <= $time;
@@ -168,21 +180,40 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
protected function findTemplate($name)
{
$throw = func_num_args() > 1 ? func_get_arg(1) : true;
$name = $this->normalizeName($name);
if (isset($this->cache[$name])) {
return $this->cache[$name];
}
if (isset($this->errorCache[$name])) {
if (!$throw) {
return false;
}
throw new Twig_Error_Loader($this->errorCache[$name]);
}
$this->validateName($name);
list($namespace, $shortname) = $this->parseName($name);
if (!isset($this->paths[$namespace])) {
throw new Twig_Error_Loader(sprintf('There are no registered paths for namespace "%s".', $namespace));
$this->errorCache[$name] = sprintf('There are no registered paths for namespace "%s".', $namespace);
if (!$throw) {
return false;
}
throw new Twig_Error_Loader($this->errorCache[$name]);
}
foreach ($this->paths[$namespace] as $path) {
if (!$this->isAbsolutePath($path)) {
$path = $this->rootPath.'/'.$path;
}
if (is_file($path.'/'.$shortname)) {
if (false !== $realpath = realpath($path.'/'.$shortname)) {
return $this->cache[$name] = $realpath;
@@ -192,7 +223,13 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
}
}
throw new Twig_Error_Loader(sprintf('Unable to find template "%s" (looked into: %s).', $name, implode(', ', $this->paths[$namespace])));
$this->errorCache[$name] = sprintf('Unable to find template "%s" (looked into: %s).', $name, implode(', ', $this->paths[$namespace]));
if (!$throw) {
return false;
}
throw new Twig_Error_Loader($this->errorCache[$name]);
}
protected function parseName($name, $default = self::MAIN_NAMESPACE)
@@ -213,7 +250,7 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
protected function normalizeName($name)
{
return preg_replace('#/{2,}#', '/', strtr((string) $name, '\\', '/'));
return preg_replace('#/{2,}#', '/', str_replace('\\', '/', (string) $name));
}
protected function validateName($name)
@@ -237,4 +274,17 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
}
}
}
private function isAbsolutePath($file)
{
return strspn($file, '/\\', 0, 1)
|| (strlen($file) > 3 && ctype_alpha($file[0])
&& substr($file, 1, 1) === ':'
&& strspn($file, '/\\', 2, 1)
)
|| null !== parse_url($file, PHP_URL_SCHEME)
;
}
}
class_alias('Twig_Loader_Filesystem', 'Twig\Loader\FilesystemLoader', false);

View File

@@ -3,12 +3,14 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
@trigger_error('The Twig_Loader_String class is deprecated since version 1.18.1 and will be removed in 2.0. Use Twig_Loader_Array instead or Twig_Environment::createTemplate().', E_USER_DEPRECATED);
/**
* Loads a template from a string.
*
@@ -21,37 +23,34 @@
*
* @deprecated since 1.18.1 (to be removed in 2.0)
*
* @internal
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class Twig_Loader_String implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
class Twig_Loader_String implements Twig_LoaderInterface, Twig_ExistsLoaderInterface, Twig_SourceContextLoaderInterface
{
/**
* {@inheritdoc}
*/
public function getSource($name)
{
@trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', get_class($this)), E_USER_DEPRECATED);
return $name;
}
/**
* {@inheritdoc}
*/
public function getSourceContext($name)
{
return new Twig_Source($name, $name);
}
public function exists($name)
{
return true;
}
/**
* {@inheritdoc}
*/
public function getCacheKey($name)
{
return $name;
}
/**
* {@inheritdoc}
*/
public function isFresh($name, $time)
{
return true;

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -24,6 +24,8 @@ interface Twig_LoaderInterface
* @return string The template source code
*
* @throws Twig_Error_Loader When $name is not found
*
* @deprecated since 1.27 (to be removed in 2.0), implement Twig_SourceContextLoaderInterface
*/
public function getSource($name);
@@ -51,3 +53,5 @@ interface Twig_LoaderInterface
*/
public function isFresh($name, $time);
}
class_alias('Twig_LoaderInterface', 'Twig\Loader\LoaderInterface', false);

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -35,3 +35,5 @@ class Twig_Markup implements Countable
return function_exists('mb_get_info') ? mb_strlen($this->content, $this->charset) : strlen($this->content);
}
}
class_alias('Twig_Markup', 'Twig\Markup', false);

View File

@@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -22,6 +22,8 @@ class Twig_Node implements Twig_NodeInterface
protected $lineno;
protected $tag;
private $name;
/**
* Constructor.
*
@@ -35,6 +37,11 @@ class Twig_Node implements Twig_NodeInterface
*/
public function __construct(array $nodes = array(), array $attributes = array(), $lineno = 0, $tag = null)
{
foreach ($nodes as $name => $node) {
if (!$node instanceof Twig_NodeInterface) {
@trigger_error(sprintf('Using "%s" for the value of node "%s" of "%s" is deprecated since version 1.25 and will be removed in 2.0.', is_object($node) ? get_class($node) : null === $node ? 'null' : gettype($node), $name, get_class($this)), E_USER_DEPRECATED);
}
}
$this->nodes = $nodes;
$this->attributes = $attributes;
$this->lineno = $lineno;
@@ -74,6 +81,8 @@ class Twig_Node implements Twig_NodeInterface
*/
public function toXml($asDom = false)
{
@trigger_error(sprintf('%s is deprecated since version 1.16.1 and will be removed in 2.0.', __METHOD__), E_USER_DEPRECATED);
$dom = new DOMDocument('1.0', 'UTF-8');
$dom->formatOutput = true;
$dom->appendChild($xml = $dom->createElement('twig'));
@@ -99,7 +108,7 @@ class Twig_Node implements Twig_NodeInterface
$node->appendChild($child);
}
return $asDom ? $dom : $dom->saveXml();
return $asDom ? $dom : $dom->saveXML();
}
public function compile(Twig_Compiler $compiler)
@@ -109,8 +118,18 @@ class Twig_Node implements Twig_NodeInterface
}
}
public function getTemplateLine()
{
return $this->lineno;
}
/**
* @deprecated since 1.27 (to be removed in 2.0)
*/
public function getLine()
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getTemplateLine() instead.', E_USER_DEPRECATED);
return $this->lineno;
}
@@ -120,11 +139,7 @@ class Twig_Node implements Twig_NodeInterface
}
/**
* Returns true if the attribute is defined.
*
* @param string $name The attribute name
*
* @return bool true if the attribute is defined, false otherwise
* @return bool
*/
public function hasAttribute($name)
{
@@ -132,10 +147,6 @@ class Twig_Node implements Twig_NodeInterface
}
/**
* Gets an attribute value by name.
*
* @param string $name
*
* @return mixed
*/
public function getAttribute($name)
@@ -148,8 +159,6 @@ class Twig_Node implements Twig_NodeInterface
}
/**
* Sets an attribute by name to a value.
*
* @param string $name
* @param mixed $value
*/
@@ -158,21 +167,12 @@ class Twig_Node implements Twig_NodeInterface
$this->attributes[$name] = $value;
}
/**
* Removes an attribute by name.
*
* @param string $name
*/
public function removeAttribute($name)
{
unset($this->attributes[$name]);
}
/**
* Returns true if the node with the given name exists.
*
* @param string $name
*
* @return bool
*/
public function hasNode($name)
@@ -181,10 +181,6 @@ class Twig_Node implements Twig_NodeInterface
}
/**
* Gets a node by name.
*
* @param string $name
*
* @return Twig_Node
*/
public function getNode($name)
@@ -196,22 +192,15 @@ class Twig_Node implements Twig_NodeInterface
return $this->nodes[$name];
}
/**
* Sets a node.
*
* @param string $name
* @param Twig_Node $node
*/
public function setNode($name, $node = null)
{
if (!$node instanceof Twig_NodeInterface) {
@trigger_error(sprintf('Using "%s" for the value of node "%s" of "%s" is deprecated since version 1.25 and will be removed in 2.0.', is_object($node) ? get_class($node) : null === $node ? 'null' : gettype($node), $name, get_class($this)), E_USER_DEPRECATED);
}
$this->nodes[$name] = $node;
}
/**
* Removes a node by name.
*
* @param string $name
*/
public function removeNode($name)
{
unset($this->nodes[$name]);
@@ -226,4 +215,42 @@ class Twig_Node implements Twig_NodeInterface
{
return new ArrayIterator($this->nodes);
}
public function setTemplateName($name)
{
$this->name = $name;
foreach ($this->nodes as $node) {
if (null !== $node) {
$node->setTemplateName($name);
}
}
}
public function getTemplateName()
{
return $this->name;
}
/**
* @deprecated since 1.27 (to be removed in 2.0)
*/
public function setFilename($name)
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use setTemplateName() instead.', E_USER_DEPRECATED);
$this->setTemplateName($name);
}
/**
* @deprecated since 1.27 (to be removed in 2.0)
*/
public function getFilename()
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getTemplateName() instead.', E_USER_DEPRECATED);
return $this->name;
}
}
class_alias('Twig_Node', 'Twig\Node\Node', false);
class_exists('Twig_Compiler');

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -27,13 +27,10 @@ class Twig_Node_AutoEscape extends Twig_Node
parent::__construct(array('body' => $body), array('value' => $value), $lineno, $tag);
}
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler $compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$compiler->subcompile($this->getNode('body'));
}
}
class_alias('Twig_Node_AutoEscape', 'Twig\Node\AutoEscapeNode', false);

View File

@@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -22,11 +22,6 @@ class Twig_Node_Block extends Twig_Node
parent::__construct(array('body' => $body), array('name' => $name), $lineno, $tag);
}
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler $compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$compiler
@@ -42,3 +37,5 @@ class Twig_Node_Block extends Twig_Node
;
}
}
class_alias('Twig_Node_Block', 'Twig\Node\BlockNode', false);

View File

@@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -22,11 +22,6 @@ class Twig_Node_BlockReference extends Twig_Node implements Twig_NodeOutputInter
parent::__construct(array(), array('name' => $name), $lineno, $tag);
}
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler $compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$compiler
@@ -35,3 +30,5 @@ class Twig_Node_BlockReference extends Twig_Node implements Twig_NodeOutputInter
;
}
}
class_alias('Twig_Node_BlockReference', 'Twig\Node\BlockReferenceNode', false);

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2011 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -17,3 +17,5 @@
class Twig_Node_Body extends Twig_Node
{
}
class_alias('Twig_Node_Body', 'Twig\Node\BodyNode', false);

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2015 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -33,7 +33,7 @@ class Twig_Node_CheckSecurity extends Twig_Node
foreach (array('tags', 'filters', 'functions') as $type) {
foreach ($this->{'used'.ucfirst($type)} as $name => $node) {
if ($node instanceof Twig_Node) {
${$type}[$name] = $node->getLine();
${$type}[$name] = $node->getTemplateLine();
} else {
${$type}[$node] = null;
}
@@ -46,7 +46,7 @@ class Twig_Node_CheckSecurity extends Twig_Node
->write('$functions = ')->repr(array_filter($functions))->raw(";\n\n")
->write("try {\n")
->indent()
->write("\$this->env->getExtension('sandbox')->checkSecurity(\n")
->write("\$this->env->getExtension('Twig_Extension_Sandbox')->checkSecurity(\n")
->indent()
->write(!$tags ? "array(),\n" : "array('".implode("', '", array_keys($tags))."'),\n")
->write(!$filters ? "array(),\n" : "array('".implode("', '", array_keys($filters))."'),\n")
@@ -56,7 +56,7 @@ class Twig_Node_CheckSecurity extends Twig_Node
->outdent()
->write("} catch (Twig_Sandbox_SecurityError \$e) {\n")
->indent()
->write("\$e->setTemplateFile(\$this->getTemplateName());\n\n")
->write("\$e->setSourceContext(\$this->getSourceContext());\n\n")
->write("if (\$e instanceof Twig_Sandbox_SecurityNotAllowedTagError && isset(\$tags[\$e->getTagName()])) {\n")
->indent()
->write("\$e->setTemplateLine(\$tags[\$e->getTagName()]);\n")
@@ -76,3 +76,5 @@ class Twig_Node_CheckSecurity extends Twig_Node
;
}
}
class_alias('Twig_Node_CheckSecurity', 'Twig\Node\CheckSecurityNode', false);

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2011 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -21,11 +21,6 @@ class Twig_Node_Do extends Twig_Node
parent::__construct(array('expr' => $expr), array(), $lineno, $tag);
}
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler $compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$compiler
@@ -36,3 +31,5 @@ class Twig_Node_Do extends Twig_Node
;
}
}
class_alias('Twig_Node_Do', 'Twig\Node\DoNode', false);

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2012 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -17,11 +17,13 @@
class Twig_Node_Embed extends Twig_Node_Include
{
// we don't inject the module to avoid node visitors to traverse it twice (as it will be already visited in the main module)
public function __construct($filename, $index, Twig_Node_Expression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null)
public function __construct($name, $index, Twig_Node_Expression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null)
{
parent::__construct(new Twig_Node_Expression_Constant('not_used', $lineno), $variables, $only, $ignoreMissing, $lineno, $tag);
$this->setAttribute('filename', $filename);
$this->setAttribute('name', $name);
// to be removed in 2.0, used name instead
$this->setAttribute('filename', $name);
$this->setAttribute('index', $index);
}
@@ -29,14 +31,16 @@ class Twig_Node_Embed extends Twig_Node_Include
{
$compiler
->write('$this->loadTemplate(')
->string($this->getAttribute('filename'))
->string($this->getAttribute('name'))
->raw(', ')
->repr($compiler->getFilename())
->repr($this->getTemplateName())
->raw(', ')
->repr($this->getLine())
->repr($this->getTemplateLine())
->raw(', ')
->string($this->getAttribute('index'))
->raw(')')
;
}
}
class_alias('Twig_Node_Embed', 'Twig\Node\EmbedNode', false);

View File

@@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -18,3 +18,5 @@
abstract class Twig_Node_Expression extends Twig_Node
{
}
class_alias('Twig_Node_Expression', 'Twig\Node\Expression\AbstractExpression', false);

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -43,7 +43,7 @@ class Twig_Node_Expression_Array extends Twig_Node_Expression
foreach ($this->getKeyValuePairs() as $pair) {
// we compare the string representation of the keys
// to avoid comparing the line numbers which are not relevant here.
if ((string) $key == (string) $pair['key']) {
if ((string) $key === (string) $pair['key']) {
return true;
}
}
@@ -54,17 +54,12 @@ class Twig_Node_Expression_Array extends Twig_Node_Expression
public function addElement(Twig_Node_Expression $value, Twig_Node_Expression $key = null)
{
if (null === $key) {
$key = new Twig_Node_Expression_Constant(++$this->index, $value->getLine());
$key = new Twig_Node_Expression_Constant(++$this->index, $value->getTemplateLine());
}
array_push($this->nodes, $key, $value);
}
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler $compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$compiler->raw('array(');
@@ -84,3 +79,5 @@ class Twig_Node_Expression_Array extends Twig_Node_Expression
$compiler->raw(')');
}
}
class_alias('Twig_Node_Expression_Array', 'Twig\Node\Expression\ArrayExpression', false);

View File

@@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -12,11 +12,6 @@
class Twig_Node_Expression_AssignName extends Twig_Node_Expression_Name
{
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler $compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$compiler
@@ -26,3 +21,5 @@ class Twig_Node_Expression_AssignName extends Twig_Node_Expression_Name
;
}
}
class_alias('Twig_Node_Expression_AssignName', 'Twig\Node\Expression\AssignNameExpression', false);

View File

@@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -16,11 +16,6 @@ abstract class Twig_Node_Expression_Binary extends Twig_Node_Expression
parent::__construct(array('left' => $left, 'right' => $right), array(), $lineno);
}
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler $compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$compiler
@@ -38,3 +33,5 @@ abstract class Twig_Node_Expression_Binary extends Twig_Node_Expression
abstract public function operator(Twig_Compiler $compiler);
}
class_alias('Twig_Node_Expression_Binary', 'Twig\Node\Expression\Binary\AbstractBinary', false);

View File

@@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_Add extends Twig_Node_Expression_Binary
return $compiler->raw('+');
}
}
class_alias('Twig_Node_Expression_Binary_Add', 'Twig\Node\Expression\Binary\AddBinary', false);

View File

@@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_And extends Twig_Node_Expression_Binary
return $compiler->raw('&&');
}
}
class_alias('Twig_Node_Expression_Binary_And', 'Twig\Node\Expression\Binary\AndBinary', false);

View File

@@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_BitwiseAnd extends Twig_Node_Expression_Binary
return $compiler->raw('&');
}
}
class_alias('Twig_Node_Expression_Binary_BitwiseAnd', 'Twig\Node\Expression\Binary\BitwiseAndBinary', false);

View File

@@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_BitwiseOr extends Twig_Node_Expression_Binary
return $compiler->raw('|');
}
}
class_alias('Twig_Node_Expression_Binary_BitwiseOr', 'Twig\Node\Expression\Binary\BitwiseOrBinary', false);

View File

@@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_BitwiseXor extends Twig_Node_Expression_Binary
return $compiler->raw('^');
}
}
class_alias('Twig_Node_Expression_Binary_BitwiseXor', 'Twig\Node\Expression\Binary\BitwiseXorBinary', false);

View File

@@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_Concat extends Twig_Node_Expression_Binary
return $compiler->raw('.');
}
}
class_alias('Twig_Node_Expression_Binary_Concat', 'Twig\Node\Expression\Binary\ConcatBinary', false);

View File

@@ -3,8 +3,8 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) 2009 Armin Ronacher
* (c) Fabien Potencier
* (c) Armin Ronacher
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_Div extends Twig_Node_Expression_Binary
return $compiler->raw('/');
}
}
class_alias('Twig_Node_Expression_Binary_Div', 'Twig\Node\Expression\Binary\DivBinary', false);

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2013 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -28,3 +28,5 @@ class Twig_Node_Expression_Binary_EndsWith extends Twig_Node_Expression_Binary
return $compiler->raw('');
}
}
class_alias('Twig_Node_Expression_Binary_EndsWith', 'Twig\Node\Expression\Binary\EndsWithBinary', false);

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -15,3 +15,5 @@ class Twig_Node_Expression_Binary_Equal extends Twig_Node_Expression_Binary
return $compiler->raw('==');
}
}
class_alias('Twig_Node_Expression_Binary_Equal', 'Twig\Node\Expression\Binary\EqualBinary', false);

View File

@@ -3,23 +3,18 @@
/*
* This file is part of Twig.
*
* (c) 2009 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Twig_Node_Expression_Binary_FloorDiv extends Twig_Node_Expression_Binary
{
/**
* Compiles the node to PHP.
*
* @param Twig_Compiler $compiler A Twig_Compiler instance
*/
public function compile(Twig_Compiler $compiler)
{
$compiler->raw('intval(floor(');
$compiler->raw('(int) floor(');
parent::compile($compiler);
$compiler->raw('))');
$compiler->raw(')');
}
public function operator(Twig_Compiler $compiler)
@@ -27,3 +22,5 @@ class Twig_Node_Expression_Binary_FloorDiv extends Twig_Node_Expression_Binary
return $compiler->raw('/');
}
}
class_alias('Twig_Node_Expression_Binary_FloorDiv', 'Twig\Node\Expression\Binary\FloorDivBinary', false);

View File

@@ -3,7 +3,7 @@
/*
* This file is part of Twig.
*
* (c) 2010 Fabien Potencier
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -15,3 +15,5 @@ class Twig_Node_Expression_Binary_Greater extends Twig_Node_Expression_Binary
return $compiler->raw('>');
}
}
class_alias('Twig_Node_Expression_Binary_Greater', 'Twig\Node\Expression\Binary\GreaterBinary', false);

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