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] [0.7.4 - 24.12.2017]
* fixed mysql fatal error on tibiacom template - top 5 box * fixed mysql fatal error on tibiacom template - top 5 box
* fixed displaying of level percent bar on tibian signature * fixed displaying of level percent bar on tibian signature

35
TODO
View File

@@ -2,28 +2,42 @@
0.* 0.*
* support duplicated vocation names with different ids * support duplicated vocation names with different ids
* plugins: option to define custom requirements check in json file, to check if system meets the requirement * sandbox for plugins, don't install when requirements are not passed
* add support for defining max myaac version in plugin.json file * add changelog management interface
* cache Menus in templates * plugins require:
* don't show error indicators on first time load - createaccount page * php extension
* update Twig to the latest version from 1.x branch * database table or column
* semantic versioning support for plugins (github.com/composer/semver) * kathrine tickets - show/hide
* add some notice to the user that installing step "Import Schema" will take some time * highscores - by balance
* check user IP on installing to prevent install by random user * 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: 1.0:
* i18n support (issue #1 on github) * i18n support (issue #1 on github)
* New Admin Panel layout and interface * 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 * remove tibiacom template, and include it as a plugin
2.0 2.0
* remove gesior backward support
* remove compat functions * remove compat functions
* remove $template['link_*']
* folder restructure: * 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) * 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 * rename templates to layouts as templates is meant to be used for twig templates
* change gifts_system to shop_system configurable * change gifts_system to shop_system configurable
* move most used options in system/templates dir to separate directories (more transparent) * 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): At any time between (version not specified):
* better news archive with search function (like on tibia.com) * 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 account.management page to be more realistic (like on tibia.com)
* update guilds 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 * possibility to add extra cache engines with plugins
* new cache engine - plain php, is good with pure php 7.0+ and opcache
* preferably configurable (enable/disable) forum TinyMCE editor * preferably configurable (enable/disable) forum TinyMCE editor
* new cache engine - plain php, is good with pure php 7.0+ and opcache
* OTAdmin support in Admin Panel * OTAdmin support in Admin Panel
* database towns table support for TFS 1.3 * 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(); session_start();
define('MYAAC', true); define('MYAAC', true);
define('MYAAC_VERSION', '0.7.4'); define('MYAAC_VERSION', '0.8.0-dev');
define('DATABASE_VERSION', 20); define('DATABASE_VERSION', 21);
define('TABLE_PREFIX', 'myaac_'); define('TABLE_PREFIX', 'myaac_');
define('START_TIME', microtime(true)); define('START_TIME', microtime(true));
define('MYAAC_OS', (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') ? 'WINDOWS' : (strtoupper(PHP_OS) == 'DARWIN' ? 'MAC' : 'LINUX')); 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_VIDEOS', 1024);
define('FLAG_CONTENT_FAQ', 2048); define('FLAG_CONTENT_FAQ', 2048);
define('FLAG_CONTENT_MENUS', 4096); define('FLAG_CONTENT_MENUS', 4096);
define('FLAG_CONTENT_PLAYERS', 8192);
// news // news
define('NEWS', 1); define('NEWS', 1);

View File

@@ -46,8 +46,6 @@ $config = array(
// footer // footer
'footer' => ''/*'<br/>Your Server &copy; 2016. All rights reserved.'*/, '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' => 'en', // default language (currently only 'en' available)
'language_allow_change' => false, 'language_allow_change' => false,
@@ -56,7 +54,7 @@ $config = array(
'views_counter' => true, 'views_counter' => true,
// cache system. by default file cache is used // 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) '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) // database details (leave blank for auto detect from config.lua)
@@ -65,6 +63,7 @@ $config = array(
'database_user' => '', 'database_user' => '',
'database_password' => '', 'database_password' => '',
'database_name' => '', '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 system (only TFS 0.3)
'multiworld' => false, // use multiworld system? 'multiworld' => false, // use multiworld system?
@@ -75,7 +74,7 @@ $config = array(
// images // images
'outfit_images_url' => 'http://outfit-images.ots.me/outfit.php', // set to animoutfit.php for animated outfit '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
'account_management' => true, // disable if you're using other method to manage users (fe. tfs account manager) '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_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_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 '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>'*/ '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) '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'); include(TOOLS . 'signature/index.php');
exit(); 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"); header("HTTP/1.0 404 Not Found");
exit; 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'])) if(file_exists(BASE . 'install') && (!isset($config['installed']) || !$config['installed']))
{ {
header('Location: ' . BASE_URL . 'install/'); header('Location: ' . BASE_URL . 'install/');
@@ -176,21 +178,17 @@ if(fetchDatabaseConfig('database_version', $tmp)) { // we got version
$tmp = (int)$tmp; $tmp = (int)$tmp;
if($tmp < DATABASE_VERSION) { // import if older if($tmp < DATABASE_VERSION) { // import if older
for($i = $tmp + 1; $i <= DATABASE_VERSION; $i++) { for($i = $tmp + 1; $i <= DATABASE_VERSION; $i++) {
$file = SYSTEM . 'migrations/' . $i . '.php'; require(SYSTEM . 'migrations/' . $i . '.php');
if(file_exists($file)) { updateDatabaseConfig('database_version', $i);
require($file);
}
} }
updateDatabaseConfig('database_version', DATABASE_VERSION);
} }
} }
else { // register first version else { // register first version
registerDatabaseConfig('database_version', 0);
for($i = 1; $i <= DATABASE_VERSION; $i++) { for($i = 1; $i <= DATABASE_VERSION; $i++) {
require(SYSTEM . 'migrations/' . $i . '.php'); require(SYSTEM . 'migrations/' . $i . '.php');
updateDatabaseConfig('database_version', $i);
} }
registerDatabaseConfig('database_version', DATABASE_VERSION);
} }
// event system // event system
@@ -422,14 +420,17 @@ else
} }
echo '<!-- MyAAC ' . MYAAC_VERSION . ' :: http://www.my-aac.org/ -->' . "\n"; echo '<!-- MyAAC ' . MYAAC_VERSION . ' :: http://www.my-aac.org/ -->' . "\n";
if(($config['debug_level'] & 1) == 1) if(superAdmin()) {
echo '<!-- Generated in :: ' . round(microtime(true) - START_TIME, 4) . ' -->'; 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) if($config['database_log']) {
echo "\n" . '<!-- Queries done :: ' . $db->queries() . ' -->'; echo PHP_EOL . '<!-- Database Queries Done by MyAAC:' . PHP_EOL . $db->getLog() . '-->';
}
if(($config['debug_level'] & 4) == 4 && function_exists('memory_get_peak_usage')) }
echo "\n" . '<!-- Peak memory usage: ' . convert_bytes(memory_get_peak_usage(true)) . ' -->';
$hooks->trigger(HOOK_FINISH); $hooks->trigger(HOOK_FINISH);
?> ?>

View File

@@ -6,36 +6,36 @@ if(!isset($_SESSION['var_server_path'])) {
$error = true; $error = true;
} }
$config['server_path'] = $_SESSION['var_server_path']; $config['server_path'] = $_SESSION['var_server_path'];
// take care of trailing slash at the end // take care of trailing slash at the end
if($config['server_path'][strlen($config['server_path']) - 1] != '/') if($config['server_path'][strlen($config['server_path']) - 1] != '/')
$config['server_path'] .= '/'; $config['server_path'] .= '/';
if((!isset($error) || !$error) && !file_exists($config['server_path'] . 'config.lua')) { if((!isset($error) || !$error) && !file_exists($config['server_path'] . 'config.lua')) {
error($locale['step_database_error_config']); error($locale['step_database_error_config']);
$error = true;
}
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'];
else if(isset($config['lua']['mysqlHost'])) // tfs 0.2/1.0
$config['database_type'] = 'mysql';
else if(isset($config['lua']['database_type'])) // otserv
$config['database_type'] = $config['lua']['database_type'];
else if(isset($config['lua']['sql_type'])) // otserv
$config['database_type'] = $config['lua']['sql_type'];
$config['database_type'] = strtolower($config['database_type']);
if(empty($config['database_type'])) {
error($locale['step_database_error_database_empty']);
$error = true; $error = true;
} }
else if($config['database_type'] != 'mysql') {
if(!isset($error) || !$error) { $locale['step_database_error_only_mysql'] = str_replace('$DATABASE_TYPE$', '<b>' . $config['database_type'] . '</b>', $locale['step_database_error_only_mysql']);
$config['lua'] = load_config_lua($config['server_path'] . 'config.lua'); error($locale['step_database_error_only_mysql']);
if(isset($config['lua']['sqlType'])) // tfs 0.3 $error = true;
$config['database_type'] = $config['lua']['sqlType'];
else if(isset($config['lua']['mysqlHost'])) // tfs 0.2/1.0
$config['database_type'] = 'mysql';
else if(isset($config['lua']['database_type'])) // otserv
$config['database_type'] = $config['lua']['database_type'];
else if(isset($config['lua']['sql_type'])) // otserv
$config['database_type'] = $config['lua']['sql_type'];
$config['database_type'] = strtolower($config['database_type']);
if(empty($config['database_type'])) {
error($locale['step_database_error_database_empty']);
$error = true;
}
else if($config['database_type'] != 'mysql') {
$locale['step_database_error_only_mysql'] = str_replace('$DATABASE_TYPE$', '<b>' . $config['database_type'] . '</b>', $locale['step_database_error_only_mysql']);
error($locale['step_database_error_only_mysql']);
$error = true;
}
} }
}
?> ?>

View File

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

View File

