Compare commits

..

127 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
slawkens1
b83fb05b82 * update to 0.7.4 2017-12-24 09:50:53 +01:00
slawkens1
cf12265cd8 * fixed displaying of percent bar on tibian signature 2017-12-24 09:37:28 +01:00
slawkens1
e4110a6981 * automatically update highscores_ids_hidden for users who installed myaac before
* update TODO
2017-12-21 22:08:47 +01:00
slawkens1
412908026d * inform user about Twig cache failure on installation, instead of http 500 error
* when dir system/cache is not writable by the webserver, then show some
nice notice to the user about it instead of http 500 error
* remember client version and usage stats checkbox in session on install
* fixed some small warning introducted yesterday about
highscores_ids_hidden
* updated TODO
2017-12-19 23:32:30 +01:00
slawkens1
8a7887cf06 * for compability 2017-12-19 00:05:49 +01:00
slawkens1
779dd003dd * update to 0.7.3
* better solution for hidding samples (configurable)
* removed players.is_sample field
2017-12-19 00:01:59 +01:00
slawkens1
0b2895dc56 * fixed some warnings on install on servers using account.id
* added version 772 constant to install client choose (OTHire)
* forgot to add is_sample to samples on install
2017-12-18 23:30:18 +01:00
slawkens1
fed5d08703 * updated TODO 2017-12-18 16:07:12 +01:00
slawkens1
f131f27ac3 * forgot something with latest commit 2017-12-18 09:56:43 +01:00
slawkens1
19dbbdcf4f * auto generate myaac cache & session prefix on install to be unique accross installations
* prevent adding duplicated newses with installation
* players.is_sample to prevent displaying on highscores
2017-12-18 09:54:42 +01:00
slawkens1
d650035980 * fixed last menu closing in tibiacom template 2017-12-18 09:09:24 +01:00
slawkens1
fbc803d09f * updated polish locale (translation) on install
* fixed hidding shop system menu on tibiacom template when disabled in
config
* some changes to sample characters: chanced town_id to 1, posx: 1000,
posy: 1000, posz: 1000 and default group_id to 1 so you can change
in-game outfits and they will be used
* fixed account.login redirect not working on tibiacom template
* installation: warn about wrong admin account name/id and password
* (internal) removed some duplicated code on install finish
* (internal) renamed installation step files to be in correct order
* added TODO file
* bumped version to 0.7.3
2017-12-18 09:01:54 +01:00
Slawomir Boczek
df4c594d4f * forgot to update CHANGELOG in 0.7.1 release 2017-12-15 16:36:51 +01:00
slawkens1
482445cb98 * switch to 0.7.2-dev 2017-12-13 19:21:11 +01:00
slawkens1
1c002c63a3 * update to 0.7.1 official release 2017-12-13 19:15:44 +01:00
slawkens1
cd366b6087 * changed some notice when version check is failed 2017-12-13 19:06:50 +01:00
slawkens1
83dc5b7650 * removed duplicated "Support List" menu item 2017-12-10 00:42:27 +01:00
slawkens1
d9675b1bc6 * (internal) moved changelog to twig
* added changelog menu item to kathrine template
* (fix) if changelog type or where is set to 0 then display as unknown
2017-11-23 17:55:42 +01:00
slawkens1
036520566c * fixed some php short tag
* fixed guild change description back button
2017-11-22 00:22:31 +01:00
slawkens1
8b302749ff * update to 0.7.1-dev 2017-11-20 18:16:13 +01:00
slawkens1
68b3e2cfee * update to 0.7.0 2017-11-20 18:08:12 +01:00
slawkens1
9ee6906e4d * fixed loading of custom pages 2017-11-20 17:48:25 +01:00
slawkens1
be38f51cc7 * updated phpmailer to version 5.2.26 (from 5.2.23) 2017-11-19 20:25:03 +01:00
slawkens1
aaed21f752 * (#30) fixed recovering account on servers that doesn't support salts 2017-11-19 15:22:57 +01:00
slawkens1
a1dddd7df8 * updated tinymce to version 4.7.2 2017-11-16 17:10:27 +01:00
slawkens1
f26795ca7a * im dumb :[! 2017-11-14 21:20:05 +01:00
slawkens1
7d6bbb3385 * verify install post values directly on config page and display error
* first usage report will be send after 7 days
2017-11-14 21:11:32 +01:00
slawkens1
37f792d9ce * forgot to commit twig templates in last commit
* added some validation in guilds actions if guild has been set to
prevent php notices
2017-11-14 20:27:59 +01:00
slawkens1
867c86d702 github is weird 2017-11-14 20:01:14 +01:00
slawkens1
05f8756a12 * fixed viewing pages with capital letters (like serverInfo) on case sensitive systems
* fixed changing comment of characters with space and other special
characters in name (#29)
* fixed viewing guilds with space and other special characters in name
(#29)
* (kathrine template) fixed displaying menu when no URI is set (URI =
'/')
* added some additional checks for Validator guildName and rankName if
name is empty
* (internal) new twig filter: urlencode, which is using urlencode php
function
2017-11-14 19:58:44 +01:00
slawkens1
c581c35a73 * update to 0.7.0-dev 2017-11-12 22:06:20 +01:00
slawkens1
b37bd5f0ae * github is weird 2017-11-12 21:56:47 +01:00
slawkens1
56a01e1e64 * fixed account email confirm function
* log some error info when mail cannot be send on account create
* fixed some weird include possibilities with forum and account actions
(verify action name)
* twig getLink function will now return with full url (BASE_URL
included)
* fixed some changelog PHP Notice warning
* (internal) shortened message functions
2017-11-12 21:55:12 +01:00
slawkens1
6aa58bddd8 * removed some tibiacom character typo '}?>' 2017-11-12 19:38:02 +01:00
slawkens1
0515f2825a * fixed loading hooks from plugin installed from command line 2017-11-10 23:03:54 +01:00
slawkens
0d37e07a0d * (fix) remove hooks from db on plugin deinstall 2017-11-09 11:31:02 +01:00
slawkens
ab69b182e6 Change version to 0.6.6-dev 2017-11-09 10:13:56 +01:00
slawkens
7b84614a79 * removed @version header from files, as it was hard to maintain 2017-11-09 10:02:15 +01:00
slawkens
361e536243 * admin panel, pages - link will be opened in new tab 2017-11-06 08:56:02 +01:00
slawkens
39fee6e57d * menus are now showed by the order they're saved into menu_categories configurable
* fixed visitors in admin panel showing, when cache is disabled
2017-11-06 08:50:06 +01:00
slawkens
56a0c6e6bf * some unimportant changes 2017-11-03 16:12:50 +01:00
slawkens
eb8993e746 * added back bug_report configurable cause some templates are using it 2017-11-03 10:46:23 +01:00
slawkens
edeb781600 Merge branch 'master' of https://github.com/slawkens/myaac 2017-11-03 09:43:51 +01:00
slawkens
9aa4e308c1 * reverted removing base href in html head
* added anonymous usage statistics reporting
* (fix) don't show templates that doesn't exist in Menus option in Admin Panel
* (fix) menu ordering by category
* (fix) showing changelog with urls in Admin Panel
* (internal) moved uninstall logic to Plugins class
2017-11-03 09:43:47 +01:00
slawkens1
05abf41b64 * removed some useless <br> in gallery box 2017-10-29 19:50:15 +01:00
slawkens
ac9c43e280 * fixed editing news 2017-10-26 16:25:24 +02:00
slawkens
c05e7f29c5 * fixed tibiacom menus extending on some pages 2017-10-26 16:07:10 +02:00
slawkens
583f3394fc * added featured article to tibiacom template (you can add them with add news button)
* added networks (facebook and twitter) and highscores (top 5) boxes to tibiacom template, configurable in templates/tibiacom/config.php
* fixed polls box in tibiacom template
* (internal) moved tibiacom boxes to separate directory
* (internal) renamed constant TICKET -> TICKER
2017-10-26 15:35:22 +02:00
slawkens
5e414ebda8 * added news ticker for kathrine template
* (internal) moved news tickers to twig template
* (internal) moved Forum class to separate file
* (internal) moved deprecated functions to compat.php
2017-10-25 09:50:12 +02:00
slawkens
21b1383c9a * update forum post after editing news (when forum post has been created) 2017-10-24 15:18:30 +02:00
slawkens
6c9e09ea73 * moved template menus to database, they're now dynamically loaded
* you can edit them in Admin Panel under 'Menus' option.
* you can also add custom links, like http://google.pl
* removed videos pages, as it can be easily added using custom Menus and Pages with insert Media
* removed bug_report configurable, its now enabled by default
2017-10-24 14:42:23 +02:00
slawkens
195ec4b11e * added some compat functions that are used by shop system 2017-10-24 04:59:52 +02:00
slawkens
bf988a7f6e * added tinymce editor to 'Pages' in admin panel
* enabled code plugin for tinymce which enabled raw html code editing
2017-10-23 14:59:43 +02:00
slawkens
25f8028ae3 * fixed some typos 2017-10-23 11:37:49 +02:00
slawkens
28299744c4 * fixed uninstalling plugin 2017-10-23 10:13:50 +02:00
slawkens
72212f8256 * added links to edit/delete/hide custom page directly from page 2017-10-23 09:10:22 +02:00
slawkens1
1610a4ab91 * update to 0.6.6 2017-10-22 23:38:51 +02:00
slawkens1
87a3d1e5d1 * fixed some php fatal error on spells page
* changed spells.vocations field in db size to 300
* please reload your spells after this update!
2017-10-22 23:36:05 +02:00
slawkens1
2b6d65e955 * update to 0.6.5 2017-10-21 04:32:20 +02:00
slawkens1
cd44d28674 *fixed displaying custom pages
* fixed adding new group board
2017-10-21 04:30:02 +02:00
slawkens1
2edeb1b3e2 * fixed guild create link 2017-10-20 22:40:02 +02:00
slawkens1
9f946d4bc4 * update to 0.6.4 2017-10-20 22:17:54 +02:00
slawkens1
5266f33af5 * reverted getLastLogin cause it was used by tibia11-login plugin 2017-10-20 22:01:05 +02:00
slawkens1
85c9a1e84d * update to 0.6.3 2017-10-20 21:18:50 +02:00
slawkens1
5951fe21ec * fixed creating account :(
* fixed showing premium account status
2017-10-20 21:15:46 +02:00
slawkens1
c6b6638705 * fixed viewing thread without being logged
* removed unused and wrong function OTS_Account::getLastLogin() (field
lastday is used for premium)
2017-10-20 20:29:10 +02:00
497 changed files with 11246 additions and 5371 deletions

598
CHANGELOG
View File

@@ -1,289 +1,413 @@
[0.7.7 - 08.01.2018]
* important fix for servers with promotion column (caused player.vocation to be resetted when saving player, for example: on change name, accept invite to guild, leave guild)
* immediately reload config.lua when there's change in config.server_path detected
* added new forum option: "Enable HTML" (only for moderators)
* fixed othire default column value (#26)
* fixed saving custom vocations in admin panel (#36)
* fixed warning in highscores when vocation doesn't exist
* fixed characters page - config.characters.frags "Notice: Use of undefined constant"
* fixed getBoolean function when boolean is passed
* fixed empty success message on leave guild
* fixed displaying premium account days
* function OTS_Account:getPremDays will now return -1 if there's freePremium configurable enabled on the server
* fixed tr bgcolor in characters view (Frags) (#38)
* fixed some warning in guild show
* fixed PHP warning about country not existing on online and characters pages
* fixed forum bbcode parsing
* don't add extra <br/> to the TinyMCE news forum posts
* (internal) using $player->getVocationName() where possible instead of older method
[0.7.6 - 05.01.2017]
* fixed othire account creating/installation
* fixed table name players -> players_online
* fixed unexpected error logging about email fail
* added max_execution_time to the install finish step
* some small fix regarding highscores vocation box
[0.7.5 - 04.01.2017]
* fixed bug on othire with config.account_premium_days
* fixed bug on TFS 1.x when online_afk is enabled
* warning about leaving news page with changes
* added player status to tibiacom top 5 highscores box
* save detected country on create account in session
* fixed getPremDays and isPremium functions (newest 11.x engines are bugged when it comes to PACC, its not fault of MyAAC)
* fix when there are no changelogs or highscores yet
* small fix regarding getTopPlayers function which was ignoring $limit variable
* fixed news adding when type != ARTICLE
* fixed template path finding
* fixed displaying article_text when it was empty saved
[0.7.4 - 24.12.2017]
* fixed mysql fatal error on tibiacom template - top 5 box
* fixed displaying of level percent bar on tibian signature
* inform user about Twig cache failure on installation, instead of http 500 error
* when dir system/cache is not writable by the webserver, then show some nice notice to the user about it instead of http 500 error
* remember client version select and usage stats checkbox in session on install
* automatically update highscores_ids_hidden for users who installed myaac before (migration)
[0.7.3 - 18.12.2017]
* auto generate myaac cache & session prefix on install to be unique across installations
* fixed hiding shop system menu on tibiacom template when disabled in config
* prevent adding duplicated newses with installation
* some changes to sample characters: chanced town_id to 1, posx: 1000, posy: 1000, posz: 1000 and default group_id to 1 so you can change in-game outfits and they will be used
* added version 772 constant to install client choose (OTHire)
* better solution for hidding samples (configurable) - highscores_ids_hidden
* fixed account.login redirect not working on tibiacom template
* installation: warn about wrong admin account name/id and password
* fixed last menu closing in tibiacom template
* updated polish locale (translation) on install
* (internal) removed some duplicated code on install finish
* (internal) renamed installation step files to be in correct order
* added TODO file
[0.7.1 - 13.12.2017]
* added changelog menu item to kathrine template
* fixed some php short tag in changelogs page
* fixed guild change description back button
* removed duplicated "Support List" menu item from tibiacom template
* changed some notice when version check is failed
* (internal) moved changelog to twig
[0.7.0 - 20.11.2017]
* moved template menus to database, they're now dynamically loaded
* added anonymous usage statistics reporting (only if user agrees, first usage report will be send after 7 days)
* you can edit them in Admin Panel under 'Menus' option
* you can also add custom links, like http://google.pl
* added networks (facebook and twitter) and highscores (top 5) boxes to tibiacom template, configurable in templates/tibiacom/config.php
* added news ticker for kathrine template
* added featured article to tibiacom template (you can add them with add news button)
* added tinymce editor to 'Pages' in admin panel
* added links to edit/delete/hide custom page directly from page
* update forum post after editing news (when forum post has been created)
* enabled code plugin for tinymce which enabled raw html code editing
* removed videos pages, as it can be easily added using custom Menus and Pages with insert Media
* removed bug_report configurable, its now enabled by default
* log some error info when mail cannot be send on account create
* twig getLink function will now return with full url (BASE_URL included)
* verify install post values directly on config page and display error
* updated tinymce to version 4.7.2 (from 4.7.0)
* updated phpmailer to version 5.2.26 (from 5.2.23)
* (#30) (fix) recovering account on servers that doesn't support salts
* (fix) account email confirm function
* (fix) showing changelog with urls in Admin Panel
* (fix) uninstalling plugin
* (fix) polls box in tibiacom template
* (fix) remove hooks from db on plugin deinstall
* (fix) some weird include possibilities with forum and account actions (verify action name)
* (fix) loading hooks from plugin installed from command line
* (fix) some changelog PHP Notice warning
* (internal) moved uninstall logic to Plugins class
* (internal) moved tibiacom boxes to separate directory
* (internal) moved news tickers to twig template
* (internal) moved Forum class to separate file
* (internal) moved deprecated functions to compat.php
* (internal) added some compat functions that are used by shop system
* (internal) renamed constant TICKET -> TICKER
* (internal) shortened message functions
[0.6.6 - 22.10.2017]
* fixed some php fatal error on spells page
* changed spells.vocations field in db size to 300
* please reload your spells after this update!
[0.6.5 - 21.10.2017]
* fixed displaying custom pages
* fixed adding new group forum board
[0.6.4 - 20.10.2017]
* reverted OTS_Account::getLastLogin() cause its used by tibia11-login plugin
[0.6.3 - 20.10.2017]
* fixed creating account
* fixed viewing thread without being logged
* fixed showing premium account status
[0.6.2 - 20.10.2017]
- added forums for guilds and groups
- added nice looking menu for my account page in default template
- new command line tool: install_plugin.php - can be used to install plugins from command line. Usage: "php install_plugin.php path_to_file"
- added new tooltip to view characters equipment item name and monster loot
- added items.xml loader class and weapons.xml loader class
- minimum PHP version to install AAC is now 5.3.0 cause of Anonymous functions used by Twig
- Added 'Are you sure?' popup when uninstalling plugin
- added some warnings when plugin json file is incomplete
- fixed showing in characters ban expires when is unlimited
- fixed displaying monster loot when item.name in loot is used instead of item.id
- load also runes into spells table
- display plugin uninstall option only if its possible
- after changing template you will be redirected to latest viewed page
- display gallery add image form only on main gallery page
- (internal) moved most of guilds html-in-php code to twig
- (internal) moved spells page to twig template
- (internal) removed useless spells.spell column that was duplicate of spells.words
- (internal) save monster loot in database in json format instead loading it every time from xml file
- (internal) store monster voices and immunities in json format
- (internal) moved buttons to separate template
- (internal) moved online search form to twig
- (internal) added new function getItemNameById($id)
- (internal) Moved plugin install logic to a new class: Plugins
- (internal) changed spells.vocations database field to store json data instead of comma separated
- (internal) removed $hook_types array, using defined() and constant() functions now
- (internal) removed useless monsters.gfx_name field from database
- (internal) renamed database field monsters.hide_creature to hidden
- (internal) renamed existing Items class to Items_Images
- (internal) optimized Spells class
- (internal) new function: OTS_Guild::hasMember(OTS_Player $player)
- (internal) new function: Forum::hasAccess($board_id)
* added forums for guilds and groups
* added nice looking menu for my account page in default template
* new command line tool: install_plugin.php - can be used to install plugins from command line. Usage: "php install_plugin.php path_to_file"
* added new tooltip to view characters equipment item name and monster loot
* added items.xml loader class and weapons.xml loader class
* minimum PHP version to install AAC is now 5.3.0 cause of Anonymous functions used by Twig
* Added 'Are you sure?' popup when uninstalling plugin
* added some warnings when plugin json file is incomplete
* fixed showing in characters ban expires when is unlimited
* fixed displaying monster loot when item.name in loot is used instead of item.id
* load also runes into spells table
* display plugin uninstall option only if its possible
* after changing template you will be redirected to latest viewed page
* display gallery add image form only on main gallery page
* (internal) moved most of guilds html-in-php code to twig
* (internal) moved spells page to twig template
* (internal) removed useless spells.spell column that was duplicate of spells.words
* (internal) save monster loot in database in json format instead loading it every time from xml file
* (internal) store monster voices and immunities in json format
* (internal) moved buttons to separate template
* (internal) moved online search form to twig
* (internal) added new function getItemNameById($id)
* (internal) Moved plugin install logic to a new class: Plugins
* (internal) changed spells.vocations database field to store json data instead of comma separated
* (internal) removed $hook_types array, using defined() and constant() functions now
* (internal) removed useless monsters.gfx_name field from database
* (internal) renamed database field monsters.hide_creature to hidden
* (internal) renamed existing Items class to Items_Images
* (internal) optimized Spells class
* (internal) new function: OTS_Guild::hasMember(OTS_Player $player)
* (internal) new function: Forum::hasAccess($board_id)
[0.6.1 - 17.10.2017]
- fixed signatures loading
- new configurable: session_prefix, to allow more websites on one machine (must be unique for every website on your dedicated server!)
- better error handling for monsters and spells loader (save errors to system/logs/error.log)
- check if file exist before loading (monsters and spells)
- (internal) Account::getAccess() = Account::getGroupId()
- (internal) moved account actions (pages) to account/ directory
- (internal) moved forum actions (pages) to forum/ directory
- (internal) moved forum.edit_post to twig templates
* fixed signatures loading
* new configurable: session_prefix, to allow more websites on one machine (must be unique for every website on your dedicated server!)
* better error handling for monsters and spells loader (save errors to system/logs/error.log)
* check if file exist before loading (monsters and spells)
* (internal) Account::getAccess() = Account::getGroupId()
* (internal) moved account actions (pages) to account/ directory
* (internal) moved forum actions (pages) to forum/ directory
* (internal) moved forum.edit_post to twig templates
[0.6.0 - 16.10.2017]
- added faq management - add/edit/move/hide/delete from website
- new account.login view for tibiacom template
- monsters and spells are now being loaded at the installation of the AAC
- fix for php versions under 5.5 where empty() function supported only variables
- added missing change email and change info buttons to account.management default template
- added new indicator icons for create account, create character and change character name
- fixed config loader when some inline comments are present
- fixed editing page in admin panel that contains some html code
- fixed forum new post on mac os and some specific mysql versions
- attempt to fix incorrect views counter behavior (its resetting to 0 in some cases)
- enabled cache http headers for signatures
- check if monster file exist before loading it
- fixed if plugin zip file name contains dot (.)
- renamed screenshots to gallery and movies to videos
- moved install pages to twig
- fixed Account::getGuildAccess function
- removed never used library from sources - dwoo
- moved check_* functions to class Validator
- from now all validators ajax requests will fire onblur instead of onkeyup
- ajax requests returns now json instead of xml
- added 404 response when file is not found
* added faq management - add/edit/move/hide/delete from website
* new account.login view for tibiacom template
* monsters and spells are now being loaded at the installation of the AAC
* fix for php versions under 5.5 where empty() function supported only variables
* added missing change email and change info buttons to account.management default template
* added new indicator icons for create account, create character and change character name
* fixed config loader when some inline comments are present
* fixed editing page in admin panel that contains some html code
* fixed forum new post on mac os and some specific mysql versions
* attempt to fix incorrect views counter behavior (its resetting to 0 in some cases)
* enabled cache http headers for signatures
* check if monster file exist before loading it
* fixed if plugin zip file name contains dot (.)
* renamed screenshots to gallery and movies to videos
* moved install pages to twig
* fixed Account::getGuildAccess function
* removed never used library from sources - dwoo
* moved check_* functions to class Validator
* from now all validators ajax requests will fire onblur instead of onkeyup
* ajax requests returns now json instead of xml
* added 404 response when file is not found
[0.5.1 - 11.10.2017]
- fixed forum add/edit board
- new configurable: highscores_length, how much highscores to display
- fixed highscores links (ALL, previous and next page)
- update templates cache when installing/uninstalling plugin
- moved character deaths and frags table generation to twig
- fixed some bug when you uninstall plugin and then try to install again on the same page
- check if plugin exist before uninstalling
- fixed some warning in OTS_Base_DB
* fixed forum add/edit board
* new configurable: highscores_length, how much highscores to display
* fixed highscores links (ALL, previous and next page)
* update templates cache when installing/uninstalling plugin
* moved character deaths and frags table generation to twig
* fixed some bug when you uninstall plugin and then try to install again on the same page
* check if plugin exist before uninstalling
* fixed some warning in OTS_Base_DB
[0.5.0 - 10.10.2017]
- moved .htaccess rules to plain php (index.php)
- updated tinymce to the latest (4.7.0) version, you can now embed code, for example youtube videos
- added option to uninstall plugin
- added option to require specified myaac, php or database version for plugins, without that plugin won't be installed
- change accountmanagement links to use friendly_urls
- fixed creating new forum thread
- sample characters are now assigned to admin account and have group_id 4 to not be shown on highscores
- added links loaded from database to admin panel - for future plugins
- print some info to error.log when can't find config.lua
- some fixes in account changecomment action
- show info when account name/number or password is empty on login
- fixed showing account login errors
- added few characters hooks
- fixed some kathrine template js bug when shop is disabled
- you can now use slash '/' in custom pages loaded from database
- added new twig function getLink that convert link taking into account config.friendly_urls
- internalLayoutLink -> getLink
* moved .htaccess rules to plain php (index.php)
* updated tinymce to the latest (4.7.0) version, you can now embed code, for example youtube videos
* added option to uninstall plugin
* added option to require specified myaac, php or database version for plugins, without that plugin won't be installed
* change accountmanagement links to use friendly_urls
* fixed creating new forum thread
* sample characters are now assigned to admin account and have group_id 4 to not be shown on highscores
* added links loaded from database to admin panel - for future plugins
* print some info to error.log when can't find config.lua
* some fixes in account changecomment action
* show info when account name/number or password is empty on login
* fixed showing account login errors
* added few characters hooks
* fixed some kathrine template js bug when shop is disabled
* you can now use slash '/' in custom pages loaded from database
* added new twig function getLink that convert link taking into account config.friendly_urls
* internalLayoutLink -> getLink
[0.4.3 - 05.10.2017]
- better config loader taken from latest gesior, you can now include files in your config by doing dofile('config.local.lua')
- fixed country detection in create account
- fixed showing of character deaths and frags
- fixed https://otland.net/threads/myaac-v0-0-1.251454/page-13#post-2466303
- fixed https://otland.net/threads/myaac-v0-0-1.251454/page-13#post-2466313
- fixed rook sample, which will now have level 1, 150 health, 0 mana, and 400 cap.
- fixed samples being deleted by tfs 1.0+ cause of 'deletion' field set to 1
- pages loaded from database have higher priority than normal .php pages, so they will be loaded first if they exist
- moved many pages to twig templates
- change download client links from clients.halfaway.net to tibia-clients.com
- added bugtracker to kathrine template
- added CREDITS file
* better config loader taken from latest gesior, you can now include files in your config by doing dofile('config.local.lua')
* fixed country detection in create account
* fixed showing of character deaths and frags
* fixed https://otland.net/threads/myaac-v0-0-1.251454/page-13#post-2466303
* fixed https://otland.net/threads/myaac-v0-0-1.251454/page-13#post-2466313
* fixed rook sample, which will now have level 1, 150 health, 0 mana, and 400 cap.
* fixed samples being deleted by tfs 1.0+ cause of 'deletion' field set to 1
* pages loaded from database have higher priority than normal .php pages, so they will be loaded first if they exist
* moved many pages to twig templates
* change download client links from clients.halfaway.net to tibia-clients.com
* added bugtracker to kathrine template
* added CREDITS file
[0.4.2 - 14.09.2017]
- updated version number
* updated version number
[0.4.1 - 13.09.2017]
- fixed log in to admin panel
- fixed File is not .zip plugin upload error
* fixed log in to admin panel
* fixed File is not .zip plugin upload error
[0.4.0 - 13.09.2017
- added option to add/edit/delete/hide/move forum boards
- moved some of HTML-in-PHP code to Twig templates
- added bug_report configurable which can enable/disable bug tracker
- log errors instead of showing them to users with system directories
- fix when $_SERVER['HTTP_ACCEPT_ENCODING'] is not set
- when it fails to load config.lua it will output error also to error.log
- automatically detect json file in .zip instead of basing on filename (admin panel - plugins)
- hopefully fixed the error with "The file you are trying to upload is not a .zip file. Please try again."
- fixed wrong name of table in bugtracker
- fixed some bugs in bugtracker
- added report bug link in templates
- fixed some rare error when user is logged in for longer than 15 minutes and tries to login again
- fixed some grammar errors
- some small improvements
- fixed some separators in kathrine template
* added option to add/edit/delete/hide/move forum boards
* moved some of HTML-in-PHP code to Twig templates
* added bug_report configurable which can enable/disable bug tracker
* log errors instead of showing them to users with system directories
* fix when $_SERVER['HTTP_ACCEPT_ENCODING'] is not set
* when it fails to load config.lua it will output error also to error.log
* automatically detect json file in .zip instead of basing on filename (admin panel - plugins)
* hopefully fixed the error with "The file you are trying to upload is not a .zip file. Please try again."
* fixed wrong name of table in bugtracker
* fixed some bugs in bugtracker
* added report bug link in templates
* fixed some rare error when user is logged in for longer than 15 minutes and tries to login again
* fixed some grammar errors
* some small improvements
* fixed some separators in kathrine template
[0.3.0 - 28.08.2017]
- added administration panel for screenshots management with auto thumbnail generator and image auto-resizing
- added Twig template engine and moved some html-in-php code to it
- automatically detect player country based on user location (IP) on create account
- player sex (gender) is now configurable at $config['genders']
- fixed recovering account and changing password when salt is enabled
- fixed installing samples when for example Rook Sample already exist and other samples not
- fixed some mysql error when character you trying to create already exist
- fixed some warning when you select nonexistent country
- password change minimal/maximal length notice is now more precise
- added 'enabled' field in myaac_hooks table, which can enable or disable specified hook
- removed DEFAULT '' for TEXT field. It didn't worked under some systems like MAC OS X.
- minimum PHP version to install the MyAAC is now 5.2.0 cause of pathinfo (extension) function
- removed unused admin stylish template
- removed some unused cities field from myaac_spells table
- moved news adding at installation from schema.sql to finish.php
- some optimizations
* added administration panel for screenshots management with auto thumbnail generator and image auto-resizing
* added Twig template engine and moved some html-in-php code to it
* automatically detect player country based on user location (IP) on create account
* player sex (gender) is now configurable at $config['genders']
* fixed recovering account and changing password when salt is enabled
* fixed installing samples when for example Rook Sample already exist and other samples not
* fixed some mysql error when character you trying to create already exist
* fixed some warning when you select nonexistent country
* password change minimal/maximal length notice is now more precise
* added 'enabled' field in myaac_hooks table, which can enable or disable specified hook
* removed DEFAULT '' for TEXT field. It didn't worked under some systems like MAC OS X.
* minimum PHP version to install the MyAAC is now 5.2.0 cause of pathinfo (extension) function
* removed unused admin stylish template
* removed some unused cities field from myaac_spells table
* moved news adding at installation from schema.sql to finish.php
* some optimizations
[0.2.4 - 09.06.2017]
- fixed invite to guild
- added id field on monsters, so you can delete them in phpmyadmin
- fixed adding some creatures with ' and "
- fixed when there are spaces at beginning of the file (creatures)
- fixed when file is unable to parse (creatures)
- fixed typo loss_items => loss_containers
- more elegant way of showing message on reload creatures and spells
* fixed invite to guild
* added id field on monsters, so you can delete them in phpmyadmin
* fixed adding some creatures with ' and "
* fixed when there are spaces at beginning of the file (creatures)
* fixed when file is unable to parse (creatures)
* fixed typo loss_items => loss_containers
* more elegant way of showing message on reload creatures and spells
[0.2.3 - 31.05.2017]
- fixed guild management on OTHire 0.0.3
- set default skills to 10 when creating new character
- fixed displaying of "Create forum thread" in newses
- fixed deleting guild on servers that use players.rank_id field
- fixed phpmailer class loading (https://otland.net/threads/myaac-v0-0-1.251454/page-8#post-2445222)
- fixed displaying vocation amount on online page
- better support for custom vocations, you just need to set in config vocations_amount to yours.
- fixed huge space in player name (https://otland.net/threads/myaac-v0-0-1.251454/page-7#post-2444328)
- fixed Undefined variable (https://otland.net/threads/myaac-v0-0-1.251454/page-7#post-2444034)
- fixed Undefined offset (https://otland.net/threads/myaac-v0-0-1.251454/page-7#post-2444035)
* fixed guild management on OTHire 0.0.3
* set default skills to 10 when creating new character
* fixed displaying of "Create forum thread" in newses
* fixed deleting guild on servers that use players.rank_id field
* fixed phpmailer class loading (https://otland.net/threads/myaac-v0-0-1.251454/page-8#post-2445222)
* fixed displaying vocation amount on online page
* better support for custom vocations, you just need to set in config vocations_amount to yours.
* fixed huge space in player name (https://otland.net/threads/myaac-v0-0-1.251454/page-7#post-2444328)
* fixed Undefined variable (https://otland.net/threads/myaac-v0-0-1.251454/page-7#post-2444034)
* fixed Undefined offset (https://otland.net/threads/myaac-v0-0-1.251454/page-7#post-2444035)
[0.2.2 - 22.05.2017]
- added missing cache/signature directory
- fixed https://otland.net/threads/myaac-v0-0-1.251454/page-7#post-2443868
* added missing cache/signature directory
* fixed https://otland.net/threads/myaac-v0-0-1.251454/page-7#post-2443868
[0.2.1 - 21.05.2017]
- added Swedish translation by Sizaro
- fixed some bugs with installlation & characters & houses
* added Swedish translation by Sizaro
* fixed some bugs with installlation & characters & houses
[0.2.0 - 21.05.2017]
- added option to change character sex for premium points
- moved site_closed to database, now you can close your site through admin panel
- added option to admin panel: clear cache
- added experiencetable_rows configurable
- optimized OTS_Account->getGroupId(), now its using like 20 queries less
- optimized OTS_Player->load($id) function, should be much faster now
- fixed displaying on highscores special outfits
- fixed skull images displaying
- fixed displaying unlimited premium account
- fixed bug where players.lookaddons doesn't exist (OTHire etc.) (https://otland.net/threads/myaac-v0-0-1.251454/page-6#post-2442407)
- fixed signature tibian for OTHire and other servers that doesnt use accounts.premdays field
- fixed when player name in signature containst space
- don't show "Create forum thread" when editing
- fixed red color table after create account
- updated download links, as clients.halfaway.net isn't working anymore
- fixed some bugs while installing when field `email_next` or `hidden` already exist
- fixed movies unexpected comment
- added template_place_holder('center_top') to kathrine template
* added option to change character sex for premium points
* moved site_closed to database, now you can close your site through admin panel
* added option to admin panel: clear cache
* added experiencetable_rows configurable
* optimized OTS_Account->getGroupId(), now its using like 20 queries less
* optimized OTS_Player->load($id) function, should be much faster now
* fixed displaying on highscores special outfits
* fixed skull images displaying
* fixed displaying unlimited premium account
* fixed bug where players.lookaddons doesn't exist (OTHire etc.) (https://otland.net/threads/myaac-v0-0-1.251454/page-6#post-2442407)
* fixed signature tibian for OTHire and other servers that doesnt use accounts.premdays field
* fixed when player name in signature containst space
* don't show "Create forum thread" when editing
* fixed red color table after create account
* updated download links, as clients.halfaway.net isn't working anymore
* fixed some bugs while installing when field `email_next` or `hidden` already exist
* fixed movies unexpected comment
* added template_place_holder('center_top') to kathrine template
[0.1.5 - 13.05.2017]
- fixed bug with "Integrity constraint violation: 1048 Column 'ip' cannot be null"
* fixed bug with "Integrity constraint violation: 1048 Column 'ip' cannot be null"
[0.1.4 - 13.05.2017]
- added outfit shower, in characters, online, and highscores
- updated database to version 2
- fixed item images (now using item-images.ots.me host by default)
- fixed news ticket and posting long newses (https://otland.net/threads/myaac-v0-0-1.251454/page-5#post-2442026)
- news body limit increased to 65535 (mysql text field)
- removed some unused code from my old server
- added spells & monsters to kathrine template
* added outfit shower, in characters, online, and highscores
* updated database to version 2
* fixed item images (now using item-images.ots.me host by default)
* fixed news ticket and posting long newses (https://otland.net/threads/myaac-v0-0-1.251454/page-5#post-2442026)
* news body limit increased to 65535 (mysql text field)
* removed some unused code from my old server
* added spells & monsters to kathrine template
[0.1.3 - 11.05.2017]
- this is just release to update version number
* this is just release to update version number
[0.1.2 - 11.05.2017]
- forgot to update CHANGELOG and MYAAC_VERSION
* forgot to update CHANGELOG and MYAAC_VERSION
[0.1.1 - 11.05.2017]
- fixed updating myaac_config with database_version to 1
- fixed database updater
* fixed updating myaac_config with database_version to 1
* fixed database updater
[0.1.0 - 11.05.2017]
- added new feature: change character name for premium points (disabled by default, you can enable it in config under account_change_character_name in config.php)
- added automatic database updater (data migrations)
- renamed events to hooks
- moved hooks to database
- now you can use hooks in plugins
- set account.type field to 5 on install, if TFS 1.0+
- added example plugin
- new, latest google analytics code
- fixed bug with loading account.name that has numbers in it
- fixed many bugs in player editor in admin panel
- added error handling to plugin manager and some more verification in
- file has been correctly unpacked/uploaded
- fixed Statistics page in admin panel when using account.number
- fixed bug when creating/recovering account on servers with
- account.salt field (TFS 0.3 for example)
- fixed forum showing thread with html tags (added from news manager)
- new, latest code for youtube videos in movies page
- fixed showing vocation images when using $config['online_vocations_images']
- many fixes in polls (also importing proper schema)
- fixed hovering on buttons in kathrine template (on accountmanagement page)
- fixed signatures (many fixes)
- added missing gesior signature system
* added new feature: change character name for premium points (disabled by default, you can enable it in config under account_change_character_name in config.php)
* added automatic database updater (data migrations)
* renamed events to hooks
* moved hooks to database
* now you can use hooks in plugins
* set account.type field to 5 on install, if TFS 1.0+
* added example plugin
* new, latest google analytics code
* fixed bug with loading account.name that has numbers in it
* fixed many bugs in player editor in admin panel
* added error handling to plugin manager and some more verification in
* file has been correctly unpacked/uploaded
* fixed Statistics page in admin panel when using account.number
* fixed bug when creating/recovering account on servers with
* account.salt field (TFS 0.3 for example)
* fixed forum showing thread with html tags (added from news manager)
* new, latest code for youtube videos in movies page
* fixed showing vocation images when using $config['online_vocations_images']
* many fixes in polls (also importing proper schema)
* fixed hovering on buttons in kathrine template (on accountmanagement page)
* fixed signatures (many fixes)
* added missing gesior signature system
[0.0.6 - 06.05.2017]
- fixed bug while installing (https://otland.net/threads/myaac-v0-0-1.251454/page-3#post-2440543)
- fixed bug when creating character (not showing errors) (one more time)
- fixed support for TFS 0.2 series
- added FAQ link
* fixed bug while installing (https://otland.net/threads/myaac-v0-0-1.251454/page-3#post-2440543)
* fixed bug when creating character (not showing errors) (one more time)
* fixed support for TFS 0.2 series
* added FAQ link
[0.0.5 - 05.05.2017]
- fixed bug when creating character (not showing errors)
- Fixed characters loading with names that has been created with other AAC
- fixed links to shop in default template
- fixed some weird PHP 7.1 warnings/notices
- Fixed config loading with some weird comments
- fixed bug with status info utf8 encoding (https://otland.net/threads/myaac-v0-0-1.251454/page-2#post-2440259)
- fixed when ip in log_action is NULL (https://otland.net/threads/myaac-v0-0-1.251454/page-2#post-2440357)
- fixed bug when guild doesn't exist on characters page (https://otland.net/threads/myaac-v0-0-1.251454/page-2#post-2440320)
- disabled friendly_urls by default
- fixes when $config['database_*'] is set
- added CHANGELOG
* fixed bug when creating character (not showing errors)
* Fixed characters loading with names that has been created with other AAC
* fixed links to shop in default template
* fixed some weird PHP 7.1 warnings/notices
* Fixed config loading with some weird comments
* fixed bug with status info utf8 encoding (https://otland.net/threads/myaac-v0-0-1.251454/page-2#post-2440259)
* fixed when ip in log_action is NULL (https://otland.net/threads/myaac-v0-0-1.251454/page-2#post-2440357)
* fixed bug when guild doesn't exist on characters page (https://otland.net/threads/myaac-v0-0-1.251454/page-2#post-2440320)
* disabled friendly_urls by default
* fixes when $config['database_*'] is set
* added CHANGELOG
[0.0.3 - 03.05.2017]
- Full support for OTHire 0.0.3
- added support for otservers that doesn't use account.name field, instead just account number will be used
- fixed encryption detection on TFS 0.3
- fixed bug when server_config table doesn't exist
- (install) moved admin account creation to new step
- fixed news comment link
- by default, the installer creates now the Admin player, for admin account
- fixed installation errors
- fixed config.lua loading with some weird comments
* Full support for OTHire 0.0.3
* added support for otservers that doesn't use account.name field, instead just account number will be used
* fixed encryption detection on TFS 0.3
* fixed bug when server_config table doesn't exist
* (install) moved admin account creation to new step
* fixed news comment link
* by default, the installer creates now the Admin player, for admin account
* fixed installation errors
* fixed config.lua loading with some weird comments
[0.0.2 - 02.05.2017]
- updated forum links to use friendly_urls
- some more info will be shown when cannot connect to database
- show more error infos when creating character
- fixed forum link on newses
- fixed spells loading when there's vocation name instead of id
- fixed bug when you have changed template but it doesn't exist anymore
- fixed vocations with promotion loading
- fixed support for gesior pages and templates
- added function OTS_Acount:getGroupId()
* updated forum links to use friendly_urls
* some more info will be shown when cannot connect to database
* show more error infos when creating character
* fixed forum link on newses
* fixed spells loading when there's vocation name instead of id
* fixed bug when you have changed template but it doesn't exist anymore
* fixed vocations with promotion loading
* fixed support for gesior pages and templates
* added function OTS_Acount:getGroupId()
[0.0.1 - 01.05.2017]
This is first official release of MyAAC.

52
TODO Normal file
View File

@@ -0,0 +1,52 @@
// MyAAC TODO
0.*
* support duplicated vocation names with different ids
* sandbox for plugins, don't install when requirements are not passed
* add changelog management interface
* plugins require:
* php extension
* database table or column
* kathrine tickets - show/hide
* highscores - by balance
* admin panel Menus:
* open in external window (_blank option)
* color of the link
* should the link blink?
* cache:
* hooks
* Menus in templates
* move highscores to twig
* migrations: option to downgrade the database
* hooks: login + logout
* create account: create character
1.0:
* i18n support (issue #1 on github)
* New Admin Panel layout and interface
* most preferably: https://adminlte.io/
* move all pages administration to this panel (like faq, forum, newses)
* remove tibiacom template, and include it as a plugin
2.0
* remove gesior backward support
* remove compat functions
* remove $template['link_*']
* folder restructure:
* var/ (for logs, cache and data), config/, bin, public/ (for index and images and other public content), system/ (for php files and classess)
* rename templates to layouts as templates is meant to be used for twig templates
* change gifts_system to shop_system configurable
* move most used options in system/templates dir to separate directories (more transparent)
* move database fields to separate tables without modifing the OTServ schema (myaac_accounts, myaac_players)
At any time between (version not specified):
* better news archive with search function (like on tibia.com)
* guild wars management (issue #13 on github)
* update account.management page to be more realistic (like on tibia.com)
* update guilds page to be more realistic (like on tibia.com)
* possibility to add extra cache engines with plugins
* new cache engine - plain php, is good with pure php 7.0+ and opcache
* preferably configurable (enable/disable) forum TinyMCE editor
* OTAdmin support in Admin Panel
* database towns table support for TFS 1.3
* two factor authentication for TFS 1.x

1
_config.yml Normal file
View File

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

View File

@@ -39,6 +39,7 @@
'Dashboard' => 'dashboard',
'Mailer' => 'mailer',
'Pages' => 'pages',
'Menus' => 'menus',
'Plugins' => 'plugins',
'Statistics' => 'statistics',
'Visitors' => 'visitors',

View File

@@ -21,14 +21,13 @@
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2017 MyAAC
* @version 0.6.2
* @link http://my-aac.org
*/
session_start();
define('MYAAC', true);
define('MYAAC_VERSION', '0.6.2');
define('DATABASE_VERSION', 15);
define('MYAAC_VERSION', '0.8.0-dev');
define('DATABASE_VERSION', 21);
define('TABLE_PREFIX', 'myaac_');
define('START_TIME', microtime(true));
define('MYAAC_OS', (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') ? 'WINDOWS' : (strtoupper(PHP_OS) == 'DARWIN' ? 'MAC' : 'LINUX'));
@@ -46,10 +45,12 @@ define('FLAG_CONTENT_MONSTERS', 256);
define('FLAG_CONTENT_GALLERY', 512);
define('FLAG_CONTENT_VIDEOS', 1024);
define('FLAG_CONTENT_FAQ', 2048);
define('FLAG_CONTENT_MENUS', 4096);
define('FLAG_CONTENT_PLAYERS', 8192);
// news
define('NEWS', 1);
define('TICKET', 2);
define('TICKER', 2);
define('ARTICLE', 3);
// directories
@@ -65,6 +66,14 @@ define('PLUGINS', BASE . 'plugins/');
define('TEMPLATES', BASE . 'templates/');
define('TOOLS', BASE . 'tools/');
// menu categories
define('MENU_CATEGORY_NEWS', 1);
define('MENU_CATEGORY_ACCOUNT', 2);
define('MENU_CATEGORY_COMMUNITY', 3);
define('MENU_CATEGORY_FORUM', 4);
define('MENU_CATEGORY_LIBRARY', 5);
define('MENU_CATEGORY_SHOP', 6);
// otserv versions
define('OTSERV', 1);
define('OTSERV_06', 2);

View File

@@ -13,7 +13,6 @@
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2017 MyAAC
* @version 0.6.2
* @link http://my-aac.org
*/
@@ -47,8 +46,6 @@ $config = array(
// footer
'footer' => ''/*'<br/>Your Server &copy; 2016. All rights reserved.'*/,
'debug_level' => 0, // 0 - disabled, 1 - show load time, 2 - show db query counter, 3 - both, 4 - memory usage, 5 - load time & memory usage, 6 - queries & memory usage, 7 - all
'language' => 'en', // default language (currently only 'en' available)
'language_allow_change' => false,
@@ -57,7 +54,7 @@ $config = array(
'views_counter' => true,
// cache system. by default file cache is used
'cache_engine' => 'auto', // apc, eaccelerator, xcache, file, auto, or blank to disable.
'cache_engine' => 'auto', // apc, apcu, eaccelerator, xcache, file, auto, or blank to disable.
'cache_prefix' => 'myaac_', // have to be unique if running more MyAAC instances on the same server (except file system cache)
// database details (leave blank for auto detect from config.lua)
@@ -66,6 +63,7 @@ $config = array(
'database_user' => '',
'database_password' => '',
'database_name' => '',
'database_log' => false, // should database queries be logged and displayed in the page source? They will be included at the end of the .html source of the page
// multiworld system (only TFS 0.3)
'multiworld' => false, // use multiworld system?
@@ -74,9 +72,9 @@ $config = array(
//'2' => 'Your Second World Name'
),
// items
// images
'outfit_images_url' => 'http://outfit-images.ots.me/outfit.php', // set to animoutfit.php for animated outfit
'item_images_url' => 'http://item-images.ots.me/960/', // set to images/items if you host your own items in images folder
'item_images_url' => 'http://item-images.ots.me/1092/', // set to images/items if you host your own items in images folder
// account
'account_management' => true, // disable if you're using other method to manage users (fe. tfs account manager)
@@ -99,7 +97,7 @@ $config = array(
'mail_address' => 'no-reply@your-server.org', // server e-mail address (from:)
'mail_admin' => 'your-address@your-server.org', // admin email address, where mails from contact form will be sent
'mail_signature' => array( // signature that will be included at the end of every message sent using _mail function
'plain' => ''/*'--\nMy Server,\nhttp://www.myserver.com'*/,
'plain' => ""/*"--\nMy Server,\nhttp://www.myserver.com"*/,
'html' => ''/*'<br/>My Server,\n<a href="http://www.myserver.com">myserver.com</a>'*/
),
'smtp_enabled' => false, // send by smtp or mail function (set false if use mail function)
@@ -111,7 +109,7 @@ $config = array(
// reCAPTCHA (prevent spam bots)
'recaptcha_enabled' => false, // enable recaptcha verification code
'recaptcha_site_key' => '', // get your own public and private keys at https://www.google.com/recaptcha
'recaptcha_site_key' => '', // get your own site and secret keys at https://www.google.com/recaptcha
'recaptcha_secret_key' => '',
'recaptcha_theme' => 'light', // light, dark
@@ -187,6 +185,7 @@ $config = array(
'highscores_outfit' => true, // show player outfit?
'highscores_country_box' => false, // doesnt work yet! (not implemented)
'highscores_groups_hidden' => 4, // this group id and higher won't be shown on the highscores
'highscores_ids_hidden' => array(0), // this ids of players will be hidden on the highscores (should be ids of samples)
'highscores_length' => 100, // how many records per page on highscores
// characters page
@@ -214,7 +213,7 @@ $config = array(
'gifts_system' => false,
// support/system
'bug_report' => true,
'bug_report' => true, // this configurable has no effect, its always enabled
// forum
'forum' => 'site', // link to the server forum, set to "site" if you want to use build in forum system, otherwise leave empty if you aren't going to use any forum
@@ -231,6 +230,7 @@ $config = array(
'status_port' => '',
// other
'anonymous_usage_statistics' => true,
'email_lai_sec_interval' => 60, // time in seconds between e-mails to one account from lost account interface, block spam
'google_analytics_id' => '', // e.g.: UA-XXXXXXX-X
'experiencetable_columns' => 5, // how many columns to display in experience table page. * experiencetable_rows, 5 = 500 (will show up to 500 level)

Binary file not shown.

After

Width:  |  Height:  |  Size: 797 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
images/plus.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

139
index.php
View File

@@ -21,7 +21,6 @@
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2017 MyAAC
* @version 0.6.2
* @link http://my-aac.org
*/
@@ -30,20 +29,7 @@
// ini_set('display_startup_errors', 1);
// error_reporting(E_ALL);
if(preg_match("/^(.*)\.(gif|jpg|jpeg|tiff|bmp|css|js|less|map|html|php|zip|rar|gz)$/i", $_SERVER['REQUEST_URI'])) {
header("HTTP/1.0 404 Not Found");
exit;
}
require_once('common.php');
require_once(BASE . 'config.local.php');
if(file_exists(BASE . 'install') && (!isset($config['installed']) || !$config['installed']))
{
header('Location: ' . BASE_URL . 'install/');
die('Setup detected that <b>install/</b> directory exists. Please visit <a href="' . BASE_URL . 'install">this</a> url to start MyAAC Installation.<br/>Delete <b>install/</b> directory if you already installed MyAAC.<br/>Remember to REFRESH this page when you\'re done!');
}
require_once(SYSTEM . 'functions.php');
$uri = $_SERVER['REQUEST_URI'];
@@ -55,13 +41,9 @@ else
$uri = str_replace_first('/', '', $uri);
$uri = str_replace(array('index.php/', '?'), '', $uri);
define('URI', $uri);
$found = false;
if(empty($uri) || isset($_REQUEST['template'])) {
$_REQUEST['p'] = 'news';
$found = true;
}
else if(preg_match("/^[A-Za-z0-9-_%\'+]+\.png$/i", $uri)) {
if(preg_match("/^[A-Za-z0-9-_%\'+]+\.png$/i", $uri)) {
$tmp = explode('.', $uri);
$_REQUEST['name'] = urldecode($tmp[0]);
@@ -69,7 +51,28 @@ else if(preg_match("/^[A-Za-z0-9-_%\'+]+\.png$/i", $uri)) {
include(TOOLS . 'signature/index.php');
exit();
}
else if(!preg_match('/[^A-z0-9_\-]/', $uri) && file_exists(SYSTEM . 'pages/' . $uri . '.php')) {
else if(preg_match("/^(.*)\.(gif|jpg|png|jpeg|tiff|bmp|css|js|less|map|html|php|zip|rar|gz|ttf|woff|ico)$/i", $_SERVER['REQUEST_URI'])) {
header("HTTP/1.0 404 Not Found");
exit;
}
if(file_exists(BASE . 'config.local.php'))
require_once(BASE . 'config.local.php');
if(file_exists(BASE . 'install') && (!isset($config['installed']) || !$config['installed']))
{
header('Location: ' . BASE_URL . 'install/');
die('Setup detected that <b>install/</b> directory exists. Please visit <a href="' . BASE_URL . 'install">this</a> url to start MyAAC Installation.<br/>Delete <b>install/</b> directory if you already installed MyAAC.<br/>Remember to REFRESH this page when you\'re done!');
}
$found = false;
if(empty($uri) || isset($_REQUEST['template'])) {
$_REQUEST['p'] = 'news';
$found = true;
}
else {
$tmp = strtolower($uri);
if(!preg_match('/[^A-z0-9_\-]/', $uri) && file_exists(SYSTEM . 'pages/' . $tmp . '.php')) {
$_REQUEST['p'] = $uri;
$found = true;
}
@@ -88,9 +91,11 @@ else {
'/^account\/character\/name\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_name'),
'/^account\/character\/sex\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_sex'),
'/^account\/character\/delete\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'delete_character'),
'/^account\/character\/comment\/[A-Za-z]+\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_comment', 'name' => '$3'),
'/^account\/character\/comment\/[A-Za-z0-9-_%+\']+\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_comment', 'name' => '$3'),
'/^account\/character\/comment\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_comment'),
'/^account\/confirm_email\/[A-Za-z0-9-_]+\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'confirm_email', 'v' => '$2'),
'/^characters\/[A-Za-z0-9-_%+\']+$/' => array('subtopic' => 'characters', 'name' => '$1'),
'/^changelog\/[0-9]+\/?$/' => array('subtopic' => 'changelog', 'page' => '$1'),
'/^commands\/add\/?$/' => array('subtopic' => 'commands', 'action' => 'add'),
'/^commands\/edit\/?$/' => array('subtopic' => 'commands', 'action' => 'edit'),
'/^faq\/add\/?$/' => array('subtopic' => 'faq', 'action' => 'add'),
@@ -116,6 +121,7 @@ else {
'/^news\/archive\/[0-9]+\/?$/' => array('subtopic' => 'newsarchive', 'id' => '$2'),
'/^polls\/[0-9]+\/?$/' => array('subtopic' => 'polls', 'id' => '$1'),
'/^spells\/[A-Za-z0-9-_%]+\/[A-Za-z0-9-_]+\/?$/' => array('subtopic' => 'spells', 'vocation' => '$1', 'order' => '$2'),
'/^gifts\/history\/?$/' => array('subtopic' => 'gifts', 'action' => 'show_history'),
);
foreach($rules as $rule => $redirect) {
@@ -135,19 +141,23 @@ else {
break;
}
}
if(!$found)
$_REQUEST['p'] = $uri;
}
}
// define page visited, so it can be used within events system
$page = isset($_REQUEST['subtopic']) ? $_REQUEST['subtopic'] : (isset($_REQUEST['p']) ? $_REQUEST['p'] : '');
if(empty($page) || preg_match('/[^A-z0-9\/_\-]/', $page)) {
if(empty($page) || !preg_match('/^[A-z0-9\_\-]+$/', $page)) {
$tmp = URI;
if(!empty($tmp)) {
$page = $tmp;
}
else {
if(!$found)
$page = '404';
else
$page = 'news';
}
}
$page = strtolower($page);
define('PAGE', $page);
@@ -168,21 +178,17 @@ if(fetchDatabaseConfig('database_version', $tmp)) { // we got version
$tmp = (int)$tmp;
if($tmp < DATABASE_VERSION) { // import if older
for($i = $tmp + 1; $i <= DATABASE_VERSION; $i++) {
$file = SYSTEM . 'migrations/' . $i . '.php';
if(file_exists($file)) {
require($file);
require(SYSTEM . 'migrations/' . $i . '.php');
updateDatabaseConfig('database_version', $i);
}
}
updateDatabaseConfig('database_version', DATABASE_VERSION);
}
}
else { // register first version
registerDatabaseConfig('database_version', 0);
for($i = 1; $i <= DATABASE_VERSION; $i++) {
require(SYSTEM . 'migrations/' . $i . '.php');
updateDatabaseConfig('database_version', $i);
}
registerDatabaseConfig('database_version', DATABASE_VERSION);
}
// event system
@@ -191,6 +197,41 @@ $hooks = new Hooks();
$hooks->load();
$hooks->trigger(HOOK_STARTUP);
// anonymous usage statistics
// sent only when user agrees
if(isset($config['anonymous_usage_statistics']) && $config['anonymous_usage_statistics']) {
$report_time = 30 * 24 * 60 * 60; // report one time per 30 days
$should_report = true;
$value = '';
if($cache->enabled() && $cache->fetch('last_usage_report', $value)) {
$should_report = time() > (int)$value + $report_time;
}
else {
$value = '';
if(fetchDatabaseConfig('last_usage_report', $value)) {
$should_report = time() > (int)$value + $report_time;
if($cache->enabled()) {
$cache->set('last_usage_report', $value);
}
}
else {
registerDatabaseConfig('last_usage_report', time() - ($report_time - (7 * 24 * 60 * 60))); // first report after a week
$should_report = false;
}
}
if($should_report) {
require_once(LIBS . 'usage_statistics.php');
Usage_Statistics::report();
updateDatabaseConfig('last_usage_report', time());
if($cache->enabled()) {
$cache->set('last_usage_report', time());
}
}
}
if($config['views_counter'])
require_once(SYSTEM . 'counter.php');
@@ -236,6 +277,7 @@ if($config['backward_support']) {
$layout_header = template_header();
$layout_name = $template_path;
$news_content = '';
$tickers_content = '';
$subtopic = PAGE;
$main_content = '';
@@ -276,14 +318,14 @@ if($load_it)
$ignore = false;
$logged_access = 0;
$logged_access = 1;
if($logged && $account_logged && $account_logged->isLoaded()) {
$logged_access = $account_logged->getAccess();
}
$query =
$db->query(
'SELECT `title`, `body`, `php`' .
'SELECT `id`, `title`, `body`, `php`, `hidden`' .
' FROM `' . TABLE_PREFIX . 'pages`' .
' WHERE `name` LIKE ' . $db->quote($page) . ' AND `hidden` != 1 AND `access` <= ' . $db->quote($logged_access));
if($query->rowCount() > 0) // found page
@@ -323,11 +365,17 @@ if($load_it)
}
else
$content .= $query['body']; // plain html
if(hasFlag(FLAG_CONTENT_PAGES) || superAdmin()) {
$content = $twig->render('admin.pages.links.html.twig', array(
'page' => array('id' => $query['id'], 'hidden' => $query['hidden'])
)) . $content;
}
}
else
{
$file = SYSTEM . 'pages/' . $page . '.php';
if(!@file_exists($file) && !$found)
if(!@file_exists($file))
{
$page = '404';
$file = SYSTEM . 'pages/404.php';
@@ -372,14 +420,17 @@ else
}
echo '<!-- MyAAC ' . MYAAC_VERSION . ' :: http://www.my-aac.org/ -->' . "\n";
if(($config['debug_level'] & 1) == 1)
echo '<!-- Generated in :: ' . round(microtime(true) - START_TIME, 4) . ' -->';
if(superAdmin()) {
echo '<!-- Generated in: ' . round(microtime(true) - START_TIME, 4) . 'ms -->';
echo PHP_EOL . '<!-- Queries done: ' . $db->queries() . ' -->';
if(function_exists('memory_get_peak_usage')) {
echo PHP_EOL . '<!-- Peak memory usage: ' . convert_bytes(memory_get_peak_usage(true)) . ' -->';
}
if(($config['debug_level'] & 2) == 2)
echo "\n" . '<!-- Queries done :: ' . $db->queries() . ' -->';
if(($config['debug_level'] & 4) == 4 && function_exists('memory_get_peak_usage'))
echo "\n" . '<!-- Peak memory usage: ' . convert_bytes(memory_get_peak_usage(true)) . ' -->';
if($config['database_log']) {
echo PHP_EOL . '<!-- Database Queries Done by MyAAC:' . PHP_EOL . $db->getLog() . '-->';
}
}
$hooks->trigger(HOOK_FINISH);
?>

View File

@@ -1,12 +1,17 @@
<?php
defined('MYAAC') or die('Direct access not allowed!');
if(!isset($_SESSION['var_server_path'])) {
error($locale['step_database_error_config']);
$error = true;
}
$config['server_path'] = $_SESSION['var_server_path'];
// take care of trailing slash at the end
if($config['server_path'][strlen($config['server_path']) - 1] != '/')
$config['server_path'] .= '/';
if(!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 = true;
}

View File

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

View File

@@ -78,4 +78,23 @@ function next_form($previous = true, $next = true)
<input type="hidden" name="step" id="step" value="' . $step . '" />' . next_buttons($previous, $next) . '
</form>';
}
?>
function win_is_writable($path) {
if($path[strlen( $path ) - 1] == '/') { // if it looks like a directory, check a random file within the directory
return win_is_writable( $path . uniqid( mt_rand() ) . '.tmp');
} elseif(is_dir( $path )) { // If it's a directory (and not a file) check a random file within the directory
return win_is_writable( $path . '/' . uniqid( mt_rand() ) . '.tmp' );
}
// check tmp file for read/write capabilities
$should_delete_tmp_file = !file_exists( $path );
$f = @fopen( $path, 'a' );
if ( $f === false )
return false;
fclose( $f );
if($should_delete_tmp_file)
unlink($path);
return true;
}

View File

@@ -84,9 +84,9 @@ CREATE TABLE `myaac_forum_boards`
`name` VARCHAR(32) NOT NULL,
`description` VARCHAR(255) NOT NULL DEFAULT '',
`ordering` INT(11) NOT NULL DEFAULT 0,
`closed` TINYINT(1) NOT NULL DEFAULT 0,
`guild` INT(11) NOT NULL DEFAULT 0,
`access` INT(11) NOT NULL DEFAULT 0,
`closed` TINYINT(1) NOT NULL DEFAULT 0,
`hidden` TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`)
) ENGINE = MyISAM;
@@ -107,8 +107,9 @@ CREATE TABLE `myaac_forum`
`author_aid` int(20) NOT NULL default '0',
`author_guid` int(20) NOT NULL default '0',
`post_text` text NOT NULL,
`post_topic` varchar(255) NOT NULL,
`post_topic` varchar(255) NOT NULL DEFAULT '',
`post_smile` tinyint(1) NOT NULL default '0',
`post_html` tinyint(1) NOT NULL default '0',
`post_date` int(20) NOT NULL default '0',
`last_edit_aid` int(20) NOT NULL default '0',
`edit_date` int(20) NOT NULL default '0',
@@ -140,6 +141,87 @@ CREATE TABLE `myaac_items`
PRIMARY KEY (`id`)
) ENGINE = MyISAM;
CREATE TABLE `myaac_menu`
(
`id` INT(11) NOT NULL AUTO_INCREMENT,
`template` VARCHAR(255) NOT NULL,
`name` VARCHAR(255) NOT NULL,
`link` VARCHAR(255) NOT NULL,
`category` INT(11) NOT NULL DEFAULT 1,
`ordering` INT(11) NOT NULL DEFAULT 0,
`enabled` INT(1) NOT NULL DEFAULT 1,
PRIMARY KEY (`id`)
) ENGINE = MyISAM;
/* MENU_CATEGORY_NEWS kathrine */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Latest News', 'news', 1, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'News Archive', 'news/archive', 1, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Changelog', 'changelog', 1, 2);
/* MENU_CATEGORY_ACCOUNT kathrine */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Account Management', 'account/manage', 2, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Create Account', 'account/create', 2, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Lost Account?', 'account/lost', 2, 2);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Server Rules', 'rules', 2, 3);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Downloads', 'downloads', 5, 4);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Report Bug', 'bugtracker', 2, 5);
/* MENU_CATEGORY_COMMUNITY kathrine */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Who is Online?', 'online', 3, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Characters', 'characters', 3, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Guilds', 'guilds', 3, 2);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Highscores', 'highscores', 3, 3);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Last Deaths', 'lastkills', 3, 4);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Houses', 'houses', 3, 5);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Bans', 'bans', 3, 6);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Forum', 'forum', 3, 7);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Team', 'team', 3, 8);
/* MENU_CATEGORY_LIBRARY kathrine */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Monsters', 'creatures', 5, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Spells', 'spells', 5, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Server Info', 'serverInfo', 5, 2);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Commands', 'commands', 5, 3);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Gallery', 'gallery', 5, 4);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Experience Table', 'experienceTable', 5, 5);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'FAQ', 'faq', 5, 6);
/* MENU_CATEGORY_SHOP kathrine */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Buy Points', 'points', 6, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Shop Offer', 'gifts', 6, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Shop History', 'gifts/history', 6, 2);
/* MENU_CATEGORY_NEWS tibiacom */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Latest News', 'news', 1, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'News Archive', 'news/archive', 1, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Changelog', 'changelog', 1, 2);
/* MENU_CATEGORY_ACCOUNT tibiacom */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Account Management', 'account/manage', 2, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Create Account', 'account/create', 2, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Lost Account?', 'account/lost', 2, 2);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Server Rules', 'rules', 2, 3);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Downloads', 'downloads', 2, 4);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Report Bug', 'bugtracker', 2, 5);
/* MENU_CATEGORY_COMMUNITY tibiacom */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Characters', 'characters', 3, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Who Is Online?', 'online', 3, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Highscores', 'highscores', 3, 2);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Last Kills', 'lastkills', 3, 3);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Houses', 'houses', 3, 4);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Guilds', 'guilds', 3, 5);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Polls', 'polls', 3, 6);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Bans', 'bans', 3, 7);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Support List', 'team', 3, 8);
/* MENU_CATEGORY_FORUM tibiacom */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Forum', 'forum', 4, 0);
/* MENU_CATEGORY_LIBRARY tibiacom */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Creatures', 'creatures', 5, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Spells', 'spells', 5, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Commands', 'commands', 5, 2);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Exp Stages', 'experienceStages', 5, 3);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Gallery', 'gallery', 5, 4);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Server Info', 'serverInfo', 5, 5);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Experience Table', 'experienceTable', 5, 6);
/* MENU_CATEGORY_SHOP tibiacom */
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Buy Points', 'points', 6, 0);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Shop Offer', 'gifts', 6, 1);
INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Shop History', 'gifts/history', 6, 2);
CREATE TABLE `myaac_monsters` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`hidden` tinyint(1) NOT NULL default 0,
@@ -174,13 +256,15 @@ CREATE TABLE `myaac_news`
`id` INT(11) NOT NULL AUTO_INCREMENT,
`title` VARCHAR(100) NOT NULL,
`body` TEXT NOT NULL,
`type` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '1 - news, 2 - ticket, 3 - article',
`type` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '1 - news, 2 - ticker, 3 - article',
`date` INT(11) NOT NULL DEFAULT 0,
`category` TINYINT(1) NOT NULL DEFAULT 0,
`player_id` INT(11) NOT NULL DEFAULT 0,
`last_modified_by` INT(11) NOT NULL DEFAULT 0,
`last_modified_date` INT(11) NOT NULL DEFAULT 0,
`comments` VARCHAR(50) NOT NULL,
`comments` VARCHAR(50) NOT NULL DEFAULT '',
`article_text` VARCHAR(300) NOT NULL DEFAULT '',
`article_image` VARCHAR(100) NOT NULL DEFAULT '',
`hidden` TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`)
) ENGINE = MyISAM;

View File

@@ -0,0 +1,11 @@
We have detected that you don't have access to write to the system/cache directory. Under linux you can fix it by using this two command, where first one should be enough (for apache):<br/><br/><span class="console">chown -R www-data.www-data /var/www/*</span><br/><span class="console">chmod -R 660 system/cache</span>
<style type="text/css">
.console {
font-family:Courier;
color: #CCCCCC;
background: #000000;
border: 3px double #CCCCCC;
padding: 0px;
}
</style>

View File

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

3
install/ip.txt Normal file
View File

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

View File

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

View File

@@ -0,0 +1,21 @@
<?php
defined('MYAAC') or die('Direct access not allowed!');
$clients = array();
foreach($config['clients'] as $client) {
$client_version = (string)($client / 100);
if(strpos($client_version, '.') == false)
$client_version .= '.0';
$clients[$client] = $client_version;
}
echo $twig->render('install.config.html.twig', array(
'clients' => $clients,
'timezones' => DateTimeZone::listIdentifiers(),
'locale' => $locale,
'session' => $_SESSION,
'errors' => isset($errors) ? $errors : null,
'buttons' => next_buttons()
));
?>

View File

@@ -0,0 +1,100 @@
<?php
defined('MYAAC') or die('Direct access not allowed!');
//ini_set('display_errors', false);
ini_set('max_execution_time', 300);
$error = false;
if(!isset($_SESSION['var_server_path'])) {
error($locale['step_database_error_path']);
$error = true;
}
if(!$error) {
$content = "<?php";
$content .= PHP_EOL;
$content .= '// place for your configuration directives, so you can later easily update myaac';
$content .= PHP_EOL;
$content .= '$config[\'installed\'] = true;';
$content .= PHP_EOL;
$content .= '$config[\'mail_enabled\'] = true;';
$content .= PHP_EOL;
foreach($_SESSION as $key => $value)
{
if(strpos($key, 'var_') !== false)
{
if($key == 'var_server_path')
{
$value = str_replace("\\", "/", $value);
if($value[strlen($value) - 1] != '/')
$value .= '/';
}
if($key == 'var_usage') {
$content .= '$config[\'anonymous_usage_statistics\'] = ' . ((int)$value == 1 ? 'true' : 'false') . ';';
$content .= PHP_EOL;
}
else if($key != 'var_account' && $key != 'var_account_id' && $key != 'var_password' && $key != 'var_step') {
$content .= '$config[\'' . str_replace('var_', '', $key) . '\'] = \'' . $value . '\';';
$content .= PHP_EOL;
}
}
}
require(BASE . 'install/includes/config.php');
if(!$error) {
success($locale['step_database_importing']);
require(BASE . 'install/includes/database.php');
echo $twig->render('install.installer.html.twig', array(
'url' => 'tools/5-database.php',
'message' => $locale['loading_spinner']
));
if(!$error) {
if(!Validator::email($_SESSION['var_mail_admin'])) {
error($locale['step_config_mail_admin_error']);
$error = true;
}
if(!Validator::email($_SESSION['var_mail_address'])) {
error($locale['step_config_mail_address_error']);
$error = true;
}
$content .= '$config[\'client_download\'] = \'http://tibia-clients.com/clients/download/\'. $config[\'client\'] . \'/exe/windows\';';
$content .= PHP_EOL;
$content .= '$config[\'client_download_linux\'] = \'http://tibia-clients.com/clients/download/\'. $config[\'client\'] . \'/tar/linux\';';
$content .= PHP_EOL;
$content .= '$config[\'session_prefix\'] = \'myaac_' . generateRandomString(8, true, false, true, false) . '_\';';
$content .= PHP_EOL;
$content .= '$config[\'cache_prefix\'] = \'myaac_' . generateRandomString(8, true, false, true, false) . '_\';';
$saved = true;
if(!$error) {
$saved = file_put_contents(BASE . 'config.local.php', $content);
}
if($saved) {
if(!$error) {
$_SESSION['saved'] = true;
}
}
else {
$_SESSION['config_content'] = $content;
unset($_SESSION['saved']);
$locale['step_database_error_file'] = str_replace('$FILE$', '<b>' . BASE . 'config.local.php</b>', $locale['step_database_error_file']);
warning($locale['step_database_error_file'] . '<br/>
<textarea cols="70" rows="10">' . $content . '</textarea>');
}
}
}
}
?>
<form action="<?php echo BASE_URL; ?>install/" method="post">
<input type="hidden" name="step" id="step" value="admin" />
<?php echo next_buttons(true, $error ? false : true);
?>
</form>

View File

@@ -8,6 +8,7 @@ if(!$error) {
echo $twig->render('install.admin.html.twig', array(
'locale' => $locale,
'session' => $_SESSION,
'errors' => isset($errors) ? $errors : null,
'buttons' => next_buttons(true, $error ? false : true)
));
}

138
install/steps/7-finish.php Normal file
View File

@@ -0,0 +1,138 @@
<?php
defined('MYAAC') or die('Direct access not allowed!');
ini_set('max_execution_time', 300);
if(isset($config['installed']) && $config['installed'] && !isset($_SESSION['saved'])) {
warning($locale['already_installed']);
}
else {
require(SYSTEM . 'init.php');
if(!$error) {
if(USE_ACCOUNT_NAME)
$account = isset($_SESSION['var_account']) ? $_SESSION['var_account'] : null;
else
$account_id = isset($_SESSION['var_account_id']) ? $_SESSION['var_account_id'] : null;
$password = $_SESSION['var_password'];
$config_salt_enabled = $db->hasColumn('accounts', 'salt');
if($config_salt_enabled)
{
$salt = generateRandomString(10, false, true, true);
$password = $salt . $password;
}
$account_db = new OTS_Account();
if(isset($account))
$account_db->find($account);
else
$account_db->load($account_id);
$player_db = new OTS_Player();
$player_db->find('Admin');
$groups = new OTS_Groups_List();
if(!$player_db->isLoaded())
{
$player = new OTS_Player();
$player->setName('Admin');
$player_used = &$player;
}
else {
$player_used = &$player_db;
}
$player_used->setGroupId($groups->getHighestId());
if($account_db->isLoaded()) {
$account_db->setPassword(encrypt($password));
$account_db->setEMail($_SESSION['var_mail_admin']);
$account_db->save();
$account_used = &$account_db;
}
else {
$new_account = new OTS_Account();
if(USE_ACCOUNT_NAME) {
$new_account->create($account);
}
else {
$new_account->create(null, $account_id);
}
$new_account->setPassword(encrypt($password));
$new_account->setEMail($_SESSION['var_mail_admin']);
$new_account->unblock();
$new_account->save();
$new_account->setCustomField('created', time());
$new_account->logAction('Account created.');
$account_used = &$new_account;
}
if($config_salt_enabled)
$account_used->setCustomField('salt', $salt);
$account_used->setCustomField('web_flags', FLAG_ADMIN + FLAG_SUPER_ADMIN);
$account_used->setCustomField('country', 'us');
if($db->hasColumn('accounts', 'group_id'))
$account_used->setCustomField('group_id', $groups->getHighestId());
if($db->hasColumn('accounts', 'type'))
$account_used->setCustomField('type', 5);
if(!$player_db->isLoaded())
$player->setAccountId($account_used->getId());
else
$player_db->setAccountId($account_used->getId());
success($locale['step_database_created_account']);
setSession('account', $account_used->getId());
setSession('password', encrypt($password));
setSession('remember_me', true);
if($player_db->isLoaded()) {
$player_db->save();
}
else {
$player->save();
}
$player_id = 0;
$query = $db->query("SELECT `id` FROM `players` WHERE `name` = " . $db->quote('Admin') . ";");
if($query->rowCount() == 1) {
$query = $query->fetch();
$player_id = $query['id'];
}
$query = $db->query("SELECT `id` FROM `" . TABLE_PREFIX ."news` WHERE `title` LIKE 'Hello!';");
if($query->rowCount() == 0) {
if(query("INSERT INTO `" . TABLE_PREFIX ."news` (`id`, `type`, `date`, `category`, `title`, `body`, `player_id`, `comments`, `hidden`) VALUES (NULL, '1', UNIX_TIMESTAMP(), '2', 'Hello!', 'MyAAC is just READY to use!', " . $player_id . ", 'http://my-aac.org', '0');
INSERT INTO `myaac_news` (`id`, `type`, `date`, `category`, `title`, `body`, `player_id`, `comments`, `hidden`) VALUES (NULL, '2', UNIX_TIMESTAMP(), '4', 'Hello tickets!', 'http://my-aac.org', " . $player_id . ", '', '0');")) {
success($locale['step_database_created_news']);
}
}
echo $twig->render('install.installer.html.twig', array(
'url' => 'tools/7-finish.php',
'message' => $locale['importing_spinner']
));
if(!isset($_SESSION['installed'])) {
file_get_contents('http://my-aac.org/report_install.php?v=' . MYAAC_VERSION . '&b=' . urlencode(BASE_URL));
$_SESSION['installed'] = true;
}
foreach($_SESSION as $key => $value) {
if(strpos($key, 'var_') !== false)
unset($_SESSION[$key]);
}
unset($_SESSION['saved']);
if(file_exists(CACHE . 'install.txt')) {
unlink(CACHE . 'install.txt');
}
}
}
?>

View File

@@ -1,262 +0,0 @@
<?php
defined('MYAAC') or die('Direct access not allowed!');
//ini_set('display_errors', false);
ini_set('max_execution_time', 300);
$error = false;
if(!isset($_SESSION['var_server_path'])) {
error($locale['step_database_error_path']);
$error = true;
}
if(!$error) {
$content = "<?php\n";
foreach($_SESSION as $key => $value)
{
if(strpos($key, 'var_') !== false)
{
if($key == 'var_server_path')
{
$value = str_replace("\\", "/", $value);
if($value[strlen($value) - 1] != '/')
$value .= "/";
}
if($key != 'var_account' && $key != 'var_account_id' && $key != 'var_password') {
$content .= '$config[\'' . str_replace('var_', '', $key) . '\'] = \'' . $value . '\';';
$content .= PHP_EOL;
}
}
}
require(BASE . 'install/includes/config.php');
if(!$error) {
success($locale['step_database_importing']);
require(BASE . 'install/includes/database.php');
if(!tableExist('accounts')) {
$locale['step_database_error_table'] = str_replace('$TABLE$', 'accounts', $locale['step_database_error_table']);
error($locale['step_database_error_table']);
$error = true;
}
else if(!tableExist('players')) {
$locale['step_database_error_table'] = str_replace('$TABLE$', 'players', $locale['step_database_error_table']);
error($locale['step_database_error_table']);
$error = true;
}
else if(!tableExist('guilds')) {
$locale['step_database_error_table'] = str_replace('$TABLE$', 'guilds', $locale['step_database_error_table']);
error($locale['step_database_error_table']);
$error = true;
}
if(tableExist(TABLE_PREFIX . 'account_actions')) {
$locale['step_database_error_table_exist'] = str_replace('$TABLE$', TABLE_PREFIX . 'account_actions', $locale['step_database_error_table_exist']);
warning($locale['step_database_error_table_exist']);
}
else if(!$error) {
// import schema
try {
$db->query(file_get_contents(BASE . 'install/includes/schema.sql'));
}
catch(PDOException $error_) {
error($locale['step_database_error_schema'] . ' ' . $error_);
$error = true;
}
if(!$error) {
registerDatabaseConfig('database_version', DATABASE_VERSION);
$locale['step_database_success_schema'] = str_replace('$PREFIX$', TABLE_PREFIX, $locale['step_database_success_schema']);
success($locale['step_database_success_schema']);
}
}
if(!$error) {
if(fieldExist('key', 'accounts')) {
if(query("ALTER TABLE `accounts` MODIFY `key` VARCHAR(64) NOT NULL DEFAULT '';"))
success($locale['step_database_modifying_field'] . ' accounts.key...');
}
else {
if(query("ALTER TABLE `accounts` ADD `key` VARCHAR(64) NOT NULL DEFAULT '' AFTER `email`;"))
success($locale['step_database_adding_field'] . ' accounts.key...');
}
if(!fieldExist('blocked', 'accounts')) {
if(query("ALTER TABLE `accounts` ADD `blocked` TINYINT(1) NOT NULL DEFAULT FALSE COMMENT 'internal usage' AFTER `key`;"))
success($locale['step_database_adding_field'] . ' accounts.created...');
}
if(!fieldExist('created', 'accounts')) {
if(query("ALTER TABLE `accounts` ADD `created` INT(11) NOT NULL DEFAULT 0 AFTER `" . (fieldExist('group_id', 'accounts') ? 'group_id' : 'blocked') . "`;"))
success($locale['step_database_adding_field'] . ' accounts.created...');
}
if(!fieldExist('rlname', 'accounts')) {
if(query("ALTER TABLE `accounts` ADD `rlname` VARCHAR(255) NOT NULL DEFAULT '' AFTER `created`;"))
success($locale['step_database_adding_field'] . ' accounts.rlname...');
}
if(!fieldExist('location', 'accounts')) {
if(query("ALTER TABLE `accounts` ADD `location` VARCHAR(255) NOT NULL DEFAULT '' AFTER `rlname`;"))
success($locale['step_database_adding_field'] . ' accounts.location...');
}
if(!fieldExist('country', 'accounts')) {
if(query("ALTER TABLE `accounts` ADD `country` VARCHAR(3) NOT NULL DEFAULT '' AFTER `location`;"))
success($locale['step_database_adding_field'] . ' accounts.country...');
}
if(fieldExist('page_lastday', 'accounts')) {
if(query("ALTER TABLE `accounts` CHANGE `page_lastday` `web_lastlogin` INT(11) NOT NULL DEFAULT 0;")) {
$tmp = str_replace('$FIELD$', 'accounts.page_lastday', $locale['step_database_changing_field']);
$tmp = str_replace('$FIELD_NEW$', 'accounts.web_lastlogin', $tmp);
success($tmp);
}
}
else if(!fieldExist('web_lastlogin', 'accounts')) {
if(query("ALTER TABLE `accounts` ADD `web_lastlogin` INT(11) NOT NULL DEFAULT 0 AFTER `country`;"))
success($locale['step_database_adding_field'] . ' accounts.web_lastlogin...');
}
if(!fieldExist('web_flags', 'accounts')) {
if(query("ALTER TABLE `accounts` ADD `web_flags` INT(11) NOT NULL DEFAULT 0 AFTER `web_lastlogin`;"))
success($locale['step_database_adding_field'] . ' accounts.web_flags...');
}
if(!fieldExist('email_hash', 'accounts')) {
if(query("ALTER TABLE `accounts` ADD `email_hash` VARCHAR(32) NOT NULL DEFAULT '' AFTER `web_flags`;"))
success($locale['step_database_adding_field'] . ' accounts.email_hash...');
}
if(!fieldExist('email_verified', 'accounts')) {
if(query("ALTER TABLE `accounts` ADD `email_verified` TINYINT(1) NOT NULL DEFAULT 0 AFTER `email_hash`;"))
success($locale['step_database_adding_field'] . ' accounts.email_verified...');
}
if(!fieldExist('email_new', 'accounts')) {
if(query("ALTER TABLE `accounts` ADD `email_new` VARCHAR(255) NOT NULL DEFAULT '' AFTER `email_hash`;"))
success($locale['step_database_adding_field'] . ' accounts.email_new...');
}
if(!fieldExist('email_new_time', 'accounts')) {
if(query("ALTER TABLE `accounts` ADD `email_new_time` INT(11) NOT NULL DEFAULT 0 AFTER `email_new`;"))
success($locale['step_database_adding_field'] . ' accounts.email_new_time...');
}
if(!fieldExist('email_code', 'accounts')) {
if(query("ALTER TABLE `accounts` ADD `email_code` VARCHAR(255) NOT NULL DEFAULT '' AFTER `email_new_time`;"))
success($locale['step_database_adding_field'] . ' accounts.email_code...');
}
if(fieldExist('next_email', 'accounts')) {
if(!fieldExist('email_next', 'accounts')) {
if(query("ALTER TABLE `accounts` CHANGE `next_email` `email_next` INT(11) NOT NULL DEFAULT 0;")) {
$tmp = str_replace('$FIELD$', 'accounts.next_email', $locale['step_database_changing_field']);
$tmp = str_replace('$FIELD_NEW$', 'accounts.email_next', $tmp);
success($tmp);
}
}
}
else if(!fieldExist('email_next', 'accounts')) {
if(query("ALTER TABLE `accounts` ADD `email_next` INT(11) NOT NULL DEFAULT 0 AFTER `email_code`;"))
success($locale['step_database_adding_field'] . ' accounts.email_next...');
}
if(!fieldExist('premium_points', 'accounts')) {
if(query("ALTER TABLE `accounts` ADD `premium_points` INT(11) NOT NULL DEFAULT 0 AFTER `email_next`;"))
success($locale['step_database_adding_field'] . ' accounts.premium_points...');
}
if(!fieldExist('description', 'guilds')) {
if(query("ALTER TABLE `guilds` ADD `description` TEXT NOT NULL;"))
success($locale['step_database_adding_field'] . ' guilds.description...');
}
if(fieldExist('logo_gfx_name', 'guilds')) {
if(query("ALTER TABLE `guilds` CHANGE `logo_gfx_name` `logo_name` VARCHAR( 255 ) NOT NULL DEFAULT 'default.gif';")) {
$tmp = str_replace('$FIELD$', 'guilds.logo_gfx_name', $locale['step_database_changing_field']);
$tmp = str_replace('$FIELD_NEW$', 'guilds.logo_name', $tmp);
success($tmp);
}
}
else if(!fieldExist('logo_name', 'guilds')) {
if(query("ALTER TABLE `guilds` ADD `logo_name` VARCHAR( 255 ) NOT NULL DEFAULT 'default.gif';"))
success($locale['step_database_adding_field'] . ' guilds.logo_name...');
}
if(!fieldExist('created', 'players')) {
if(query("ALTER TABLE `players` ADD `created` INT(11) NOT NULL DEFAULT 0;"))
success($locale['step_database_adding_field'] . ' players.created...');
}
if(!fieldExist('deleted', 'players') && !fieldExist('deletion', 'players')) {
if(query("ALTER TABLE `players` ADD `deleted` TINYINT(1) NOT NULL DEFAULT 0;"))
success($locale['step_database_adding_field'] . ' players.comment...');
}
if(fieldExist('hide_char', 'players')) {
if(!fieldExist('hidden', 'players')) {
if(query("ALTER TABLE `players` CHANGE `hide_char` `hidden` TINYINT(1) NOT NULL DEFAULT 0;")) {
$tmp = str_replace('$FIELD$', 'players.hide_char', $locale['step_database_changing_field']);
$tmp = str_replace('$FIELD_NEW$', 'players.hidden', $tmp);
success($tmp);
}
}
}
else if(!fieldExist('hidden', 'players')) {
if(query("ALTER TABLE `players` ADD `hidden` TINYINT(1) NOT NULL DEFAULT 0;"))
success($locale['step_database_adding_field'] . ' players.hidden...');
}
if(!fieldExist('comment', 'players')) {
if(query("ALTER TABLE `players` ADD `comment` TEXT NOT NULL;"))
success($locale['step_database_adding_field'] . ' players.comment...');
}
}
if(!$error && (!isset($_SESSION['saved']))) {
$content .= '$config[\'installed\'] = true;';
$content .= PHP_EOL;
$content .= '$config[\'mail_enabled\'] = true;';
$content .= PHP_EOL;
if(!Validator::email($_SESSION['var_mail_admin'])) {
error($locale['step_config_mail_admin_error']);
$error = true;
}
if(!Validator::email($_SESSION['var_mail_address'])) {
error($locale['step_config_mail_address_error']);
$error = true;
}
$content .= '$config[\'client_download\'] = \'http://tibia-clients.com/clients/download/\'. $config[\'client\'] . \'/exe/windows\';';
$content .= PHP_EOL;
$content .= '$config[\'client_download_linux\'] = \'http://tibia-clients.com/clients/download/\'. $config[\'client\'] . \'/tar/linux\';';
$content .= PHP_EOL;
$content .= '// place for your configuration directives, so you can later easily update myaac';
$content .= PHP_EOL;
$content .= "?>";
$file = fopen(BASE . 'config.local.php', 'a+');
if($file) {
if(!$error) {
fwrite($file, $content);
$_SESSION['saved'] = true;
}
}
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>');
}
}
}
}
?>
<form action="<?php echo BASE_URL; ?>install/" method="post">
<input type="hidden" name="step" id="step" value="admin" />
<?php echo next_buttons(true, $error ? false : true);
?>
</form>

View File

@@ -1,217 +0,0 @@
<?php
defined('MYAAC') or die('Direct access not allowed!');
if(isset($config['installed']) && $config['installed'] && !isset($_SESSION['saved'])) {
warning($locale['already_installed']);
}
else {
require(SYSTEM . 'init.php');
if(!$error) {
if(USE_ACCOUNT_NAME)
$account = isset($_SESSION['var_account']) ? $_SESSION['var_account'] : null;
else
$account_id = isset($_SESSION['var_account_id']) ? $_SESSION['var_account_id'] : null;
$password = $_SESSION['var_password'];
$config_salt_enabled = fieldExist('salt', 'accounts');
if($config_salt_enabled)
{
$salt = generateRandomString(10, false, true, true);
$password = $salt . $password;
}
/*
$account_db = new OTS_Account();
$account_db->load(1);
if($account_db->isLoaded()) {
if(USE_ACCOUNT_NAME)
$account_db->setName('dummy_account');
$account_db->setPassword('for sample characters. ' . generateRandomString(10));
$account_db->save();
}
else {
$new_account = new OTS_Account();
if(USE_ACCOUNT_NAME)
$new_account->create('dummy_account', 1);
else
$new_account->create(null, 1);
$new_account->setPassword('for sample characters. ' . generateRandomString(10));
$new_account->save();
}
*/
$account_db = new OTS_Account();
if(isset($account))
$account_db->find($account);
else
$account_db->load($account_id);
$player_db = new OTS_Player();
$player_db->find('Admin');
$groups = new OTS_Groups_List();
if(!$player_db->isLoaded())
{
$player = new OTS_Player();
$player->setName('Admin');
$player->setGroupId($groups->getHighestId());
}
if($account_db->isLoaded()) {
$account_db->setPassword(encrypt($password));
$account_db->setEMail($_SESSION['var_mail_admin']);
$account_db->save();
if($config_salt_enabled)
$account_db->setCustomField('salt', $salt);
$account_db->setCustomField('web_flags', 3);
$account_db->setCustomField('country', 'us');
if(fieldExist('group_id', 'accounts'))
$account_db->setCustomField('group_id', $groups->getHighestId());
if(fieldExist('type', 'accounts'))
$account_db->setCustomField('type', 5);
if(!$player_db->isLoaded())
$player->setAccountId($account_db->getId());
else
$player_db->setAccountId($account_db->getId());
setSession('account', $account_db->getId());
}
else {
$new_account = new OTS_Account();
$new_account->create($account);
$new_account->setPassword(encrypt($password));
$new_account->setEMail($_SESSION['var_mail_admin']);
$new_account->unblock();
$new_account->save();
if($config_salt_enabled)
$new_account->setCustomField('salt', $salt);
$new_account->setCustomField('created', time());
$new_account->setCustomField('web_flags', 3);
$new_account->setCustomField('country', 'us');
if(fieldExist('group_id', 'accounts'))
$new_account->setCustomField('group_id', $groups->getHighestId());
if(fieldExist('type', 'accounts'))
$new_account->setCustomField('type', 5);
$new_account->logAction('Account created.');
if(!$player_db->isLoaded())
$player->setAccountId($new_account->getId());
else
$player_db->setAccountId($new_account->getId());
setSession('account', $new_account->getId());
}
success($locale['step_database_created_account']);
setSession('password', encrypt($password));
setSession('remember_me', true);
if($player_db->isLoaded()) {
$player_db->save();
}
else {
$player->save();
}
$player_id = 0;
$query = $db->query("SELECT `id` FROM `players` WHERE `name` = " . $db->quote('Admin') . ";");
if($query->rowCount() == 1) {
$query = $query->fetch();
$player_id = $query['id'];
}
if(query("INSERT INTO `myaac_news` (`id`, `type`, `date`, `category`, `title`, `body`, `player_id`, `comments`, `hidden`) VALUES (NULL, '1', UNIX_TIMESTAMP(), '2', 'Hello!', 'MyAAC is just READY to use!', " . $player_id . ", 'http://my-aac.org', '0');
INSERT INTO `myaac_news` (`id`, `type`, `date`, `category`, `title`, `body`, `player_id`, `comments`, `hidden`) VALUES (NULL, '2', UNIX_TIMESTAMP(), '4', 'Hello tickets!', 'http://my-aac.org', " . $player_id . ", '', '0');")) {
success($locale['step_database_created_news']);
}
$deleted = 'deleted';
if(fieldExist('deletion', 'players'))
$deleted = 'deletion';
$insert_into_players = "INSERT INTO `players` (`id`, `name`, `group_id`, `account_id`, `level`, `vocation`, `health`, `healthmax`, `experience`, `lookbody`, `lookfeet`, `lookhead`, `looklegs`, `looktype`, `maglevel`, `mana`, `manamax`, `manaspent`, `soul`, `town_id`, `posx`, `posy`, `posz`, `conditions`, `cap`, `sex`, `lastlogin`, `lastip`, `save`, `lastlogout`, `balance`, `$deleted`, `created`, `hidden`, `comment`) VALUES ";
$success = true;
$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', 4, " . getSession('account') . ", 1, 0, 150, 150, 4200, 118, 114, 38, 57, 130, 0, 0, 0, 0, 100, 11, 2200, 1298, 7, '', 400, 1, 1255179613, 2453925456, 1, 1255179614, 0, 0, UNIX_TIMESTAMP(), 1, '');"))
$success = false;
}
$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', 4, " . getSession('account') . ", 8, 1, 185, 185, 4200, 118, 114, 38, 57, 130, 0, 35, 35, 0, 100, 11, 2200, 1298, 7, '', 470, 1, 1255179571, 2453925456, 1, 1255179612, 0, 0, UNIX_TIMESTAMP(), 1, '');"))
$success = false;
}
$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', 4, " . getSession('account') . ", 8, 2, 185, 185, 4200, 118, 114, 38, 57, 130, 0, 35, 35, 0, 100, 11, 2200, 1298, 7, '', 470, 1, 1255179655, 2453925456, 1, 1255179658, 0, 0, UNIX_TIMESTAMP(), 1, '');"))
$success = false;
}
$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', 4, " . getSession('account') . ", 8, 3, 185, 185, 4200, 118, 114, 38, 57, 129, 0, 35, 35, 0, 100, 11, 2200, 1298, 7, '', 470, 1, 1255179854, 2453925456, 1, 1255179858, 0, 0, UNIX_TIMESTAMP(), 1, '');"))
$success = false;
}
$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', 4, " . getSession('account') . ", 8, 4, 185, 185, 4200, 118, 114, 38, 57, 131, 0, 35, 35, 0, 100, 11, 2200, 1298, 7, '', 470, 1, 1255179620, 2453925456, 1, 1255179654, 0, 0, UNIX_TIMESTAMP(), 1, '');"))
$success = false;
}
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());
}
$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'])) {
file_get_contents('http://my-aac.org/report_install.php?v=' . MYAAC_VERSION . '&b=' . urlencode(BASE_URL));
$_SESSION['installed'] = true;
}
foreach($_SESSION as $key => $value) {
if(strpos($key, 'var_') !== false)
unset($_SESSION[$key]);
}
unset($_SESSION['saved']);
}
}
?>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -7,6 +7,7 @@ if(php_sapi_name() != "cli") {
require_once('../../common.php');
require_once(SYSTEM . 'functions.php');
require_once(SYSTEM . 'init.php');
require_once(SYSTEM . 'hooks.php');
require_once(LIBS . 'plugins.php');
if($argc != 2) {
@@ -28,7 +29,7 @@ if(Plugins::install($path_to_file)) {
echo 'WARNING: ' . $warning;
}
$info = Plugins::getPluginInfo();
$info = Plugins::getPlugin();
echo (isset($info['name']) ? $info['name'] . ' p' : 'P') . 'lugin has been successfully installed.';
}
else

View File

@@ -1,14 +1,24 @@
<?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!');
$clients_list = array(
$config['clients'] = array(
710,
740,
750,
760,
770,
772,
780,
7920,
792,
800,
810,
821,
@@ -65,20 +75,4 @@ $clients_list = array(
1098,
1100,
);
$clients = array();
foreach($clients_list as $client) {
$client_version = (string)($client / 100);
if(strpos($client_version, '.') == false)
$client_version .= '.0';
$clients[$client] = $client_version;
}
echo $twig->render('install.config.html.twig', array(
'clients' => $clients,
'locale' => $locale,
'session' => $_SESSION,
'buttons' => next_buttons()
));
?>

75
system/compat.php Normal file
View File

@@ -0,0 +1,75 @@
<?php
/**
* Deprecated functions (compat)
*
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2017 MyAAC
* @link http://my-aac.org
*/
defined('MYAAC') or die('Direct access not allowed!');
function check_name($name, &$errors = '') {
if(Validator::characterName($name))
return true;
$errors = Validator::getLastError();
return false;
}
function check_account_id($id, &$errors = '') {
if(Validator::accountId($id))
return true;
$errors = Validator::getLastError();
return false;
}
function check_account_name($name, &$errors = '') {
if(Validator::accountName($name))
return true;
$errors = Validator::getLastError();
return false;
}
function check_name_new_char($name, &$errors = '') {
if(Validator::newCharacterName($name))
return true;
$errors = Validator::getLastError();
return false;
}
function check_rank_name($name, &$errors = '') {
if(Validator::rankName($name))
return true;
$errors = Validator::getLastError();
return false;
}
function check_guild_name($name, &$errors = '') {
if(Validator::guildName($name))
return true;
$errors = Validator::getLastError();
return false;
}
function news_place() {
return tickers();
}
function tableExist($table)
{
global $db;
return $db->hasTable($table);
}
function fieldExist($field, $table)
{
global $db;
return $db->hasColumn($table, $field);
}
?>

View File

@@ -5,7 +5,6 @@
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2017 MyAAC
* @version 0.6.2
* @link http://my-aac.org
*/
defined('MYAAC') or die('Direct access not allowed!');

View File

@@ -5,7 +5,6 @@
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2017 MyAAC
* @version 0.6.2
* @link http://my-aac.org
*/
defined('MYAAC') or die('Direct access not allowed!');

View File

@@ -5,7 +5,6 @@
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2017 MyAAC
* @version 0.6.2
* @link http://my-aac.org
*/
defined('MYAAC') or die('Direct access not allowed!');

View File

@@ -1,4 +1,12 @@
<?php
/**
* Database connection
*
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2017 MyAAC
* @link http://my-aac.org
*/
defined('MYAAC') or die('Direct access not allowed!');
if(!isset($config['database_type'][0]) || !isset($config['database_user'][0]) || !isset($config['database_password'][0]) || !isset($config['database_name'][0]))
@@ -68,13 +76,17 @@ defined('MYAAC') or die('Direct access not allowed!');
if(isset($config['lua']['useMD5Passwords']) && getBoolean($config['lua']['useMD5Passwords']))
$config['database_encryption'] = 'md5';
if(!isset($config['database_log'])) {
$config['database_log'] = false;
}
try {
$ots->connect(POT::DB_MYSQL,
array(
$ots->connect(array(
'host' => $config['database_host'],
'user' => $config['database_user'],
'password' => $config['database_password'],
'database' => $config['database_name']
'database' => $config['database_name'],
'log' => $config['database_log']
)
);
}

View File

@@ -5,27 +5,29 @@
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2017 MyAAC
* @version 0.6.2
* @link http://my-aac.org
*/
defined('MYAAC') or die('Direct access not allowed!');
function success($message, $return = false) {
if($return)
return '<p class="success">' . $message . '</p>';
echo '<p class="success">' . $message . '</p>';
function message($message, $type, $return)
{
if($return)
return '<p class="' . $type . '">' . $message . '</p>';
echo '<p class="' . $type . '">' . $message . '</p>';
return true;
}
function success($message, $return = false) {
return message($message, 'success', $return);
}
function warning($message, $return = false) {
if($return)
return '<p class="warning">' . $message . '</p>';
echo '<p class="warning">' . $message . '</p>';
return message($message, 'warning', $return);
}
function note($message, $return = false) {
return message($message, 'note', $return);
}
function error($message, $return = false) {
if($return)
return '<p class="error">' . $message . '</p>';
echo '<p class="error">' . $message . '</p>';
return message($message, 'error', $return);
}
function longToIp($ip)
@@ -67,7 +69,7 @@ function getPlayerLink($name, $generate = true)
if(is_numeric($name))
{
$player = $ots->createObject('Player');
$player = new OTS_Player();
$player->load(intval($name));
if($player->isLoaded())
$name = $player->getName();
@@ -154,6 +156,10 @@ function getFlagImage($country)
if(!isset($config['countries']))
require(SYSTEM . 'countries.conf.php');
if(!isset($config['countries'][$country])) {
return '';
}
return '<img src="images/flags/' . $country . '.gif" title="' . $config['countries'][$country]. '"/>';
}
@@ -165,7 +171,9 @@ function getFlagImage($country)
*/
function getBoolean($v)
{
if(!$v || !isset($v[0])) return false;
if(is_bool($v)) {
return $v;
}
if(is_numeric($v))
return intval($v) > 0;
@@ -300,22 +308,6 @@ function encrypt($str)
return $str;
}
function tableExist($table)
{
global $db, $config;
$query = $db->query("SELECT `TABLE_NAME` FROM `information_schema`.`tables` WHERE `TABLE_SCHEMA` = " . $db->quote($config['database_name']) . " AND `TABLE_NAME` = " . $db->quote($table) . ";");
return $query->rowCount() > 0;
}
function fieldExist($field, $table)
{
global $db;
if(count($db->query("SHOW COLUMNS FROM `" . $table . "` LIKE '" . $field . "'")->fetchAll()))
return true;
return false;
}
//delete player with name
function delete_player($name)
{
@@ -374,9 +366,9 @@ function delete_guild($id)
global $db, $ots;
foreach($rank_list as $rank_in_guild) {
if(tableExist('guild_members'))
if($db->hasTable('guild_members'))
$players_with_rank = $db->query('SELECT `players`.`id` as `id`, `guild_members`.`rank_id` as `rank_id` FROM `players`, `guild_members` WHERE `guild_members`.`rank_id` = ' . $rank_in_guild->getId() . ' AND `players`.`id` = `guild_members`.`player_id` ORDER BY `name`;');
else if(tableExist('guild_membership'))
else if($db->hasTable('guild_membership'))
$players_with_rank = $db->query('SELECT `players`.`id` as `id`, `guild_membership`.`rank_id` as `rank_id` FROM `players`, `guild_membership` WHERE `guild_membership`.`rank_id` = ' . $rank_in_guild->getId() . ' AND `players`.`id` = `guild_membership`.`player_id` ORDER BY `name`;');
else
$players_with_rank = $db->query('SELECT `id`, `rank_id` FROM `players` WHERE `rank_id` = ' . $rank_in_guild->getId() . ' AND `deleted` = 0;');
@@ -384,7 +376,7 @@ function delete_guild($id)
$players_with_rank_number = $players_with_rank->rowCount();
if($players_with_rank_number > 0) {
foreach($players_with_rank as $result) {
$player = $ots->createObject('Player');
$player = new OTS_Player();
$player->load($result['id']);
if(!$player->isLoaded())
continue;
@@ -411,42 +403,16 @@ function short_text($text, $limit)
return $text;
}
function news_place()
function tickers()
{
global $template_path, $news_content;
global $tickers_content, $featured_article;
$news = '';
if(PAGE == 'news')
{
//add tickers to site - without it tickers will not be showed
if(isset($news_content))
$news .= $news_content;
//featured article
/* $news .= ' <div id="featuredarticle" class="Box">
<div class="Corner-tl" style="background-image:url('.$template_path.'/images/content/corner-tl.gif);"></div>
<div class="Corner-tr" style="background-image:url('.$template_path.'/images/content/corner-tr.gif);"></div>
<div class="Border_1" style="background-image:url('.$template_path.'/images/content/border-1.gif);"></div>
<div class="BorderTitleText" style="background-image:url('.$template_path.'/images/content/title-background-green.gif);"></div>
<img class="Title" src="'.$template_path.'/images/strings/headline-featuredarticle.gif" alt="Contentbox headline" />
<div class="Border_2">
<div class="Border_3">
<div class="BoxContent" style="background-image:url('.$template_path.'/images/content/scroll.gif);">
<div id=\'TeaserThumbnail\'><img src="'.$template_path.'/images/news/features.jpg" width=150 height=100 border=0 alt="" /></div><div id=\'TeaserText\'><div style="position: relative; top: -2px; margin-bottom: 2px;" >
<b>Tutaj wpisz tytul</b></div>
tutaj wpisz tresc newsa<br>
zdjecie laduje sie w <i>tibiacom/images/news/features.jpg</i><br>
skad sie laduje mozesz zmienic linijke ponad komentarzem
</div> </div>
</div>
</div>
<div class="Border_1" style="background-image:url('.$template_path.'/images/content/border-1.gif);"></div>
<div class="CornerWrapper-b"><div class="Corner-bl" style="background-image:url('.$template_path.'/images/content/corner-bl.gif);"></div></div>
<div class="CornerWrapper-b"><div class="Corner-br" style="background-image:url('.$template_path.'/images/content/corner-br.gif);"></div></div>
</div>';*/
if(PAGE == 'news') {
if(isset($tickers_content))
return $tickers_content . $featured_article;
}
return $news;
return '';
}
/**
@@ -485,8 +451,8 @@ function template_header($is_admin = false)
<meta http-equiv="content-type" content="text/html; charset=' . $charset . '" />';
if(!$is_admin)
$ret .= '
<title>' . $title_full . '</title>
<base href="' . BASE_URL . '" />';
<base href="' . BASE_URL . '" />
<title>' . $title_full . '</title>';
$ret .= '
<meta name="description" content="' . $config['meta_description'] . '" />
@@ -587,7 +553,7 @@ function getCreatureName($killer, $showStatus = false, $extendedInfo = false)
if(is_numeric($killer))
{
$player = $ots->createObject('Player');
$player = new OTS_Player();
$player->load($killer);
if($player->isLoaded())
{
@@ -597,7 +563,7 @@ function getCreatureName($killer, $showStatus = false, $extendedInfo = false)
$str .= '<font color="'.($player->isOnline() ? 'green' : 'red').'">' . $player->getName() . '</font></b></a>';
if($extendedInfo) {
$str .= '<br><small>'.$player->getLevel().' '.$config['vocations'][$player->getVocation()].'</small>';
$str .= '<br><small>'.$player->getLevel().' '.$player->getVocationName().'</small>';
}
return $str;
}
@@ -840,9 +806,9 @@ function _mail($to, $subject, $body, $altBody = '', $add_html_tags = true)
$signature_html = $config['mail_signature']['html'];
if($add_html_tags && isset($body[0]))
$body = '<html><head></head><body>' . $body . '<br/><br/>' . $signature_html . '</body></html>';
$tmp_body = '<html><head></head><body>' . $body . '<br/><br/>' . $signature_html . '</body></html>';
else
$body .= '<br/><br/>' . $signature_html;
$tmp_body .= '<br/><br/>' . $signature_html;
if($config['smtp_enabled'])
{
@@ -863,7 +829,7 @@ function _mail($to, $subject, $body, $altBody = '', $add_html_tags = true)
$mailer->FromName = $config['lua']['serverName'];
$mailer->Subject = $subject;
$mailer->AddAddress($to);
$mailer->Body = $body;
$mailer->Body = $tmp_body;
$signature_plain = '';
if(isset($config['mail_signature']['plain']))
@@ -871,6 +837,9 @@ function _mail($to, $subject, $body, $altBody = '', $add_html_tags = true)
if(isset($altBody[0]))
$mailer->AltBody = $altBody . $signature_plain;
else { // automatically generate plain html
$mailer->AltBody = strip_tags(preg_replace('/<a(.*)href="([^"]*)"(.*)>/','$2', $body)) . "\n" . $signature_plain;
}
return $mailer->Send();
}
@@ -958,6 +927,7 @@ function str_replace_first($search, $replace, $subject) {
if ($pos !== false) {
return substr_replace($subject, $replace, $pos, strlen($search));
}
return $subject;
}
@@ -974,6 +944,71 @@ function unsetSession($key) {
unset($_SESSION[$config['session_prefix'] . $key]);
}
function getTopPlayers($limit = 5) {
global $cache, $config, $db;
$fetch_from_db = true;
if($cache->enabled())
{
$tmp = '';
if($cache->fetch('top_' . $limit . '_level', $tmp))
{
$players = unserialize($tmp);
$fetch_from_db = false;
}
}
if($fetch_from_db)
{
$deleted = 'deleted';
if($db->hasColumn('players', 'deletion'))
$deleted = 'deletion';
$is_tfs10 = $db->hasTable('players_online');
$players = $db->query('SELECT `id`, `name`, `level`, `experience`' . ($is_tfs10 ? '' : ', `online`') . ' FROM `players` WHERE `group_id` < ' . $config['highscores_groups_hidden'] . ' AND `id` NOT IN (' . implode(', ', $config['highscores_ids_hidden']) . ') AND `' . $deleted . '` = 0 AND `account_id` != 1 ORDER BY `experience` DESC LIMIT ' . (int)$limit)->fetchAll();
if($is_tfs10) {
foreach($players as &$player) {
$query = $db->query('SELECT `player_id` FROM `players_online` WHERE `player_id` = ' . $player['id']);
$player['online'] = ($query->rowCount() > 0 ? 1 : 0);
}
}
$i = 0;
foreach($players as &$player) {
$player['rank'] = ++$i;
}
if($cache->enabled())
$cache->set('top_' . $limit . '_level', serialize($players), 120);
}
return $players;
}
function deleteDirectory($dir) {
if(!file_exists($dir)) {
return true;
}
if(!is_dir($dir)) {
return unlink($dir);
}
foreach(scandir($dir) as $item) {
if($item == '.' || $item == '..') {
continue;
}
if(!deleteDirectory($dir . DIRECTORY_SEPARATOR . $item)) {
return false;
}
}
return rmdir($dir);
}
// validator functions
require_once(LIBS . 'validator.php');
require_once(SYSTEM . 'compat.php');
?>

View File

@@ -5,7 +5,6 @@
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2017 MyAAC
* @version 0.6.2
* @link http://my-aac.org
*/
defined('MYAAC') or die('Direct access not allowed!');

View File

@@ -5,18 +5,17 @@
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2017 MyAAC
* @version 0.6.2
* @link http://my-aac.org
*/
defined('MYAAC') or die('Direct access not allowed!');
// load configuration
require_once(BASE . 'config.php');
if(file_exists(BASE . 'config.local.php')) // user customizations
require(BASE . 'config.local.php');
if(!isset($config['installed']) || !$config['installed']) {
header('Location: ' . BASE_URL);
die('AAC has not been installed yet or there was error during installation. Please install again.');
die('MyAAC has not been installed yet or there was error during installation. Please install again.');
}
date_default_timezone_set($config['date_timezone']);
@@ -39,7 +38,8 @@ Twig_Autoloader::register();
$twig_loader = new Twig_Loader_Filesystem(SYSTEM . 'templates');
$twig = new Twig_Environment($twig_loader, array(
'cache' => CACHE . 'twig/',
'auto_reload' => true
'auto_reload' => true,
//'debug' => true
));
$function = new Twig_SimpleFunction('getStyle', function ($i) {
@@ -48,11 +48,7 @@ $function = new Twig_SimpleFunction('getStyle', function ($i) {
$twig->addFunction($function);
$function = new Twig_SimpleFunction('getLink', function ($s) {
global $config;
if($config['friendly_urls'])
return $s;
return '?' . $s;
return getLink($s);
});
$twig->addFunction($function);
@@ -62,6 +58,11 @@ $function = new Twig_SimpleFunction('hook', function ($hook) {
});
$twig->addFunction($function);
$filter = new Twig_SimpleFilter('urlencode', function ($s) {
return urlencode($s);
});
$twig->addFilter($filter);
// trim values we receive
if(isset($_POST))
{
@@ -87,21 +88,26 @@ if(isset($_REQUEST))
}
// load otserv config file
$tmp = '';
if($cache->enabled() && $cache->fetch('config_lua', $tmp)) {
$config_lua_reload = true;
if($cache->enabled()) {
$tmp = null;
if($cache->fetch('server_path', $tmp) && $tmp == $config['server_path']) {
$tmp = null;
if($cache->fetch('config_lua', $tmp) && $tmp) {
$config['lua'] = unserialize($tmp);
/*if(isset($config['lua']['myaac'][0])) {
foreach($config['lua']['myaac'] as $key => $value)
$config[$key] = $value;
}*/
$config_lua_reload = false;
}
else
{
}
}
if($config_lua_reload) {
$config['lua'] = load_config_lua($config['server_path'] . 'config.lua');
// cache config
if($cache->enabled())
if($cache->enabled()) {
$cache->set('config_lua', serialize($config['lua']), 120);
$cache->set('server_path', $config['server_path']);
}
}
unset($tmp);
@@ -148,12 +154,17 @@ else
$config['data_path'] = $tmp;
unset($tmp);
// new config values for compability
if(!isset($config['highscores_ids_hidden']) || count($config['highscores_ids_hidden']) == 0) {
$config['highscores_ids_hidden'] = array(0);
}
// POT
require_once(SYSTEM . 'libs/pot/OTS.php');
$ots = POT::getInstance();
require_once(SYSTEM . 'database.php');
define('USE_ACCOUNT_NAME', fieldExist('name', 'accounts'));
define('USE_ACCOUNT_NAME', $db->hasColumn('accounts', 'name'));
// load vocation names
$tmp = '';
if($cache->enabled() && $cache->fetch('vocations', $tmp)) {

View File

@@ -5,7 +5,6 @@
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2017 MyAAC
* @version 0.6.2
* @link http://my-aac.org
*/
defined('MYAAC') or die('Direct access not allowed!');

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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