@@ -109,6 +109,7 @@ CREATE TABLE `myaac_forum`
`post_text` text NOT NULL, `post_text` text NOT NULL,
`post_topic` varchar(255) NOT NULL DEFAULT '', `post_topic` varchar(255) NOT NULL DEFAULT '',
`post_smile` tinyint(1) NOT NULL default '0', `post_smile` tinyint(1) NOT NULL default '0',
`post_html` tinyint(1) NOT NULL default '0',
`post_date` int(20) NOT NULL default '0', `post_date` int(20) NOT NULL default '0',
`last_edit_aid` int(20) NOT NULL default '0', `last_edit_aid` int(20) NOT NULL default '0',
`edit_date` 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(SYSTEM . 'functions.php');
require(BASE . 'install/includes/functions.php'); require(BASE . 'install/includes/functions.php');
require(BASE . 'install/includes/locale.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 // twig
require_once LIBS . 'Twig/Autoloader.php'; require_once LIBS . 'Twig/Autoloader.php';
@@ -17,45 +20,100 @@ $twig = new Twig_Environment($twig_loader, array(
'auto_reload' => true 'auto_reload' => true
)); ));
if(isset($_POST['vars'])) // load installation status
{
foreach($_POST['vars'] as $key => $value)
$_SESSION['var_' . $key] = $value;
}
// step
$step = isset($_POST['step']) ? $_POST['step'] : 'welcome'; $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'); $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 if(!in_array($step, $steps)) // check if step is valid
die('ERROR: Unknown step.'); die('ERROR: Unknown step.');
$install_status['step'] = $step;
$errors = array(); $errors = array();
if($step == 'database')
{ if($step == 'database') {
foreach($_POST['vars'] as $key => $value) foreach($_SESSION as $key => $value) {
{ if(strpos($key, 'var_') === false || strpos($key, 'account') !== false || strpos($key, 'password') !== false) {
if($key != 'usage' && empty($value)) continue;
{ }
$key = str_replace('var_', '', $key);
if($key != 'usage' && empty($value)) {
$errors[] = $locale['please_fill_all']; $errors[] = $locale['please_fill_all'];
break; 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']; $errors[] = $locale['step_config_mail_admin_error'];
break; break;
} }
else if($key == 'mail_address' && !Validator::email($value)) else if($key == 'mail_address' && !Validator::email($value)) {
{
$errors[] = $locale['step_config_mail_address_error']; $errors[] = $locale['step_config_mail_address_error'];
break; 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)) { if(!empty($errors)) {
$step = 'config'; $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') { else if($step == 'finish') {
// password // password
$password = $_SESSION['var_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; $error = false;
clearstatcache(); clearstatcache();
if(is_writable(CACHE) && (MYAAC_OS != 'WINDOWS' || win_is_writable(CACHE))) { if(is_writable(CACHE) && (MYAAC_OS != 'WINDOWS' || win_is_writable(CACHE))) {
ob_start(); 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;
}
}
$step_id = array_search($step, $steps); if(!$allow)
require('steps/' . $step_id . '-' . $step . '.php'); {
$content = ob_get_contents(); $content = warning('In file <b>install/ip.txt</b> must be your IP!<br/>
ob_end_clean(); 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 { else {
$content = error(file_get_contents(BASE . 'install/includes/twig_error.html'), true); $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 // start validating
version_check($locale['step_requirements_php_version'], (PHP_VERSION_ID >= 50300), PHP_VERSION); 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); $perms = (int) substr(decoct(fileperms(BASE . $value)), 2);
version_check($locale['step_requirements_write_perms'] . ': ' . $value, $perms >= 660); version_check($locale['step_requirements_write_perms'] . ': ' . $value, $perms >= 660);

View File

@@ -1,74 +1,8 @@
<?php <?php
defined('MYAAC') or die('Direct access not allowed!'); 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(); $clients = array();
foreach($clients_list as $client) { foreach($config['clients'] as $client) {
$client_version = (string)($client / 100); $client_version = (string)($client / 100);
if(strpos($client_version, '.') == false) if(strpos($client_version, '.') == false)
$client_version .= '.0'; $client_version .= '.0';
@@ -78,6 +12,7 @@ foreach($clients_list as $client) {
echo $twig->render('install.config.html.twig', array( echo $twig->render('install.config.html.twig', array(
'clients' => $clients, 'clients' => $clients,
'timezones' => DateTimeZone::listIdentifiers(),
'locale' => $locale, 'locale' => $locale,
'session' => $_SESSION, 'session' => $_SESSION,
'errors' => isset($errors) ? $errors : null, 'errors' => isset($errors) ? $errors : null,

View File

@@ -13,6 +13,12 @@ if(!isset($_SESSION['var_server_path'])) {
if(!$error) { if(!$error) {
$content = "<?php"; $content = "<?php";
$content .= PHP_EOL; $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) foreach($_SESSION as $key => $value)
{ {
if(strpos($key, 'var_') !== false) if(strpos($key, 'var_') !== false)
@@ -21,14 +27,14 @@ if(!$error) {
{ {
$value = str_replace("\\", "/", $value); $value = str_replace("\\", "/", $value);
if($value[strlen($value) - 1] != '/') if($value[strlen($value) - 1] != '/')
$value .= "/"; $value .= '/';
} }
if($key == 'var_usage') { if($key == 'var_usage') {
$content .= '$config[\'anonymous_usage_statistics\'] = ' . ((int)$value == 1 ? 'true' : 'false') . ';'; $content .= '$config[\'anonymous_usage_statistics\'] = ' . ((int)$value == 1 ? 'true' : 'false') . ';';
$content .= PHP_EOL; $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 .= '$config[\'' . str_replace('var_', '', $key) . '\'] = \'' . $value . '\';';
$content .= PHP_EOL; $content .= PHP_EOL;
} }
@@ -41,192 +47,12 @@ if(!$error) {
success($locale['step_database_importing']); success($locale['step_database_importing']);
require(BASE . 'install/includes/database.php'); require(BASE . 'install/includes/database.php');
if(!tableExist('accounts')) { echo $twig->render('install.installer.html.twig', array(
$locale['step_database_error_table'] = str_replace('$TABLE$', 'accounts', $locale['step_database_error_table']); 'url' => 'tools/5-database.php',
error($locale['step_database_error_table']); 'message' => $locale['loading_spinner']
$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;
}
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(!$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'])) { if(!Validator::email($_SESSION['var_mail_admin'])) {
error($locale['step_config_mail_admin_error']); error($locale['step_config_mail_admin_error']);
$error = true; $error = true;
@@ -243,16 +69,21 @@ if(!$error) {
$content .= '$config[\'session_prefix\'] = \'myaac_' . generateRandomString(8, true, false, true, false) . '_\';'; $content .= '$config[\'session_prefix\'] = \'myaac_' . generateRandomString(8, true, false, true, false) . '_\';';
$content .= PHP_EOL; $content .= PHP_EOL;
$content .= '$config[\'cache_prefix\'] = \'myaac_' . generateRandomString(8, true, false, true, false) . '_\';'; $content .= '$config[\'cache_prefix\'] = \'myaac_' . generateRandomString(8, true, false, true, false) . '_\';';
$content .= PHP_EOL;
$file = fopen(BASE . 'config.local.php', 'a+'); $saved = true;
if($file) { if(!$error) {
$saved = file_put_contents(BASE . 'config.local.php', $content);
}
if($saved) {
if(!$error) { if(!$error) {
fwrite($file, $content);
$_SESSION['saved'] = true; $_SESSION['saved'] = true;
} }
} }
else { 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']); $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/> warning($locale['step_database_error_file'] . '<br/>
<textarea cols="70" rows="10">' . $content . '</textarea>'); <textarea cols="70" rows="10">' . $content . '</textarea>');

View File

@@ -1,6 +1,7 @@
<?php <?php
defined('MYAAC') or die('Direct access not allowed!'); defined('MYAAC') or die('Direct access not allowed!');
ini_set('max_execution_time', 300);
if(isset($config['installed']) && $config['installed'] && !isset($_SESSION['saved'])) { if(isset($config['installed']) && $config['installed'] && !isset($_SESSION['saved'])) {
warning($locale['already_installed']); warning($locale['already_installed']);
} }
@@ -14,7 +15,7 @@ else {
$password = $_SESSION['var_password']; $password = $_SESSION['var_password'];
$config_salt_enabled = fieldExist('salt', 'accounts'); $config_salt_enabled = $db->hasColumn('accounts', 'salt');
if($config_salt_enabled) if($config_salt_enabled)
{ {
$salt = generateRandomString(10, false, true, true); $salt = generateRandomString(10, false, true, true);
@@ -76,9 +77,9 @@ else {
$account_used->setCustomField('web_flags', FLAG_ADMIN + FLAG_SUPER_ADMIN); $account_used->setCustomField('web_flags', FLAG_ADMIN + FLAG_SUPER_ADMIN);
$account_used->setCustomField('country', 'us'); $account_used->setCustomField('country', 'us');
if(fieldExist('group_id', 'accounts')) if($db->hasColumn('accounts', 'group_id'))
$account_used->setCustomField('group_id', $groups->getHighestId()); $account_used->setCustomField('group_id', $groups->getHighestId());
if(fieldExist('type', 'accounts')) if($db->hasColumn('accounts', 'type'))
$account_used->setCustomField('type', 5); $account_used->setCustomField('type', 5);
if(!$player_db->isLoaded()) if(!$player_db->isLoaded())
@@ -114,103 +115,10 @@ else {
} }
} }
$deleted = 'deleted'; echo $twig->render('install.installer.html.twig', array(
if(fieldExist('deletion', 'players')) 'url' => 'tools/7-finish.php',
$deleted = 'deletion'; 'message' => $locale['importing_spinner']
));
$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']);
if(!isset($_SESSION['installed'])) { if(!isset($_SESSION['installed'])) {
file_get_contents('http://my-aac.org/report_install.php?v=' . MYAAC_VERSION . '&b=' . urlencode(BASE_URL)); 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[$key]);
} }
unset($_SESSION['saved']); 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']; ?>" /> <meta http-equiv="Content-Type" content="text/html; charset=<?php echo $locale['encoding']; ?>" />
<title>MyAAC - <?php echo $locale['installation']; ?></title> <title>MyAAC - <?php echo $locale['installation']; ?></title>
<link rel="stylesheet" type="text/css" href="template/style.css" /> <link rel="stylesheet" type="text/css" href="template/style.css" />
<script type="text/javascript" src="<?php echo BASE_URL; ?>tools/jquery.js"></script>
</head> </head>
<body> <body>
<div id="wrapper"> <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", "contact": "nobody@example.org",
"require": { "require": {
"myaac": "0.4.3", "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", "install": "plugins/example/install.php",
"uninstall": [ "uninstall": [
"plugins/example.json", "plugins/example.json",
"plugins/example/install.php", "plugins/example-directory",
"plugins/example/before.php" "templates/other-directory"
/***
this is example of multi line comment
1. list example
2. something
****/
], ],
"hooks": { "hooks": {
"Example Hook": { "Example Hook": {

View File

@@ -29,7 +29,7 @@ if(Plugins::install($path_to_file)) {
echo 'WARNING: ' . $warning; echo 'WARNING: ' . $warning;
} }
$info = Plugins::getPluginInfo(); $info = Plugins::getPlugin();
echo (isset($info['name']) ? $info['name'] . ' p' : 'P') . 'lugin has been successfully installed.'; echo (isset($info['name']) ? $info['name'] . ' p' : 'P') . 'lugin has been successfully installed.';
} }
else 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() { function news_place() {
return tickers(); 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'])) if(isset($config['lua']['useMD5Passwords']) && getBoolean($config['lua']['useMD5Passwords']))
$config['database_encryption'] = 'md5'; $config['database_encryption'] = 'md5';
if(!isset($config['database_log'])) {
$config['database_log'] = false;
}
try { try {
$ots->connect(POT::DB_MYSQL, $ots->connect(array(
array(
'host' => $config['database_host'], 'host' => $config['database_host'],
'user' => $config['database_user'], 'user' => $config['database_user'],
'password' => $config['database_password'], '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)) if(is_numeric($name))
{ {
$player = $ots->createObject('Player'); $player = new OTS_Player();
$player->load(intval($name)); $player->load(intval($name));
if($player->isLoaded()) if($player->isLoaded())
$name = $player->getName(); $name = $player->getName();
@@ -156,6 +156,10 @@ function getFlagImage($country)
if(!isset($config['countries'])) if(!isset($config['countries']))
require(SYSTEM . 'countries.conf.php'); require(SYSTEM . 'countries.conf.php');
if(!isset($config['countries'][$country])) {
return '';
}
return '<img src="images/flags/' . $country . '.gif" title="' . $config['countries'][$country]. '"/>'; return '<img src="images/flags/' . $country . '.gif" title="' . $config['countries'][$country]. '"/>';
} }
@@ -167,7 +171,9 @@ function getFlagImage($country)
*/ */
function getBoolean($v) function getBoolean($v)
{ {
if(!$v || !isset($v[0])) return false; if(is_bool($v)) {
return $v;
}
if(is_numeric($v)) if(is_numeric($v))
return intval($v) > 0; return intval($v) > 0;
@@ -302,22 +308,6 @@ function encrypt($str)
return $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 //delete player with name
function delete_player($name) function delete_player($name)
{ {
@@ -376,9 +366,9 @@ function delete_guild($id)
global $db, $ots; global $db, $ots;
foreach($rank_list as $rank_in_guild) { 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`;'); $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`;'); $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 else
$players_with_rank = $db->query('SELECT `id`, `rank_id` FROM `players` WHERE `rank_id` = ' . $rank_in_guild->getId() . ' AND `deleted` = 0;'); $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(); $players_with_rank_number = $players_with_rank->rowCount();
if($players_with_rank_number > 0) { if($players_with_rank_number > 0) {
foreach($players_with_rank as $result) { foreach($players_with_rank as $result) {
$player = $ots->createObject('Player'); $player = new OTS_Player();
$player->load($result['id']); $player->load($result['id']);
if(!$player->isLoaded()) if(!$player->isLoaded())
continue; continue;
@@ -563,7 +553,7 @@ function getCreatureName($killer, $showStatus = false, $extendedInfo = false)
if(is_numeric($killer)) if(is_numeric($killer))
{ {
$player = $ots->createObject('Player'); $player = new OTS_Player();
$player->load($killer); $player->load($killer);
if($player->isLoaded()) 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>'; $str .= '<font color="'.($player->isOnline() ? 'green' : 'red').'">' . $player->getName() . '</font></b></a>';
if($extendedInfo) { if($extendedInfo) {
$str .= '<br><small>'.$player->getLevel().' '.$config['vocations'][$player->getVocation()].'</small>'; $str .= '<br><small>'.$player->getLevel().' '.$player->getVocationName().'</small>';
} }
return $str; return $str;
} }
@@ -816,9 +806,9 @@ function _mail($to, $subject, $body, $altBody = '', $add_html_tags = true)
$signature_html = $config['mail_signature']['html']; $signature_html = $config['mail_signature']['html'];
if($add_html_tags && isset($body[0])) 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 else
$body .= '<br/><br/>' . $signature_html; $tmp_body .= '<br/><br/>' . $signature_html;
if($config['smtp_enabled']) if($config['smtp_enabled'])
{ {
@@ -839,7 +829,7 @@ function _mail($to, $subject, $body, $altBody = '', $add_html_tags = true)
$mailer->FromName = $config['lua']['serverName']; $mailer->FromName = $config['lua']['serverName'];
$mailer->Subject = $subject; $mailer->Subject = $subject;
$mailer->AddAddress($to); $mailer->AddAddress($to);
$mailer->Body = $body; $mailer->Body = $tmp_body;
$signature_plain = ''; $signature_plain = '';
if(isset($config['mail_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])) if(isset($altBody[0]))
$mailer->AltBody = $altBody . $signature_plain; $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(); return $mailer->Send();
} }
@@ -968,10 +961,18 @@ function getTopPlayers($limit = 5) {
if($fetch_from_db) if($fetch_from_db)
{ {
$deleted = 'deleted'; $deleted = 'deleted';
if(fieldExist('deletion', 'players')) if($db->hasColumn('players', 'deletion'))
$deleted = '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; $i = 0;
foreach($players as &$player) { foreach($players as &$player) {

View File

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

View File

@@ -3,7 +3,7 @@
/* /*
* This file is part of Twig. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * file that was distributed with this source code.
@@ -13,13 +13,15 @@
* Autoloads Twig classes. * Autoloads Twig classes.
* *
* @author Fabien Potencier <fabien@symfony.com> * @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 class Twig_Autoloader
{ {
/** /**
* Registers Twig_Autoloader as an SPL 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) public static function register($prepend = false)
{ {
@@ -33,7 +35,7 @@ class Twig_Autoloader
/** /**
* Handles autoloading of classes. * Handles autoloading of classes.
* *
* @param string $class A class name. * @param string $class a class name
*/ */
public static function autoload($class) public static function autoload($class)
{ {

View File

@@ -16,9 +16,6 @@
*/ */
abstract class Twig_BaseNodeVisitor implements Twig_NodeVisitorInterface abstract class Twig_BaseNodeVisitor implements Twig_NodeVisitorInterface
{ {
/**
* {@inheritdoc}
*/
final public function enterNode(Twig_NodeInterface $node, Twig_Environment $env) final public function enterNode(Twig_NodeInterface $node, Twig_Environment $env)
{ {
if (!$node instanceof Twig_Node) { if (!$node instanceof Twig_Node) {
@@ -28,9 +25,6 @@ abstract class Twig_BaseNodeVisitor implements Twig_NodeVisitorInterface
return $this->doEnterNode($node, $env); return $this->doEnterNode($node, $env);
} }
/**
* {@inheritdoc}
*/
final public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env) final public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env)
{ {
if (!$node instanceof Twig_Node) { if (!$node instanceof Twig_Node) {
@@ -43,9 +37,6 @@ abstract class Twig_BaseNodeVisitor implements Twig_NodeVisitorInterface
/** /**
* Called before child nodes are visited. * 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 * @return Twig_Node The modified node
*/ */
abstract protected function doEnterNode(Twig_Node $node, Twig_Environment $env); 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. * 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 * @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); 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. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* (c) 2009 Armin Ronacher * (c) Armin Ronacher
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * file that was distributed with this source code.
@@ -21,31 +21,30 @@ class Twig_Compiler implements Twig_CompilerInterface
protected $source; protected $source;
protected $indentation; protected $indentation;
protected $env; protected $env;
protected $debugInfo; protected $debugInfo = array();
protected $sourceOffset; protected $sourceOffset;
protected $sourceLine; protected $sourceLine;
protected $filename; protected $filename;
/**
* Constructor.
*
* @param Twig_Environment $env The twig environment instance
*/
public function __construct(Twig_Environment $env) public function __construct(Twig_Environment $env)
{ {
$this->env = $env; $this->env = $env;
$this->debugInfo = array();
} }
/**
* @deprecated since 1.25 (to be removed in 2.0)
*/
public function getFilename() 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; return $this->filename;
} }
/** /**
* Returns the environment instance related to this compiler. * Returns the environment instance related to this compiler.
* *
* @return Twig_Environment The environment instance * @return Twig_Environment
*/ */
public function getEnvironment() public function getEnvironment()
{ {
@@ -68,7 +67,7 @@ class Twig_Compiler implements Twig_CompilerInterface
* @param Twig_NodeInterface $node The node to compile * @param Twig_NodeInterface $node The node to compile
* @param int $indentation The current indentation * @param int $indentation The current indentation
* *
* @return Twig_Compiler The current compiler instance * @return $this
*/ */
public function compile(Twig_NodeInterface $node, $indentation = 0) public function compile(Twig_NodeInterface $node, $indentation = 0)
{ {
@@ -81,7 +80,8 @@ class Twig_Compiler implements Twig_CompilerInterface
$this->indentation = $indentation; $this->indentation = $indentation;
if ($node instanceof Twig_Node_Module) { if ($node instanceof Twig_Node_Module) {
$this->filename = $node->getAttribute('filename'); // to be removed in 2.0
$this->filename = $node->getTemplateName();
} }
$node->compile($this); $node->compile($this);
@@ -92,7 +92,7 @@ class Twig_Compiler implements Twig_CompilerInterface
public function subcompile(Twig_NodeInterface $node, $raw = true) public function subcompile(Twig_NodeInterface $node, $raw = true)
{ {
if (false === $raw) { if (false === $raw) {
$this->addIndentation(); $this->source .= str_repeat(' ', $this->indentation * 4);
} }
$node->compile($this); $node->compile($this);
@@ -105,7 +105,7 @@ class Twig_Compiler implements Twig_CompilerInterface
* *
* @param string $string The string * @param string $string The string
* *
* @return Twig_Compiler The current compiler instance * @return $this
*/ */
public function raw($string) public function raw($string)
{ {
@@ -117,14 +117,13 @@ class Twig_Compiler implements Twig_CompilerInterface
/** /**
* Writes a string to the compiled code by adding indentation. * Writes a string to the compiled code by adding indentation.
* *
* @return Twig_Compiler The current compiler instance * @return $this
*/ */
public function write() public function write()
{ {
$strings = func_get_args(); $strings = func_get_args();
foreach ($strings as $string) { foreach ($strings as $string) {
$this->addIndentation(); $this->source .= str_repeat(' ', $this->indentation * 4).$string;
$this->source .= $string;
} }
return $this; return $this;
@@ -133,10 +132,14 @@ class Twig_Compiler implements Twig_CompilerInterface
/** /**
* Appends an indentation to the current PHP code after compilation. * 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() 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); $this->source .= str_repeat(' ', $this->indentation * 4);
return $this; return $this;
@@ -147,7 +150,7 @@ class Twig_Compiler implements Twig_CompilerInterface
* *
* @param string $value The string * @param string $value The string
* *
* @return Twig_Compiler The current compiler instance * @return $this
*/ */
public function string($value) public function string($value)
{ {
@@ -161,12 +164,12 @@ class Twig_Compiler implements Twig_CompilerInterface
* *
* @param mixed $value The value to convert * @param mixed $value The value to convert
* *
* @return Twig_Compiler The current compiler instance * @return $this
*/ */
public function repr($value) public function repr($value)
{ {
if (is_int($value) || is_float($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'); setlocale(LC_NUMERIC, 'C');
} }
@@ -202,28 +205,28 @@ class Twig_Compiler implements Twig_CompilerInterface
/** /**
* Adds debugging information. * Adds debugging information.
* *
* @param Twig_NodeInterface $node The related twig node * @return $this
*
* @return Twig_Compiler The current compiler instance
*/ */
public function addDebugInfo(Twig_NodeInterface $node) public function addDebugInfo(Twig_NodeInterface $node)
{ {
if ($node->getLine() != $this->lastLine) { if ($node->getTemplateLine() != $this->lastLine) {
$this->write(sprintf("// line %d\n", $node->getLine())); $this->write(sprintf("// line %d\n", $node->getTemplateLine()));
// when mbstring.func_overload is set to 2 // when mbstring.func_overload is set to 2
// mb_substr_count() replaces substr_count() // mb_substr_count() replaces substr_count()
// but they have different signatures! // but they have different signatures!
if (((int) ini_get('mbstring.func_overload')) & 2) { 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 is much slower than the "right" version
$this->sourceLine += mb_substr_count(mb_substr($this->source, $this->sourceOffset), "\n"); $this->sourceLine += mb_substr_count(mb_substr($this->source, $this->sourceOffset), "\n");
} else { } else {
$this->sourceLine += substr_count($this->source, "\n", $this->sourceOffset); $this->sourceLine += substr_count($this->source, "\n", $this->sourceOffset);
} }
$this->sourceOffset = strlen($this->source); $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; return $this;
@@ -241,7 +244,7 @@ class Twig_Compiler implements Twig_CompilerInterface
* *
* @param int $step The number of indentation to add * @param int $step The number of indentation to add
* *
* @return Twig_Compiler The current compiler instance * @return $this
*/ */
public function indent($step = 1) public function indent($step = 1)
{ {
@@ -255,7 +258,7 @@ class Twig_Compiler implements Twig_CompilerInterface
* *
* @param int $step The number of indentation to remove * @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 * @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 // can't outdent by more steps than the current indentation level
if ($this->indentation < $step) { 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; $this->indentation -= $step;
@@ -276,3 +279,6 @@ class Twig_Compiler implements Twig_CompilerInterface
return sprintf('__internal_%s', hash('sha256', uniqid(mt_rand(), true), false)); 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. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * file that was distributed with this source code.
@@ -21,9 +21,7 @@ interface Twig_CompilerInterface
/** /**
* Compiles a node. * Compiles a node.
* *
* @param Twig_NodeInterface $node The node to compile * @return $this
*
* @return Twig_CompilerInterface The current compiler instance
*/ */
public function compile(Twig_NodeInterface $node); 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. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * 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 * 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 * 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 * 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 * and/or the name 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 * can be disabled by passing false for both the name and the line number
* when creating a new instance of this class. * when creating a new instance of this class.
* *
* @author Fabien Potencier <fabien@symfony.com> * @author Fabien Potencier <fabien@symfony.com>
@@ -34,29 +34,43 @@
class Twig_Error extends Exception class Twig_Error extends Exception
{ {
protected $lineno; protected $lineno;
// to be renamed to name in 2.0
protected $filename; protected $filename;
protected $rawMessage; protected $rawMessage;
protected $previous; protected $previous;
private $sourcePath;
private $sourceCode;
/** /**
* Constructor. * 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 * disable automatic guessing of the original template name
* and line number. * and line number.
* *
* Set the line number to -1 to enable its automatic guessing. * 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. * By default, automatic guessing is enabled.
* *
* @param string $message The error message * @param string $message The error message
* @param int $lineno The template line where the error occurred * @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 * @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) { if (PHP_VERSION_ID < 50300) {
$this->previous = $previous; $this->previous = $previous;
parent::__construct(''); parent::__construct('');
@@ -65,9 +79,9 @@ class Twig_Error extends Exception
} }
$this->lineno = $lineno; $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(); $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() 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; 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(); $this->updateRepr();
} }
@@ -130,6 +183,32 @@ class Twig_Error extends Exception
$this->updateRepr(); $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() public function guess()
{ {
$this->guessTemplateInfo(); $this->guessTemplateInfo();
@@ -155,23 +234,45 @@ class Twig_Error extends Exception
throw new BadMethodCallException(sprintf('Method "Twig_Error::%s()" does not exist.', $method)); 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() protected function updateRepr()
{ {
$this->message = $this->rawMessage; $this->message = $this->rawMessage;
if ($this->sourcePath && $this->lineno > 0) {
$this->file = $this->sourcePath;
$this->line = $this->lineno;
return;
}
$dot = false; $dot = false;
if ('.' === substr($this->message, -1)) { if ('.' === substr($this->message, -1)) {
$this->message = substr($this->message, 0, -1); $this->message = substr($this->message, 0, -1);
$dot = true; $dot = true;
} }
$questionMark = false;
if ('?' === substr($this->message, -1)) {
$this->message = substr($this->message, 0, -1);
$questionMark = true;
}
if ($this->filename) { if ($this->filename) {
if (is_string($this->filename) || (is_object($this->filename) && method_exists($this->filename, '__toString'))) { 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 { } 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) { if ($this->lineno && $this->lineno >= 0) {
@@ -181,8 +282,15 @@ class Twig_Error extends Exception
if ($dot) { if ($dot) {
$this->message .= '.'; $this->message .= '.';
} }
if ($questionMark) {
$this->message .= '?';
}
} }
/**
* @internal
*/
protected function guessTemplateInfo() protected function guessTemplateInfo()
{ {
$template = null; $template = null;
@@ -205,11 +313,18 @@ class Twig_Error extends Exception
} }
} }
// update template filename // update template name
if (null !== $template && null === $this->filename) { if (null !== $template && null === $this->filename) {
$this->filename = $template->getTemplateName(); $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) { if (null === $template || $this->lineno > -1) {
return; return;
} }
@@ -217,11 +332,6 @@ class Twig_Error extends Exception
$r = new ReflectionObject($template); $r = new ReflectionObject($template);
$file = $r->getFileName(); $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); $exceptions = array($e = $this);
while (($e instanceof self || method_exists($e, 'getPrevious')) && $e = $e->getPrevious()) { while (($e instanceof self || method_exists($e, 'getPrevious')) && $e = $e->getPrevious()) {
$exceptions[] = $e; $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. * This file is part of Twig.
* *
* (c) 2010 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * file that was distributed with this source code.
@@ -24,8 +24,17 @@
*/ */
class Twig_Error_Loader extends Twig_Error 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. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* (c) 2009 Armin Ronacher * (c) Armin Ronacher
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * file that was distributed with this source code.
@@ -18,3 +18,5 @@
class Twig_Error_Runtime extends Twig_Error 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. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* (c) 2009 Armin Ronacher * (c) Armin Ronacher
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * file that was distributed with this source code.
@@ -17,4 +17,39 @@
*/ */
class Twig_Error_Syntax extends Twig_Error 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. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * file that was distributed with this source code.
@@ -27,3 +27,5 @@ interface Twig_ExistsLoaderInterface
*/ */
public function exists($name); public function exists($name);
} }
class_alias('Twig_ExistsLoaderInterface', 'Twig\Loader\ExistsLoaderInterface', false);

View File

@@ -3,8 +3,8 @@
/* /*
* This file is part of Twig. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* (c) 2009 Armin Ronacher * (c) Armin Ronacher
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * file that was distributed with this source code.
@@ -19,6 +19,8 @@
* @see http://en.wikipedia.org/wiki/Operator-precedence_parser * @see http://en.wikipedia.org/wiki/Operator-precedence_parser
* *
* @author Fabien Potencier <fabien@symfony.com> * @author Fabien Potencier <fabien@symfony.com>
*
* @internal
*/ */
class Twig_ExpressionParser class Twig_ExpressionParser
{ {
@@ -29,11 +31,23 @@ class Twig_ExpressionParser
protected $unaryOperators; protected $unaryOperators;
protected $binaryOperators; 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->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) public function parseExpression($precedence = 0)
@@ -44,7 +58,11 @@ class Twig_ExpressionParser
$op = $this->binaryOperators[$token->getValue()]; $op = $this->binaryOperators[$token->getValue()];
$this->parser->getStream()->next(); $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); $expr = call_user_func($op['callable'], $this->parser, $expr);
} else { } else {
$expr1 = $this->parseExpression(self::OPERATOR_LEFT === $op['associativity'] ? $op['precedence'] + 1 : $op['precedence']); $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'; $negClass = 'Twig_Node_Expression_Unary_Neg';
$posClass = 'Twig_Node_Expression_Unary_Pos'; $posClass = 'Twig_Node_Expression_Unary_Pos';
if (!(in_array($ref->getName(), array($negClass, $posClass)) || $ref->isSubclassOf($negClass) || $ref->isSubclassOf($posClass))) { 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(); $this->parser->getStream()->next();
@@ -187,7 +205,7 @@ class Twig_ExpressionParser
} elseif ($token->test(Twig_Token::PUNCTUATION_TYPE, '{')) { } elseif ($token->test(Twig_Token::PUNCTUATION_TYPE, '{')) {
$node = $this->parseHashExpression(); $node = $this->parseHashExpression();
} else { } 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); $expr = array_shift($nodes);
foreach ($nodes as $node) { 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; return $expr;
@@ -278,7 +296,7 @@ class Twig_ExpressionParser
} else { } else {
$current = $stream->getCurrent(); $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 (:)'); $stream->expect(Twig_Token::PUNCTUATION_TYPE, ':', 'A hash key must be followed by a colon (:)');
@@ -317,20 +335,25 @@ class Twig_ExpressionParser
case 'parent': case 'parent':
$this->parseArguments(); $this->parseArguments();
if (!count($this->parser->getBlockStack())) { 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()) { 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); return new Twig_Node_Expression_Parent($this->parser->peekBlockStack(), $line);
case 'block': 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': case 'attribute':
$args = $this->parseArguments(); $args = $this->parseArguments();
if (count($args) < 2) { 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); 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); $arg = new Twig_Node_Expression_Constant($token->getValue(), $lineno);
if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) { if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
$type = Twig_TemplateInterface::METHOD_CALL; $type = Twig_Template::METHOD_CALL;
foreach ($this->parseArguments() as $n) { foreach ($this->parseArguments() as $n) {
$arguments->addElement($n); $arguments->addElement($n);
} }
} }
} else { } 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 ($node instanceof Twig_Node_Expression_Name && null !== $this->parser->getImportedSymbol('template', $node->getAttribute('name'))) {
if (!$arg instanceof Twig_Node_Expression_Constant) { 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'); $name = $arg->getAttribute('value');
if ($this->parser->isReservedMacroName($name)) { 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); $node = new Twig_Node_Expression_MethodCall($node, 'get'.$name, $arguments, $lineno);
@@ -500,7 +523,7 @@ class Twig_ExpressionParser
$name = null; $name = null;
if ($namedArguments && $token = $stream->nextIf(Twig_Token::OPERATOR_TYPE, '=')) { if ($namedArguments && $token = $stream->nextIf(Twig_Token::OPERATOR_TYPE, '=')) {
if (!$value instanceof Twig_Node_Expression_Name) { 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'); $name = $value->getAttribute('name');
@@ -508,7 +531,7 @@ class Twig_ExpressionParser
$value = $this->parsePrimaryExpression(); $value = $this->parsePrimaryExpression();
if (!$this->checkConstantExpression($value)) { 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 { } else {
$value = $this->parseExpression(); $value = $this->parseExpression();
@@ -536,15 +559,17 @@ class Twig_ExpressionParser
public function parseAssignmentExpression() public function parseAssignmentExpression()
{ {
$stream = $this->parser->getStream();
$targets = array(); $targets = array();
while (true) { while (true) {
$token = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE, null, 'Only variables can be assigned to'); $token = $stream->expect(Twig_Token::NAME_TYPE, null, 'Only variables can be assigned to');
if (in_array($token->getValue(), array('true', 'false', 'none'))) { $value = $token->getValue();
throw new Twig_Error_Syntax(sprintf('You cannot assign a value to "%s"', $token->getValue()), $token->getLine(), $this->parser->getFilename()); 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; break;
} }
} }
@@ -565,17 +590,96 @@ class Twig_ExpressionParser
return new Twig_Node($targets); return new Twig_Node($targets);
} }
private function parseNotTestExpression(Twig_NodeInterface $node)
{
return new Twig_Node_Expression_Unary_Not($this->parseTestExpression($node), $this->parser->getCurrentToken()->getLine());
}
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) protected function getFunctionNodeClass($name, $line)
{ {
$env = $this->parser->getEnvironment(); 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()));
if (false === $function = $env->getFunction($name)) { throw $e;
$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)); 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);
throw new Twig_Error_Syntax($message, $line, $this->parser->getFilename()); @trigger_error($message, E_USER_DEPRECATED);
} }
if ($function instanceof Twig_SimpleFunction) { if ($function instanceof Twig_SimpleFunction) {
@@ -587,15 +691,25 @@ class Twig_ExpressionParser
protected function getFilterNodeClass($name, $line) 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)) { throw $e;
$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)); 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);
throw new Twig_Error_Syntax($message, $line, $this->parser->getFilename()); @trigger_error($message, E_USER_DEPRECATED);
} }
if ($filter instanceof Twig_SimpleFilter) { if ($filter instanceof Twig_SimpleFilter) {
@@ -623,3 +737,5 @@ class Twig_ExpressionParser
return true; return true;
} }
} }
class_alias('Twig_ExpressionParser', 'Twig\ExpressionParser', false);

View File

@@ -3,91 +3,67 @@
/* /*
* This file is part of Twig. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
abstract class Twig_Extension implements Twig_ExtensionInterface abstract class Twig_Extension implements Twig_ExtensionInterface
{ {
/** /**
* Initializes the runtime environment. * @deprecated since 1.23 (to be removed in 2.0), implement Twig_Extension_InitRuntimeInterface instead
*
* This is where you can load some file that contains filter functions for instance.
*
* @param Twig_Environment $environment The current Twig_Environment instance
*/ */
public function initRuntime(Twig_Environment $environment) 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() public function getTokenParsers()
{ {
return array(); 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() public function getNodeVisitors()
{ {
return array(); return array();
} }
/**
* Returns a list of filters to add to the existing list.
*
* @return array An array of filters
*/
public function getFilters() public function getFilters()
{ {
return array(); return array();
} }
/**
* Returns a list of tests to add to the existing list.
*
* @return array An array of tests
*/
public function getTests() public function getTests()
{ {
return array(); return array();
} }
/**
* Returns a list of functions to add to the existing list.
*
* @return array An array of functions
*/
public function getFunctions() public function getFunctions()
{ {
return array(); return array();
} }
/**
* Returns a list of operators to add to the existing list.
*
* @return array An array of operators
*/
public function getOperators() public function getOperators()
{ {
return array(); return array();
} }
/** /**
* Returns a list of global variables to add to the existing list. * @deprecated since 1.23 (to be removed in 2.0), implement Twig_Extension_GlobalsInterface instead
*
* @return array An array of global variables
*/ */
public function getGlobals() public function getGlobals()
{ {
return array(); 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');

File diff suppressed because it is too large Load Diff

View File

@@ -3,18 +3,17 @@
/* /*
* This file is part of Twig. * This file is part of Twig.
* *
* (c) 2011 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
/**
* @final
*/
class Twig_Extension_Debug extends Twig_Extension 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() public function getFunctions()
{ {
// dump is safe if var_dump is overridden by xdebug // 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 // 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 // xdebug.overload_var_dump produces HTML only when html_errors is also enabled
&& (false === ini_get('html_errors') || ini_get('html_errors')) && (false === ini_get('html_errors') || ini_get('html_errors'))
|| 'cli' === php_sapi_name() || 'cli' === PHP_SAPI
; ;
return array( 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() public function getName()
{ {
return 'debug'; return 'debug';
@@ -69,3 +63,5 @@ function twig_var_dump(Twig_Environment $env, $context)
return ob_get_clean(); 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. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
/**
* @final
*/
class Twig_Extension_Escaper extends Twig_Extension class Twig_Extension_Escaper extends Twig_Extension
{ {
protected $defaultStrategy; protected $defaultStrategy;
/**
* @param string|false|callable $defaultStrategy An escaping strategy
*
* @see setDefaultStrategy()
*/
public function __construct($defaultStrategy = 'html') public function __construct($defaultStrategy = 'html')
{ {
$this->setDefaultStrategy($defaultStrategy); $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() public function getTokenParsers()
{ {
return array(new Twig_TokenParser_AutoEscape()); 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() public function getNodeVisitors()
{ {
return array(new Twig_NodeVisitor_Escaper()); 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() public function getFilters()
{ {
return array( 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. * Sets the default strategy to use when not defined by the user.
* *
* The strategy can be a valid PHP callback that takes the template * 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) public function setDefaultStrategy($defaultStrategy)
{ {
// for BC // for BC
if (true === $defaultStrategy) { 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'; $defaultStrategy = 'html';
} }
if ('filename' === $defaultStrategy) { 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'); $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. * 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, // disable string callables to avoid calling a function named html or js,
// or any other upcoming escaping strategy // or any other upcoming escaping strategy
if (!is_string($this->defaultStrategy) && is_callable($this->defaultStrategy)) { if (!is_string($this->defaultStrategy) && false !== $this->defaultStrategy) {
return call_user_func($this->defaultStrategy, $filename); return call_user_func($this->defaultStrategy, $name);
} }
return $this->defaultStrategy; return $this->defaultStrategy;
} }
/**
* Returns the name of the extension.
*
* @return string The extension name
*/
public function getName() public function getName()
{ {
return 'escaper'; return 'escaper';
@@ -111,3 +108,5 @@ function twig_raw_filter($string)
{ {
return $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. * This file is part of Twig.
* *
* (c) 2010 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
/**
* @final
*/
class Twig_Extension_Optimizer extends Twig_Extension class Twig_Extension_Optimizer extends Twig_Extension
{ {
protected $optimizers; protected $optimizers;
@@ -17,19 +21,15 @@ class Twig_Extension_Optimizer extends Twig_Extension
$this->optimizers = $optimizers; $this->optimizers = $optimizers;
} }
/**
* {@inheritdoc}
*/
public function getNodeVisitors() public function getNodeVisitors()
{ {
return array(new Twig_NodeVisitor_Optimizer($this->optimizers)); return array(new Twig_NodeVisitor_Optimizer($this->optimizers));
} }
/**
* {@inheritdoc}
*/
public function getName() public function getName()
{ {
return 'optimizer'; return 'optimizer';
} }
} }
class_alias('Twig_Extension_Optimizer', 'Twig\Extension\OptimizerExtension', false);

View File

@@ -3,7 +3,7 @@
/* /*
* This file is part of Twig. * This file is part of Twig.
* *
* (c) 2015 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * file that was distributed with this source code.
@@ -11,11 +11,11 @@
class Twig_Extension_Profiler extends Twig_Extension class Twig_Extension_Profiler extends Twig_Extension
{ {
private $actives; private $actives = array();
public function __construct(Twig_Profiler_Profile $profile) public function __construct(Twig_Profiler_Profile $profile)
{ {
$this->actives = array($profile); $this->actives[] = $profile;
} }
public function enter(Twig_Profiler_Profile $profile) public function enter(Twig_Profiler_Profile $profile)
@@ -34,19 +34,16 @@ class Twig_Extension_Profiler extends Twig_Extension
} }
} }
/**
* {@inheritdoc}
*/
public function getNodeVisitors() 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() public function getName()
{ {
return 'profiler'; 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. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
/**
* @final
*/
class Twig_Extension_Sandbox extends Twig_Extension class Twig_Extension_Sandbox extends Twig_Extension
{ {
protected $sandboxedGlobally; protected $sandboxedGlobally;
@@ -20,21 +24,11 @@ class Twig_Extension_Sandbox extends Twig_Extension
$this->sandboxedGlobally = $sandboxed; $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() public function getTokenParsers()
{ {
return array(new Twig_TokenParser_Sandbox()); 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() public function getNodeVisitors()
{ {
return array(new Twig_NodeVisitor_Sandbox()); return array(new Twig_NodeVisitor_Sandbox());
@@ -100,13 +94,10 @@ class Twig_Extension_Sandbox extends Twig_Extension
return $obj; return $obj;
} }
/**
* Returns the name of the extension.
*
* @return string The extension name
*/
public function getName() public function getName()
{ {
return 'sandbox'; return 'sandbox';
} }
} }
class_alias('Twig_Extension_Sandbox', 'Twig\Extension\SandboxExtension', false);

View File

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

View File

@@ -3,16 +3,17 @@
/* /*
* This file is part of Twig. * This file is part of Twig.
* *
* (c) 2012 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
/**
* @final
*/
class Twig_Extension_StringLoader extends Twig_Extension class Twig_Extension_StringLoader extends Twig_Extension
{ {
/**
* {@inheritdoc}
*/
public function getFunctions() public function getFunctions()
{ {
return array( return array(
@@ -20,9 +21,6 @@ class Twig_Extension_StringLoader extends Twig_Extension
); );
} }
/**
* {@inheritdoc}
*/
public function getName() public function getName()
{ {
return 'string_loader'; return 'string_loader';
@@ -37,11 +35,13 @@ class Twig_Extension_StringLoader extends Twig_Extension
* </pre> * </pre>
* *
* @param Twig_Environment $env A Twig_Environment instance * @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) 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. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * 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. * 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); public function initRuntime(Twig_Environment $environment);
/** /**
* Returns the token parser instances to add to the existing list. * 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(); public function getTokenParsers();
/** /**
* Returns the node visitor instances to add to the existing list. * 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(); public function getNodeVisitors();
/** /**
* Returns a list of filters to add to the existing list. * Returns a list of filters to add to the existing list.
* *
* @return array An array of filters * @return Twig_SimpleFilter[]
*/ */
public function getFilters(); public function getFilters();
/** /**
* Returns a list of tests to add to the existing list. * Returns a list of tests to add to the existing list.
* *
* @return array An array of tests * @return Twig_SimpleTest[]
*/ */
public function getTests(); public function getTests();
/** /**
* Returns a list of functions to add to the existing list. * Returns a list of functions to add to the existing list.
* *
* @return array An array of functions * @return Twig_SimpleFunction[]
*/ */
public function getFunctions(); public function getFunctions();
/** /**
* Returns a list of operators to add to the existing list. * 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(); public function getOperators();
@@ -71,6 +71,8 @@ interface Twig_ExtensionInterface
* Returns a list of global variables to add to the existing list. * Returns a list of global variables to add to the existing list.
* *
* @return array An array of global variables * @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(); public function getGlobals();
@@ -78,6 +80,11 @@ interface Twig_ExtensionInterface
* Returns the name of the extension. * Returns the name of the extension.
* *
* @return string The extension name * @return string The extension name
*
* @deprecated since 1.26 (to be removed in 2.0), not used anymore internally
*/ */
public function getName(); 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. * This file is part of Twig.
* *
* (c) 2015 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * file that was distributed with this source code.
@@ -13,7 +13,7 @@
* Default autoescaping strategy based on file names. * Default autoescaping strategy based on file names.
* *
* This strategy sets the HTML as the default autoescaping strategy, * 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 * Note that there is no runtime performance impact as the
* default autoescaping strategy is set at compilation time. * 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. * 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)) { if (in_array(substr($name, -1), array('/', '\\'))) {
return 'html'; 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': case 'js':
return 'js'; return 'js';
@@ -44,6 +50,11 @@ class Twig_FileExtensionEscapingStrategy
case 'txt': case 'txt':
return false; return false;
default:
return 'html';
} }
} }
} }
class_alias('Twig_FileExtensionEscapingStrategy', 'Twig\FileExtensionEscapingStrategy', false);

View File

@@ -3,12 +3,14 @@
/* /*
* This file is part of Twig. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * 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. * Represents a template filter.
* *

View File

@@ -3,12 +3,14 @@
/* /*
* This file is part of Twig. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * 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. * Represents a function template filter.
* *

View File

@@ -3,12 +3,14 @@
/* /*
* This file is part of Twig. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * 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. * Represents a method template filter.
* *
@@ -35,6 +37,6 @@ class Twig_Filter_Method extends Twig_Filter
public function compile() 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. * This file is part of Twig.
* *
* (c) 2011 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * 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. * Represents a template filter as a node.
* *

View File

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

View File

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

View File

@@ -3,12 +3,14 @@
/* /*
* This file is part of Twig. * This file is part of Twig.
* *
* (c) 2010 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * 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. * Represents a template function.
* *

View File

@@ -3,13 +3,15 @@
/* /*
* This file is part of Twig. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* (c) 2010 Arnaud Le Blanc * (c) Arnaud Le Blanc
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * 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. * Represents a function template function.
* *

View File

@@ -3,13 +3,15 @@
/* /*
* This file is part of Twig. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* (c) 2010 Arnaud Le Blanc * (c) Arnaud Le Blanc
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * 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. * Represents a method template function.
* *
@@ -36,6 +38,6 @@ class Twig_Function_Method extends Twig_Function
public function compile() 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. * This file is part of Twig.
* *
* (c) 2011 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * 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. * Represents a template function as a node.
* *

View File

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

View File

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

View File

@@ -3,8 +3,8 @@
/* /*
* This file is part of Twig. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* (c) 2009 Armin Ronacher * (c) Armin Ronacher
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * file that was distributed with this source code.
@@ -26,6 +26,7 @@ class Twig_Lexer implements Twig_LexerInterface
protected $states; protected $states;
protected $brackets; protected $brackets;
protected $env; protected $env;
// to be renamed to $name in 2.0 (where it is private)
protected $filename; protected $filename;
protected $options; protected $options;
protected $regexes; protected $regexes;
@@ -33,6 +34,8 @@ class Twig_Lexer implements Twig_LexerInterface
protected $positions; protected $positions;
protected $currentVarBlockLine; protected $currentVarBlockLine;
private $source;
const STATE_DATA = 0; const STATE_DATA = 0;
const STATE_BLOCK = 1; const STATE_BLOCK = 1;
const STATE_VAR = 2; const STATE_VAR = 2;
@@ -72,11 +75,19 @@ class Twig_Lexer implements Twig_LexerInterface
); );
} }
/** public function tokenize($code, $name = null)
* {@inheritdoc}
*/
public function tokenize($code, $filename = 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) { if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
$mbEncoding = mb_internal_encoding(); $mbEncoding = mb_internal_encoding();
mb_internal_encoding('ASCII'); mb_internal_encoding('ASCII');
@@ -84,8 +95,8 @@ class Twig_Lexer implements Twig_LexerInterface
$mbEncoding = null; $mbEncoding = null;
} }
$this->code = str_replace(array("\r\n", "\r"), "\n", $code); $this->code = str_replace(array("\r\n", "\r"), "\n", $this->source->getCode());
$this->filename = $filename; $this->filename = $this->source->getName();
$this->cursor = 0; $this->cursor = 0;
$this->lineno = 1; $this->lineno = 1;
$this->end = strlen($this->code); $this->end = strlen($this->code);
@@ -129,14 +140,14 @@ class Twig_Lexer implements Twig_LexerInterface
if (!empty($this->brackets)) { if (!empty($this->brackets)) {
list($expect, $lineno) = array_pop($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) { if ($mbEncoding) {
mb_internal_encoding($mbEncoding); mb_internal_encoding($mbEncoding);
} }
return new Twig_TokenStream($this->tokens, $this->filename); return new Twig_TokenStream($this->tokens, $this->source);
} }
protected function lexData() protected function lexData()
@@ -224,7 +235,7 @@ class Twig_Lexer implements Twig_LexerInterface
$this->moveCursor($match[0]); $this->moveCursor($match[0]);
if ($this->cursor >= $this->end) { 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 // closing bracket
elseif (false !== strpos(')]}', $this->code[$this->cursor])) { elseif (false !== strpos(')]}', $this->code[$this->cursor])) {
if (empty($this->brackets)) { 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); list($expect, $lineno) = array_pop($this->brackets);
if ($this->code[$this->cursor] != strtr($expect, '([{', ')]}')) { 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 // unlexable
else { 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) 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)) { 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); $text = substr($this->code, $this->cursor, $match[0][1] - $this->cursor);
@@ -304,7 +319,7 @@ class Twig_Lexer implements Twig_LexerInterface
protected function lexComment() protected function lexComment()
{ {
if (!preg_match($this->regexes['lex_comment'], $this->code, $match, PREG_OFFSET_CAPTURE, $this->cursor)) { 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]); $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)) { } elseif (preg_match(self::REGEX_DQ_STRING_DELIM, $this->code, $match, null, $this->cursor)) {
list($expect, $lineno) = array_pop($this->brackets); list($expect, $lineno) = array_pop($this->brackets);
if ($this->code[$this->cursor] != '"') { 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(); $this->popState();
@@ -399,9 +414,11 @@ class Twig_Lexer implements Twig_LexerInterface
protected function popState() protected function popState()
{ {
if (0 === count($this->states)) { 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); $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. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * file that was distributed with this source code.
@@ -21,12 +21,12 @@ interface Twig_LexerInterface
/** /**
* Tokenizes a source code. * Tokenizes a source code.
* *
* @param string $code The source code * @param string|Twig_Source $code The source code
* @param string $filename A unique identifier for 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 * @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. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * file that was distributed with this source code.
@@ -19,20 +19,18 @@
* *
* This loader should only be used for unit testing. * This loader should only be used for unit testing.
* *
* @final
*
* @author Fabien Potencier <fabien@symfony.com> * @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(); protected $templates = array();
/** /**
* Constructor.
*
* @param array $templates An array of templates (keys are the names, and values are the source code) * @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; $this->templates = $templates;
} }
@@ -48,11 +46,10 @@ class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
$this->templates[(string) $name] = $template; $this->templates[(string) $name] = $template;
} }
/**
* {@inheritdoc}
*/
public function getSource($name) 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; $name = (string) $name;
if (!isset($this->templates[$name])) { if (!isset($this->templates[$name])) {
throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $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]; return $this->templates[$name];
} }
/** public function getSourceContext($name)
* {@inheritdoc} {
*/ $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) public function exists($name)
{ {
return isset($this->templates[(string) $name]); return isset($this->templates[(string) $name]);
} }
/**
* {@inheritdoc}
*/
public function getCacheKey($name) public function getCacheKey($name)
{ {
$name = (string) $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)); 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) public function isFresh($name, $time)
{ {
$name = (string) $name; $name = (string) $name;
@@ -95,3 +93,5 @@ class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
return true; return true;
} }
} }
class_alias('Twig_Loader_Array', 'Twig\Loader\ArrayLoader', false);

View File

@@ -3,7 +3,7 @@
/* /*
* This file is part of Twig. * This file is part of Twig.
* *
* (c) 2011 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * file that was distributed with this source code.
@@ -12,17 +12,17 @@
/** /**
* Loads templates from other loaders. * Loads templates from other loaders.
* *
* @final
*
* @author Fabien Potencier <fabien@symfony.com> * @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(); private $hasSourceCache = array();
protected $loaders = array(); protected $loaders = array();
/** /**
* Constructor. * @param Twig_LoaderInterface[] $loaders
*
* @param Twig_LoaderInterface[] $loaders An array of loader instances
*/ */
public function __construct(array $loaders = array()) 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) public function addLoader(Twig_LoaderInterface $loader)
{ {
$this->loaders[] = $loader; $this->loaders[] = $loader;
$this->hasSourceCache = array(); $this->hasSourceCache = array();
} }
/**
* {@inheritdoc}
*/
public function getSource($name) 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(); $exceptions = array();
foreach ($this->loaders as $loader) { foreach ($this->loaders as $loader) {
if ($loader instanceof Twig_ExistsLoaderInterface && !$loader->exists($name)) { 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) public function exists($name)
{ {
$name = (string) $name; $name = (string) $name;
@@ -84,7 +97,11 @@ class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
} }
try { try {
$loader->getSource($name); if ($loader instanceof Twig_SourceContextLoaderInterface) {
$loader->getSourceContext($name);
} else {
$loader->getSource($name);
}
return $this->hasSourceCache[$name] = true; return $this->hasSourceCache[$name] = true;
} catch (Twig_Error_Loader $e) { } catch (Twig_Error_Loader $e) {
@@ -94,9 +111,6 @@ class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
return $this->hasSourceCache[$name] = false; return $this->hasSourceCache[$name] = false;
} }
/**
* {@inheritdoc}
*/
public function getCacheKey($name) public function getCacheKey($name)
{ {
$exceptions = array(); $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) public function isFresh($name, $time)
{ {
$exceptions = array(); $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. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * file that was distributed with this source code.
@@ -14,21 +14,28 @@
* *
* @author Fabien Potencier <fabien@symfony.com> * @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. */ /** Identifier of the main namespace. */
const MAIN_NAMESPACE = '__main__'; const MAIN_NAMESPACE = '__main__';
protected $paths = array(); protected $paths = array();
protected $cache = 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())
* @param string|array $paths A path or an array of paths where to look for templates
*/ */
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) { if ($paths) {
$this->setPaths($paths); $this->setPaths($paths);
} }
@@ -80,17 +87,18 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
* Adds a path where templates are stored. * Adds a path where templates are stored.
* *
* @param string $path A path where to look for templates * @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 * @throws Twig_Error_Loader
*/ */
public function addPath($path, $namespace = self::MAIN_NAMESPACE) public function addPath($path, $namespace = self::MAIN_NAMESPACE)
{ {
// invalidate the cache // invalidate the cache
$this->cache = array(); $this->cache = $this->errorCache = array();
if (!is_dir($path)) { $checkPath = $this->isAbsolutePath($path) ? $path : $this->rootPath.$path;
throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $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, '/\\'); $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. * Prepends a path where templates are stored.
* *
* @param string $path A path where to look for templates * @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 * @throws Twig_Error_Loader
*/ */
public function prependPath($path, $namespace = self::MAIN_NAMESPACE) public function prependPath($path, $namespace = self::MAIN_NAMESPACE)
{ {
// invalidate the cache // invalidate the cache
$this->cache = array(); $this->cache = $this->errorCache = array();
if (!is_dir($path)) { $checkPath = $this->isAbsolutePath($path) ? $path : $this->rootPath.$path;
throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path)); if (!is_dir($checkPath)) {
throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist ("%s").', $path, $checkPath));
} }
$path = rtrim($path, '/\\'); $path = rtrim($path, '/\\');
@@ -122,25 +131,31 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
} }
} }
/**
* {@inheritdoc}
*/
public function getSource($name) 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)); return file_get_contents($this->findTemplate($name));
} }
/** public function getSourceContext($name)
* {@inheritdoc}
*/
public function getCacheKey($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) public function exists($name)
{ {
$name = $this->normalizeName($name); $name = $this->normalizeName($name);
@@ -150,17 +165,14 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
} }
try { try {
$this->findTemplate($name); return false !== $this->findTemplate($name, false);
return true;
} catch (Twig_Error_Loader $exception) { } 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; return false;
} }
} }
/**
* {@inheritdoc}
*/
public function isFresh($name, $time) public function isFresh($name, $time)
{ {
return filemtime($this->findTemplate($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) protected function findTemplate($name)
{ {
$throw = func_num_args() > 1 ? func_get_arg(1) : true;
$name = $this->normalizeName($name); $name = $this->normalizeName($name);
if (isset($this->cache[$name])) { if (isset($this->cache[$name])) {
return $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); $this->validateName($name);
list($namespace, $shortname) = $this->parseName($name); list($namespace, $shortname) = $this->parseName($name);
if (!isset($this->paths[$namespace])) { 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) { foreach ($this->paths[$namespace] as $path) {
if (!$this->isAbsolutePath($path)) {
$path = $this->rootPath.'/'.$path;
}
if (is_file($path.'/'.$shortname)) { if (is_file($path.'/'.$shortname)) {
if (false !== $realpath = realpath($path.'/'.$shortname)) { if (false !== $realpath = realpath($path.'/'.$shortname)) {
return $this->cache[$name] = $realpath; 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) 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) protected function normalizeName($name)
{ {
return preg_replace('#/{2,}#', '/', strtr((string) $name, '\\', '/')); return preg_replace('#/{2,}#', '/', str_replace('\\', '/', (string) $name));
} }
protected function validateName($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. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * 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. * Loads a template from a string.
* *
@@ -21,37 +23,34 @@
* *
* @deprecated since 1.18.1 (to be removed in 2.0) * @deprecated since 1.18.1 (to be removed in 2.0)
* *
* @internal
*
* @author Fabien Potencier <fabien@symfony.com> * @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) 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; return $name;
} }
/** public function getSourceContext($name)
* {@inheritdoc} {
*/ return new Twig_Source($name, $name);
}
public function exists($name) public function exists($name)
{ {
return true; return true;
} }
/**
* {@inheritdoc}
*/
public function getCacheKey($name) public function getCacheKey($name)
{ {
return $name; return $name;
} }
/**
* {@inheritdoc}
*/
public function isFresh($name, $time) public function isFresh($name, $time)
{ {
return true; return true;

View File

@@ -3,7 +3,7 @@
/* /*
* This file is part of Twig. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * file that was distributed with this source code.
@@ -24,6 +24,8 @@ interface Twig_LoaderInterface
* @return string The template source code * @return string The template source code
* *
* @throws Twig_Error_Loader When $name is not found * @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); public function getSource($name);
@@ -51,3 +53,5 @@ interface Twig_LoaderInterface
*/ */
public function isFresh($name, $time); 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. * This file is part of Twig.
* *
* (c) 2010 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * 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); 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. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* (c) 2009 Armin Ronacher * (c) Armin Ronacher
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * file that was distributed with this source code.
@@ -22,6 +22,8 @@ class Twig_Node implements Twig_NodeInterface
protected $lineno; protected $lineno;
protected $tag; protected $tag;
private $name;
/** /**
* Constructor. * Constructor.
* *
@@ -35,6 +37,11 @@ class Twig_Node implements Twig_NodeInterface
*/ */
public function __construct(array $nodes = array(), array $attributes = array(), $lineno = 0, $tag = null) 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->nodes = $nodes;
$this->attributes = $attributes; $this->attributes = $attributes;
$this->lineno = $lineno; $this->lineno = $lineno;
@@ -74,6 +81,8 @@ class Twig_Node implements Twig_NodeInterface
*/ */
public function toXml($asDom = false) 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 = new DOMDocument('1.0', 'UTF-8');
$dom->formatOutput = true; $dom->formatOutput = true;
$dom->appendChild($xml = $dom->createElement('twig')); $dom->appendChild($xml = $dom->createElement('twig'));
@@ -99,7 +108,7 @@ class Twig_Node implements Twig_NodeInterface
$node->appendChild($child); $node->appendChild($child);
} }
return $asDom ? $dom : $dom->saveXml(); return $asDom ? $dom : $dom->saveXML();
} }
public function compile(Twig_Compiler $compiler) 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() 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; return $this->lineno;
} }
@@ -120,11 +139,7 @@ class Twig_Node implements Twig_NodeInterface
} }
/** /**
* Returns true if the attribute is defined. * @return bool
*
* @param string $name The attribute name
*
* @return bool true if the attribute is defined, false otherwise
*/ */
public function hasAttribute($name) 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 * @return mixed
*/ */
public function getAttribute($name) 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 string $name
* @param mixed $value * @param mixed $value
*/ */
@@ -158,21 +167,12 @@ class Twig_Node implements Twig_NodeInterface
$this->attributes[$name] = $value; $this->attributes[$name] = $value;
} }
/**
* Removes an attribute by name.
*
* @param string $name
*/
public function removeAttribute($name) public function removeAttribute($name)
{ {
unset($this->attributes[$name]); unset($this->attributes[$name]);
} }
/** /**
* Returns true if the node with the given name exists.
*
* @param string $name
*
* @return bool * @return bool
*/ */
public function hasNode($name) 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 * @return Twig_Node
*/ */
public function getNode($name) public function getNode($name)
@@ -196,22 +192,15 @@ class Twig_Node implements Twig_NodeInterface
return $this->nodes[$name]; return $this->nodes[$name];
} }
/**
* Sets a node.
*
* @param string $name
* @param Twig_Node $node
*/
public function setNode($name, $node = null) 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; $this->nodes[$name] = $node;
} }
/**
* Removes a node by name.
*
* @param string $name
*/
public function removeNode($name) public function removeNode($name)
{ {
unset($this->nodes[$name]); unset($this->nodes[$name]);
@@ -226,4 +215,42 @@ class Twig_Node implements Twig_NodeInterface
{ {
return new ArrayIterator($this->nodes); 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. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * 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); 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) public function compile(Twig_Compiler $compiler)
{ {
$compiler->subcompile($this->getNode('body')); $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. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* (c) 2009 Armin Ronacher * (c) Armin Ronacher
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * 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); 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) public function compile(Twig_Compiler $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. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* (c) 2009 Armin Ronacher * (c) Armin Ronacher
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * 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); 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) public function compile(Twig_Compiler $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. * This file is part of Twig.
* *
* (c) 2011 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * file that was distributed with this source code.
@@ -17,3 +17,5 @@
class Twig_Node_Body extends Twig_Node 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. * This file is part of Twig.
* *
* (c) 2015 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * 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 (array('tags', 'filters', 'functions') as $type) {
foreach ($this->{'used'.ucfirst($type)} as $name => $node) { foreach ($this->{'used'.ucfirst($type)} as $name => $node) {
if ($node instanceof Twig_Node) { if ($node instanceof Twig_Node) {
${$type}[$name] = $node->getLine(); ${$type}[$name] = $node->getTemplateLine();
} else { } else {
${$type}[$node] = null; ${$type}[$node] = null;
} }
@@ -46,7 +46,7 @@ class Twig_Node_CheckSecurity extends Twig_Node
->write('$functions = ')->repr(array_filter($functions))->raw(";\n\n") ->write('$functions = ')->repr(array_filter($functions))->raw(";\n\n")
->write("try {\n") ->write("try {\n")
->indent() ->indent()
->write("\$this->env->getExtension('sandbox')->checkSecurity(\n") ->write("\$this->env->getExtension('Twig_Extension_Sandbox')->checkSecurity(\n")
->indent() ->indent()
->write(!$tags ? "array(),\n" : "array('".implode("', '", array_keys($tags))."'),\n") ->write(!$tags ? "array(),\n" : "array('".implode("', '", array_keys($tags))."'),\n")
->write(!$filters ? "array(),\n" : "array('".implode("', '", array_keys($filters))."'),\n") ->write(!$filters ? "array(),\n" : "array('".implode("', '", array_keys($filters))."'),\n")
@@ -56,7 +56,7 @@ class Twig_Node_CheckSecurity extends Twig_Node
->outdent() ->outdent()
->write("} catch (Twig_Sandbox_SecurityError \$e) {\n") ->write("} catch (Twig_Sandbox_SecurityError \$e) {\n")
->indent() ->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") ->write("if (\$e instanceof Twig_Sandbox_SecurityNotAllowedTagError && isset(\$tags[\$e->getTagName()])) {\n")
->indent() ->indent()
->write("\$e->setTemplateLine(\$tags[\$e->getTagName()]);\n") ->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. * This file is part of Twig.
* *
* (c) 2011 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * 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); 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) public function compile(Twig_Compiler $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. * This file is part of Twig.
* *
* (c) 2012 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * file that was distributed with this source code.
@@ -17,11 +17,13 @@
class Twig_Node_Embed extends Twig_Node_Include 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) // 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); 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); $this->setAttribute('index', $index);
} }
@@ -29,14 +31,16 @@ class Twig_Node_Embed extends Twig_Node_Include
{ {
$compiler $compiler
->write('$this->loadTemplate(') ->write('$this->loadTemplate(')
->string($this->getAttribute('filename')) ->string($this->getAttribute('name'))
->raw(', ') ->raw(', ')
->repr($compiler->getFilename()) ->repr($this->getTemplateName())
->raw(', ') ->raw(', ')
->repr($this->getLine()) ->repr($this->getTemplateLine())
->raw(', ') ->raw(', ')
->string($this->getAttribute('index')) ->string($this->getAttribute('index'))
->raw(')') ->raw(')')
; ;
} }
} }
class_alias('Twig_Node_Embed', 'Twig\Node\EmbedNode', false);

View File

@@ -3,8 +3,8 @@
/* /*
* This file is part of Twig. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* (c) 2009 Armin Ronacher * (c) Armin Ronacher
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * file that was distributed with this source code.
@@ -18,3 +18,5 @@
abstract class Twig_Node_Expression extends Twig_Node 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. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * 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) { foreach ($this->getKeyValuePairs() as $pair) {
// we compare the string representation of the keys // we compare the string representation of the keys
// to avoid comparing the line numbers which are not relevant here. // 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; 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) public function addElement(Twig_Node_Expression $value, Twig_Node_Expression $key = null)
{ {
if (null === $key) { 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); 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) public function compile(Twig_Compiler $compiler)
{ {
$compiler->raw('array('); $compiler->raw('array(');
@@ -84,3 +79,5 @@ class Twig_Node_Expression_Array extends Twig_Node_Expression
$compiler->raw(')'); $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. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* (c) 2009 Armin Ronacher * (c) Armin Ronacher
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * file that was distributed with this source code.
@@ -12,11 +12,6 @@
class Twig_Node_Expression_AssignName extends Twig_Node_Expression_Name 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) public function compile(Twig_Compiler $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. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* (c) 2009 Armin Ronacher * (c) Armin Ronacher
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * 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); 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) public function compile(Twig_Compiler $compiler)
{ {
$compiler $compiler
@@ -38,3 +33,5 @@ abstract class Twig_Node_Expression_Binary extends Twig_Node_Expression
abstract public function operator(Twig_Compiler $compiler); 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. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* (c) 2009 Armin Ronacher * (c) Armin Ronacher
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * 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('+'); 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. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* (c) 2009 Armin Ronacher * (c) Armin Ronacher
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * 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('&&'); 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. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* (c) 2009 Armin Ronacher * (c) Armin Ronacher
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * 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('&'); 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. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* (c) 2009 Armin Ronacher * (c) Armin Ronacher
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * 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('|'); 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. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* (c) 2009 Armin Ronacher * (c) Armin Ronacher
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * 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('^'); 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. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* (c) 2009 Armin Ronacher * (c) Armin Ronacher
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * 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('.'); 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. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* (c) 2009 Armin Ronacher * (c) Armin Ronacher
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * 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('/'); 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. * This file is part of Twig.
* *
* (c) 2013 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * 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(''); 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. * This file is part of Twig.
* *
* (c) 2010 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * 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('=='); 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. * This file is part of Twig.
* *
* (c) 2009 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
class Twig_Node_Expression_Binary_FloorDiv extends Twig_Node_Expression_Binary 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) public function compile(Twig_Compiler $compiler)
{ {
$compiler->raw('intval(floor('); $compiler->raw('(int) floor(');
parent::compile($compiler); parent::compile($compiler);
$compiler->raw('))'); $compiler->raw(')');
} }
public function operator(Twig_Compiler $compiler) public function operator(Twig_Compiler $compiler)
@@ -27,3 +22,5 @@ class Twig_Node_Expression_Binary_FloorDiv extends Twig_Node_Expression_Binary
return $compiler->raw('/'); 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. * This file is part of Twig.
* *
* (c) 2010 Fabien Potencier * (c) Fabien Potencier
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * 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('>'); 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