Compare commits

..

61 Commits

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

4
.gitattributes vendored
View File

@@ -1,4 +0,0 @@
* text=auto
.gitattributes export-ignore
.gitignore export-ignore
_config.yml export-ignore

3
.gitignore vendored
View File

@@ -1,3 +0,0 @@
Thumbs.db
.DS_Store
.idea

View File

@@ -1,63 +1,4 @@
# Changelog [0.7.7 - 08.01.2018]
## [0.7.11 - 04.05.2019]
### Added:
* support for some old servers, where arrays are used in config.lua
* an additional text to the install page informing that user can reinstall MyAAC by deleting config.local.php
### Fixed:
* XSS in forum show_thread
* guilds - "Add new rank" function
* multiple mail recipients when using admin mailer function
* Admin Panel - MyAAC logs not shown if servers logs directory doesn't exist (#47)
* missing prefix for cache get() and delete() functions
* add fatal error message when myaac tables in database do not exist
* the mystical defect where "Create Account" button was not highlighted (on the account/manage page)
* bug where server_config table does not exist (OTHire as an example)
* database_name in Usage_Statistics
* forgot to open <head> in install template
### Changed:
* do not display software version
## [0.7.10 - 03.03.2018]
### Added:
* new configurable: smtp_secure
* robots.txt
### Fixed:
* editing an existing page that had php enabled
* chrome bug on save (when editing page) ERR_BLOCKED_BY_XSS_AUDITOR
* showing IP and Port in admin panel (#44, by miqueiaspenha)
* deleting plugin showing "You don't have rights to delete"
* some bug with PHPMailer not finding its language file
* default accounts.vote value
* saving some really high long ip addresses
### Changed:
* update config.highscores_ids_hidden on install when there are samples already in database
* auto add z_polls table on install
### Internal:
* changed mb_strtolower functions to strtolower()
* added new function: $hooks->exist($type)
## [0.7.9 - 13.01.2018]
* removed 6mb of trash (some useless things)
* (fix) TFS 1.x not showing promoted vocations in highscores
* otserv 0.6.x: fixed some warning (on the characters page) and fatal mysql error (on the mango signature)
* fixed default stamina on otserv 0.6.x engine (and some others perhaps)
* install: change permission check to is_writable
* changed highscores_groups_hidden to 3 (for TFS 1.x)
* updated background-artwork (tibiacom template) to the latest version, removed other ones
## [0.7.8 - 12.01.2018]
* fixed installation error " call to undefined method OTS_DB_MySQL::hasColumn()"
* updated tinymce to the latest (4.7.4) version
* enabled emoticons plugin in tinymce :)
* some security fixes
## [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) * 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 * immediately reload config.lua when there's change in config.server_path detected
* added new forum option: "Enable HTML" (only for moderators) * added new forum option: "Enable HTML" (only for moderators)
@@ -76,14 +17,14 @@
* don't add extra <br/> to the TinyMCE news forum posts * don't add extra <br/> to the TinyMCE news forum posts
* (internal) using $player->getVocationName() where possible instead of older method * (internal) using $player->getVocationName() where possible instead of older method
## [0.7.6 - 05.01.2017] [0.7.6 - 05.01.2017]
* fixed othire account creating/installation * fixed othire account creating/installation
* fixed table name players -> players_online * fixed table name players -> players_online
* fixed unexpected error logging about email fail * fixed unexpected error logging about email fail
* added max_execution_time to the install finish step * added max_execution_time to the install finish step
* some small fix regarding highscores vocation box * some small fix regarding highscores vocation box
## [0.7.5 - 04.01.2017] [0.7.5 - 04.01.2017]
* fixed bug on othire with config.account_premium_days * fixed bug on othire with config.account_premium_days
* fixed bug on TFS 1.x when online_afk is enabled * fixed bug on TFS 1.x when online_afk is enabled
* warning about leaving news page with changes * warning about leaving news page with changes
@@ -96,7 +37,7 @@
* fixed template path finding * fixed template path finding
* fixed displaying article_text when it was empty saved * fixed displaying article_text when it was empty saved
## [0.7.4 - 24.12.2017] [0.7.4 - 24.12.2017]
* fixed mysql fatal error on tibiacom template - top 5 box * fixed mysql fatal error on tibiacom template - top 5 box
* fixed displaying of level percent bar on tibian signature * fixed displaying of level percent bar on tibian signature
* inform user about Twig cache failure on installation, instead of http 500 error * inform user about Twig cache failure on installation, instead of http 500 error
@@ -104,7 +45,7 @@
* remember client version select and usage stats checkbox in session on install * remember client version select and usage stats checkbox in session on install
* automatically update highscores_ids_hidden for users who installed myaac before (migration) * automatically update highscores_ids_hidden for users who installed myaac before (migration)
## [0.7.3 - 18.12.2017] [0.7.3 - 18.12.2017]
* auto generate myaac cache & session prefix on install to be unique across installations * 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 * fixed hiding shop system menu on tibiacom template when disabled in config
* prevent adding duplicated newses with installation * prevent adding duplicated newses with installation
@@ -114,12 +55,12 @@
* fixed account.login redirect not working on tibiacom template * fixed account.login redirect not working on tibiacom template
* installation: warn about wrong admin account name/id and password * installation: warn about wrong admin account name/id and password
* fixed last menu closing in tibiacom template * fixed last menu closing in tibiacom template
* updated polish locale (translation) on install * updated polish locale (translation) on install
* (internal) removed some duplicated code on install finish * (internal) removed some duplicated code on install finish
* (internal) renamed installation step files to be in correct order * (internal) renamed installation step files to be in correct order
* added TODO file * added TODO file
## [0.7.1 - 13.12.2017] [0.7.1 - 13.12.2017]
* added changelog menu item to kathrine template * added changelog menu item to kathrine template
* fixed some php short tag in changelogs page * fixed some php short tag in changelogs page
* fixed guild change description back button * fixed guild change description back button
@@ -127,7 +68,7 @@
* changed some notice when version check is failed * changed some notice when version check is failed
* (internal) moved changelog to twig * (internal) moved changelog to twig
## [0.7.0 - 20.11.2017] [0.7.0 - 20.11.2017]
* moved template menus to database, they're now dynamically loaded * 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) * 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 edit them in Admin Panel under 'Menus' option
@@ -163,25 +104,25 @@
* (internal) added some compat functions that are used by shop system * (internal) added some compat functions that are used by shop system
* (internal) renamed constant TICKET -> TICKER * (internal) renamed constant TICKET -> TICKER
* (internal) shortened message functions * (internal) shortened message functions
## [0.6.6 - 22.10.2017] [0.6.6 - 22.10.2017]
* fixed some php fatal error on spells page * fixed some php fatal error on spells page
* changed spells.vocations field in db size to 300 * changed spells.vocations field in db size to 300
* please reload your spells after this update! * please reload your spells after this update!
## [0.6.5 - 21.10.2017] [0.6.5 - 21.10.2017]
* fixed displaying custom pages * fixed displaying custom pages
* fixed adding new group forum board * fixed adding new group forum board
## [0.6.4 - 20.10.2017] [0.6.4 - 20.10.2017]
* reverted OTS_Account::getLastLogin() cause its used by tibia11-login plugin * reverted OTS_Account::getLastLogin() cause its used by tibia11-login plugin
## [0.6.3 - 20.10.2017] [0.6.3 - 20.10.2017]
* fixed creating account * fixed creating account
* fixed viewing thread without being logged * fixed viewing thread without being logged
* fixed showing premium account status * fixed showing premium account status
## [0.6.2 - 20.10.2017] [0.6.2 - 20.10.2017]
* added forums for guilds and groups * added forums for guilds and groups
* added nice looking menu for my account page in default template * 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" * new command line tool: install_plugin.php - can be used to install plugins from command line. Usage: "php install_plugin.php path_to_file"
@@ -213,8 +154,8 @@
* (internal) optimized Spells class * (internal) optimized Spells class
* (internal) new function: OTS_Guild::hasMember(OTS_Player $player) * (internal) new function: OTS_Guild::hasMember(OTS_Player $player)
* (internal) new function: Forum::hasAccess($board_id) * (internal) new function: Forum::hasAccess($board_id)
## [0.6.1 - 17.10.2017] [0.6.1 - 17.10.2017]
* fixed signatures loading * fixed signatures loading
* new configurable: session_prefix, to allow more websites on one machine (must be unique for every website on your dedicated server!) * 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) * better error handling for monsters and spells loader (save errors to system/logs/error.log)
@@ -224,7 +165,7 @@
* (internal) moved forum actions (pages) to forum/ directory * (internal) moved forum actions (pages) to forum/ directory
* (internal) moved forum.edit_post to twig templates * (internal) moved forum.edit_post to twig templates
## [0.6.0 - 16.10.2017] [0.6.0 - 16.10.2017]
* added faq management - add/edit/move/hide/delete from website * added faq management - add/edit/move/hide/delete from website
* new account.login view for tibiacom template * new account.login view for tibiacom template
* monsters and spells are now being loaded at the installation of the AAC * monsters and spells are now being loaded at the installation of the AAC
@@ -247,7 +188,7 @@
* ajax requests returns now json instead of xml * ajax requests returns now json instead of xml
* added 404 response when file is not found * added 404 response when file is not found
## [0.5.1 - 11.10.2017] [0.5.1 - 11.10.2017]
* fixed forum add/edit board * fixed forum add/edit board
* new configurable: highscores_length, how much highscores to display * new configurable: highscores_length, how much highscores to display
* fixed highscores links (ALL, previous and next page) * fixed highscores links (ALL, previous and next page)
@@ -257,7 +198,7 @@
* check if plugin exist before uninstalling * check if plugin exist before uninstalling
* fixed some warning in OTS_Base_DB * fixed some warning in OTS_Base_DB
## [0.5.0 - 10.10.2017] [0.5.0 - 10.10.2017]
* moved .htaccess rules to plain php (index.php) * 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 * 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 uninstall plugin
@@ -276,7 +217,7 @@
* added new twig function getLink that convert link taking into account config.friendly_urls * added new twig function getLink that convert link taking into account config.friendly_urls
* internalLayoutLink -> getLink * internalLayoutLink -> getLink
## [0.4.3 - 05.10.2017] [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') * 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 country detection in create account
* fixed showing of character deaths and frags * fixed showing of character deaths and frags
@@ -290,14 +231,14 @@
* added bugtracker to kathrine template * added bugtracker to kathrine template
* added CREDITS file * added CREDITS file
## [0.4.2 - 14.09.2017] [0.4.2 - 14.09.2017]
* updated version number * updated version number
## [0.4.1 - 13.09.2017] [0.4.1 - 13.09.2017]
* fixed log in to admin panel * fixed log in to admin panel
* fixed File is not .zip plugin upload error * fixed File is not .zip plugin upload error
## [0.4.0 - 13.09.2017 [0.4.0 - 13.09.2017
* added option to add/edit/delete/hide/move forum boards * added option to add/edit/delete/hide/move forum boards
* moved some of HTML-in-PHP code to Twig templates * moved some of HTML-in-PHP code to Twig templates
* added bug_report configurable which can enable/disable bug tracker * added bug_report configurable which can enable/disable bug tracker
@@ -314,7 +255,7 @@
* some small improvements * some small improvements
* fixed some separators in kathrine template * fixed some separators in kathrine template
## [0.3.0 - 28.08.2017] [0.3.0 - 28.08.2017]
* added administration panel for screenshots management with auto thumbnail generator and image auto-resizing * 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 * 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 * automatically detect player country based on user location (IP) on create account
@@ -332,7 +273,7 @@
* moved news adding at installation from schema.sql to finish.php * moved news adding at installation from schema.sql to finish.php
* some optimizations * some optimizations
## [0.2.4 - 09.06.2017] [0.2.4 - 09.06.2017]
* fixed invite to guild * fixed invite to guild
* added id field on monsters, so you can delete them in phpmyadmin * added id field on monsters, so you can delete them in phpmyadmin
* fixed adding some creatures with ' and " * fixed adding some creatures with ' and "
@@ -341,7 +282,7 @@
* fixed typo loss_items => loss_containers * fixed typo loss_items => loss_containers
* more elegant way of showing message on reload creatures and spells * more elegant way of showing message on reload creatures and spells
## [0.2.3 - 31.05.2017] [0.2.3 - 31.05.2017]
* fixed guild management on OTHire 0.0.3 * fixed guild management on OTHire 0.0.3
* set default skills to 10 when creating new character * set default skills to 10 when creating new character
* fixed displaying of "Create forum thread" in newses * fixed displaying of "Create forum thread" in newses
@@ -353,15 +294,15 @@
* fixed Undefined variable (https://otland.net/threads/myaac-v0-0-1.251454/page-7#post-2444034) * 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 Undefined offset (https://otland.net/threads/myaac-v0-0-1.251454/page-7#post-2444035)
## [0.2.2 - 22.05.2017] [0.2.2 - 22.05.2017]
* added missing cache/signature directory * added missing cache/signature directory
* fixed https://otland.net/threads/myaac-v0-0-1.251454/page-7#post-2443868 * fixed https://otland.net/threads/myaac-v0-0-1.251454/page-7#post-2443868
## [0.2.1 - 21.05.2017] [0.2.1 - 21.05.2017]
* added Swedish translation by Sizaro * added Swedish translation by Sizaro
* fixed some bugs with installlation & characters & houses * fixed some bugs with installlation & characters & houses
## [0.2.0 - 21.05.2017] [0.2.0 - 21.05.2017]
* added option to change character sex for premium points * added option to change character sex for premium points
* moved site_closed to database, now you can close your site through admin panel * moved site_closed to database, now you can close your site through admin panel
* added option to admin panel: clear cache * added option to admin panel: clear cache
@@ -381,10 +322,10 @@
* fixed movies unexpected comment * fixed movies unexpected comment
* added template_place_holder('center_top') to kathrine template * added template_place_holder('center_top') to kathrine template
## [0.1.5 - 13.05.2017] [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] [0.1.4 - 13.05.2017]
* added outfit shower, in characters, online, and highscores * added outfit shower, in characters, online, and highscores
* updated database to version 2 * updated database to version 2
* fixed item images (now using item-images.ots.me host by default) * fixed item images (now using item-images.ots.me host by default)
@@ -393,17 +334,17 @@
* removed some unused code from my old server * removed some unused code from my old server
* added spells & monsters to kathrine template * added spells & monsters to kathrine template
## [0.1.3 - 11.05.2017] [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] [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] [0.1.1 - 11.05.2017]
* fixed updating myaac_config with database_version to 1 * fixed updating myaac_config with database_version to 1
* fixed database updater * fixed database updater
## [0.1.0 - 11.05.2017] [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 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) * added automatic database updater (data migrations)
* renamed events to hooks * renamed events to hooks
@@ -427,13 +368,13 @@
* fixed signatures (many fixes) * fixed signatures (many fixes)
* added missing gesior signature system * added missing gesior signature system
## [0.0.6 - 06.05.2017] [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 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 bug when creating character (not showing errors) (one more time)
* fixed support for TFS 0.2 series * fixed support for TFS 0.2 series
* added FAQ link * added FAQ link
## [0.0.5 - 05.05.2017] [0.0.5 - 05.05.2017]
* fixed bug when creating character (not showing errors) * fixed bug when creating character (not showing errors)
* Fixed characters loading with names that has been created with other AAC * Fixed characters loading with names that has been created with other AAC
* fixed links to shop in default template * fixed links to shop in default template
@@ -446,7 +387,7 @@
* fixes when $config['database_*'] is set * fixes when $config['database_*'] is set
* added CHANGELOG * added CHANGELOG
## [0.0.3 - 03.05.2017] [0.0.3 - 03.05.2017]
* Full support for OTHire 0.0.3 * 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 * 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 encryption detection on TFS 0.3
@@ -457,7 +398,7 @@
* fixed installation errors * fixed installation errors
* fixed config.lua loading with some weird comments * fixed config.lua loading with some weird comments
## [0.0.2 - 02.05.2017] [0.0.2 - 02.05.2017]
* updated forum links to use friendly_urls * updated forum links to use friendly_urls
* some more info will be shown when cannot connect to database * some more info will be shown when cannot connect to database
* show more error infos when creating character * show more error infos when creating character
@@ -468,8 +409,8 @@
* fixed support for gesior pages and templates * fixed support for gesior pages and templates
* added function OTS_Acount:getGroupId() * added function OTS_Acount:getGroupId()
## [0.0.1 - 01.05.2017] [0.0.1 - 01.05.2017]
This is first official release of MyAAC. This is first official release of MyAAC.
Features are listed here Features are listed here
For more information, see the release announcement on OTLand: https://otland.net/threads/myaac-v0-0-1.251454/ For more information, see the release announcement on OTLand: https://otland.net/threads/myaac-v0-0-1.251454/

View File

@@ -5,7 +5,7 @@ Official website: https://my-aac.org
### REQUIREMENTS ### REQUIREMENTS
- PHP 5.3.3 or later - PHP 5.3.0 or later
- MySQL database - MySQL database
- PDO PHP Extension - PDO PHP Extension
- XML PHP Extension - XML PHP Extension
@@ -28,7 +28,6 @@ Official website: https://my-aac.org
chmod 660 images/guilds chmod 660 images/guilds
chmod 660 images/houses chmod 660 images/houses
chmod 660 images/gallery chmod 660 images/gallery
chmod -R 770 system/cache
Visit http://your_domain/install (http://localhost/install) and follow instructions in the browser. Visit http://your_domain/install (http://localhost/install) and follow instructions in the browser.

37
TODO
View File

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

1
_config.yml Normal file
View File

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

View File

@@ -26,8 +26,8 @@
session_start(); session_start();
define('MYAAC', true); define('MYAAC', true);
define('MYAAC_VERSION', '0.7.11'); define('MYAAC_VERSION', '0.8.0-dev');
define('DATABASE_VERSION', 22); define('DATABASE_VERSION', 21);
define('TABLE_PREFIX', 'myaac_'); define('TABLE_PREFIX', 'myaac_');
define('START_TIME', microtime(true)); define('START_TIME', microtime(true));
define('MYAAC_OS', (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') ? 'WINDOWS' : (strtoupper(PHP_OS) == 'DARWIN' ? 'MAC' : 'LINUX')); define('MYAAC_OS', (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') ? 'WINDOWS' : (strtoupper(PHP_OS) == 'DARWIN' ? 'MAC' : 'LINUX'));
@@ -46,6 +46,7 @@ define('FLAG_CONTENT_GALLERY', 512);
define('FLAG_CONTENT_VIDEOS', 1024); define('FLAG_CONTENT_VIDEOS', 1024);
define('FLAG_CONTENT_FAQ', 2048); define('FLAG_CONTENT_FAQ', 2048);
define('FLAG_CONTENT_MENUS', 4096); define('FLAG_CONTENT_MENUS', 4096);
define('FLAG_CONTENT_PLAYERS', 8192);
// news // news
define('NEWS', 1); define('NEWS', 1);
@@ -99,10 +100,10 @@ if(isset($_SERVER['HTTP_HOST'])) {
define('SERVER_URL', 'https://' . $_SERVER['HTTP_HOST']); define('SERVER_URL', 'https://' . $_SERVER['HTTP_HOST']);
else else
define('SERVER_URL', 'http://' . $_SERVER['HTTP_HOST']); define('SERVER_URL', 'http://' . $_SERVER['HTTP_HOST']);
define('BASE_URL', SERVER_URL . BASE_DIR . '/'); define('BASE_URL', SERVER_URL . BASE_DIR . '/');
define('ADMIN_URL', SERVER_URL . BASE_DIR . '/admin/'); define('ADMIN_URL', SERVER_URL . BASE_DIR . '/admin/');
//define('CURRENT_URL', BASE_URL . $_SERVER['REQUEST_URI']); //define('CURRENT_URL', BASE_URL . $_SERVER['REQUEST_URI']);
} }
?> ?>

View File

@@ -46,8 +46,6 @@ $config = array(
// footer // footer
'footer' => ''/*'<br/>Your Server &copy; 2016. All rights reserved.'*/, 'footer' => ''/*'<br/>Your Server &copy; 2016. All rights reserved.'*/,
'debug_level' => 0, // 0 - disabled, 1 - show load time, 2 - show db query counter, 3 - both, 4 - memory usage, 5 - load time & memory usage, 6 - queries & memory usage, 7 - all
'language' => 'en', // default language (currently only 'en' available) 'language' => 'en', // default language (currently only 'en' available)
'language_allow_change' => false, 'language_allow_change' => false,
@@ -56,7 +54,7 @@ $config = array(
'views_counter' => true, 'views_counter' => true,
// cache system. by default file cache is used // cache system. by default file cache is used
'cache_engine' => 'auto', // apc, eaccelerator, xcache, file, auto, or blank to disable. 'cache_engine' => 'auto', // apc, apcu, eaccelerator, xcache, file, auto, or blank to disable.
'cache_prefix' => 'myaac_', // have to be unique if running more MyAAC instances on the same server (except file system cache) 'cache_prefix' => 'myaac_', // have to be unique if running more MyAAC instances on the same server (except file system cache)
// database details (leave blank for auto detect from config.lua) // database details (leave blank for auto detect from config.lua)
@@ -65,6 +63,7 @@ $config = array(
'database_user' => '', 'database_user' => '',
'database_password' => '', 'database_password' => '',
'database_name' => '', 'database_name' => '',
'database_log' => false, // should database queries be logged and displayed in the page source? They will be included at the end of the .html source of the page
// multiworld system (only TFS 0.3) // multiworld system (only TFS 0.3)
'multiworld' => false, // use multiworld system? 'multiworld' => false, // use multiworld system?
@@ -98,7 +97,7 @@ $config = array(
'mail_address' => 'no-reply@your-server.org', // server e-mail address (from:) 'mail_address' => 'no-reply@your-server.org', // server e-mail address (from:)
'mail_admin' => 'your-address@your-server.org', // admin email address, where mails from contact form will be sent 'mail_admin' => 'your-address@your-server.org', // admin email address, where mails from contact form will be sent
'mail_signature' => array( // signature that will be included at the end of every message sent using _mail function 'mail_signature' => array( // signature that will be included at the end of every message sent using _mail function
'plain' => ''/*'--\nMy Server,\nhttp://www.myserver.com'*/, 'plain' => ""/*"--\nMy Server,\nhttp://www.myserver.com"*/,
'html' => ''/*'<br/>My Server,\n<a href="http://www.myserver.com">myserver.com</a>'*/ 'html' => ''/*'<br/>My Server,\n<a href="http://www.myserver.com">myserver.com</a>'*/
), ),
'smtp_enabled' => false, // send by smtp or mail function (set false if use mail function) 'smtp_enabled' => false, // send by smtp or mail function (set false if use mail function)
@@ -107,7 +106,6 @@ $config = array(
'smtp_auth' => true, // need authorization? 'smtp_auth' => true, // need authorization?
'smtp_user' => 'admin@example.org', 'smtp_user' => 'admin@example.org',
'smtp_pass' => '', 'smtp_pass' => '',
'smtp_secure' => '', // What kind of encryption to use on the SMTP connection. Options: '', 'ssl' or 'tls', use 'ssl' for gmail
// reCAPTCHA (prevent spam bots) // reCAPTCHA (prevent spam bots)
'recaptcha_enabled' => false, // enable recaptcha verification code 'recaptcha_enabled' => false, // enable recaptcha verification code
@@ -186,7 +184,7 @@ $config = array(
'highscores_frags' => false, // show 'Frags' tab (best fraggers on the server)? Only 0.3 'highscores_frags' => false, // show 'Frags' tab (best fraggers on the server)? Only 0.3
'highscores_outfit' => true, // show player outfit? 'highscores_outfit' => true, // show player outfit?
'highscores_country_box' => false, // doesnt work yet! (not implemented) 'highscores_country_box' => false, // doesnt work yet! (not implemented)
'highscores_groups_hidden' => 3, // this group id and higher won't be shown on the highscores '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_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 'highscores_length' => 100, // how many records per page on highscores

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

872
index.php
View File

@@ -1,436 +1,436 @@
<?php <?php
/** /**
* Project: MyAAC * Project: MyAAC
* Automatic Account Creator for Open Tibia Servers * Automatic Account Creator for Open Tibia Servers
* File: index.php * File: index.php
* *
* This is free software; you can redistribute it and/or * This is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either * License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version. * version 2.1 of the License, or (at your option) any later version.
* *
* This software is distributed in the hope that it will be useful, * This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details. * Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* @package MyAAC * @package MyAAC
* @author Slawkens <slawkens@gmail.com> * @author Slawkens <slawkens@gmail.com>
* @copyright 2017 MyAAC * @copyright 2017 MyAAC
* @link http://my-aac.org * @link http://my-aac.org
*/ */
// uncomment if your php.ini have display_errors disabled and you want to see errors // uncomment if your php.ini have display_errors disabled and you want to see errors
// ini_set('display_errors', 1); // ini_set('display_errors', 1);
// ini_set('display_startup_errors', 1); // ini_set('display_startup_errors', 1);
// error_reporting(E_ALL); // error_reporting(E_ALL);
require_once('common.php'); require_once('common.php');
require_once(SYSTEM . 'functions.php'); require_once(SYSTEM . 'functions.php');
$uri = $_SERVER['REQUEST_URI']; $uri = $_SERVER['REQUEST_URI'];
$tmp = BASE_DIR; $tmp = BASE_DIR;
if(!empty($tmp)) if(!empty($tmp))
$uri = str_replace(BASE_DIR . '/', '', $uri); $uri = str_replace(BASE_DIR . '/', '', $uri);
else else
$uri = str_replace_first('/', '', $uri); $uri = str_replace_first('/', '', $uri);
$uri = str_replace(array('index.php/', '?'), '', $uri); $uri = str_replace(array('index.php/', '?'), '', $uri);
define('URI', $uri); define('URI', $uri);
if(preg_match("/^[A-Za-z0-9-_%\'+]+\.png$/i", $uri)) { if(preg_match("/^[A-Za-z0-9-_%\'+]+\.png$/i", $uri)) {
$tmp = explode('.', $uri); $tmp = explode('.', $uri);
$_REQUEST['name'] = urldecode($tmp[0]); $_REQUEST['name'] = urldecode($tmp[0]);
chdir(TOOLS . 'signature'); chdir(TOOLS . 'signature');
include(TOOLS . 'signature/index.php'); include(TOOLS . 'signature/index.php');
exit(); exit();
} }
else if(preg_match("/^(.*)\.(gif|jpg|png|jpeg|tiff|bmp|css|js|less|map|html|php|zip|rar|gz|ttf|woff|ico)$/i", $_SERVER['REQUEST_URI'])) { else if(preg_match("/^(.*)\.(gif|jpg|png|jpeg|tiff|bmp|css|js|less|map|html|php|zip|rar|gz|ttf|woff|ico)$/i", $_SERVER['REQUEST_URI'])) {
header("HTTP/1.0 404 Not Found"); header("HTTP/1.0 404 Not Found");
exit; exit;
} }
require_once(BASE . 'config.local.php'); if(file_exists(BASE . 'config.local.php'))
if(file_exists(BASE . 'install') && (!isset($config['installed']) || !$config['installed'])) require_once(BASE . 'config.local.php');
{
header('Location: ' . BASE_URL . 'install/'); if(file_exists(BASE . 'install') && (!isset($config['installed']) || !$config['installed']))
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!'); {
} 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 = false;
$found = true; if(empty($uri) || isset($_REQUEST['template'])) {
} $_REQUEST['p'] = 'news';
else { $found = true;
$tmp = strtolower($uri); }
if(!preg_match('/[^A-z0-9_\-]/', $uri) && file_exists(SYSTEM . 'pages/' . $tmp . '.php')) { else {
$_REQUEST['p'] = $uri; $tmp = strtolower($uri);
$found = true; if(!preg_match('/[^A-z0-9_\-]/', $uri) && file_exists(SYSTEM . 'pages/' . $tmp . '.php')) {
} $_REQUEST['p'] = $uri;
else { $found = true;
$rules = array( }
'/^account\/manage\/?$/' => array('subtopic' => 'accountmanagement'), else {
'/^account\/create\/?$/' => array('subtopic' => 'createaccount'), $rules = array(
'/^account\/lost\/?$/' => array('subtopic' => 'lostaccount'), '/^account\/manage\/?$/' => array('subtopic' => 'accountmanagement'),
'/^account\/logout\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'logout'), '/^account\/create\/?$/' => array('subtopic' => 'createaccount'),
'/^account\/password\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_password'), '/^account\/lost\/?$/' => array('subtopic' => 'lostaccount'),
'/^account\/register\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'register'), '/^account\/logout\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'logout'),
'/^account\/register\/new\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'register_new'), '/^account\/password\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_password'),
'/^account\/email\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_email'), '/^account\/register\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'register'),
'/^account\/info\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_info'), '/^account\/register\/new\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'register_new'),
'/^account\/character\/create\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'create_character'), '/^account\/email\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_email'),
'/^account\/character\/name\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_name'), '/^account\/info\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_info'),
'/^account\/character\/sex\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_sex'), '/^account\/character\/create\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'create_character'),
'/^account\/character\/delete\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'delete_character'), '/^account\/character\/name\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_name'),
'/^account\/character\/comment\/[A-Za-z0-9-_%+\']+\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_comment', 'name' => '$3'), '/^account\/character\/sex\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_sex'),
'/^account\/character\/comment\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_comment'), '/^account\/character\/delete\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'delete_character'),
'/^account\/confirm_email\/[A-Za-z0-9-_]+\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'confirm_email', 'v' => '$2'), '/^account\/character\/comment\/[A-Za-z0-9-_%+\']+\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_comment', 'name' => '$3'),
'/^characters\/[A-Za-z0-9-_%+\']+$/' => array('subtopic' => 'characters', 'name' => '$1'), '/^account\/character\/comment\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_comment'),
'/^changelog\/[0-9]+\/?$/' => array('subtopic' => 'changelog', 'page' => '$1'), '/^account\/confirm_email\/[A-Za-z0-9-_]+\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'confirm_email', 'v' => '$2'),
'/^commands\/add\/?$/' => array('subtopic' => 'commands', 'action' => 'add'), '/^characters\/[A-Za-z0-9-_%+\']+$/' => array('subtopic' => 'characters', 'name' => '$1'),
'/^commands\/edit\/?$/' => array('subtopic' => 'commands', 'action' => 'edit'), '/^changelog\/[0-9]+\/?$/' => array('subtopic' => 'changelog', 'page' => '$1'),
'/^faq\/add\/?$/' => array('subtopic' => 'faq', 'action' => 'add'), '/^commands\/add\/?$/' => array('subtopic' => 'commands', 'action' => 'add'),
'/^faq\/edit\/?$/' => array('subtopic' => 'faq', 'action' => 'edit'), '/^commands\/edit\/?$/' => array('subtopic' => 'commands', 'action' => 'edit'),
'/^forum\/add_board\/?$/' => array('subtopic' => 'forum', 'action' => 'add_board'),# '/^faq\/add\/?$/' => array('subtopic' => 'faq', 'action' => 'add'),
'/^forum\/edit_board\/?$/' => array('subtopic' => 'forum', 'action' => 'edit_board'), '/^faq\/edit\/?$/' => array('subtopic' => 'faq', 'action' => 'edit'),
'/^forum\/board\/[0-9]+\/?$/' => array('subtopic' => 'forum', 'action' => 'show_board', 'id' => '$2'), '/^forum\/add_board\/?$/' => array('subtopic' => 'forum', 'action' => 'add_board'),#
'/^forum\/board\/[0-9]+\/[0-9]+\/?$/' => array('subtopic' => 'forum', 'action' => 'show_board', 'id' => '$2', 'page' => '$3'), '/^forum\/edit_board\/?$/' => array('subtopic' => 'forum', 'action' => 'edit_board'),
'/^forum\/thread\/[0-9]+\/?$/' => array('subtopic' => 'forum', 'action' => 'show_thread', 'id' => '$2'), '/^forum\/board\/[0-9]+\/?$/' => array('subtopic' => 'forum', 'action' => 'show_board', 'id' => '$2'),
'/^forum\/thread\/[0-9]+\/[0-9]+\/?$/' => array('subtopic' => 'forum', 'action' => 'show_thread', 'id' => '$2', 'page' => '$3'), '/^forum\/board\/[0-9]+\/[0-9]+\/?$/' => array('subtopic' => 'forum', 'action' => 'show_board', 'id' => '$2', 'page' => '$3'),
'/^gallery\/add\/?$/' => array('subtopic' => 'gallery', 'action' => 'add'), '/^forum\/thread\/[0-9]+\/?$/' => array('subtopic' => 'forum', 'action' => 'show_thread', 'id' => '$2'),
'/^gallery\/edit\/?$/' => array('subtopic' => 'gallery', 'action' => 'edit'), '/^forum\/thread\/[0-9]+\/[0-9]+\/?$/' => array('subtopic' => 'forum', 'action' => 'show_thread', 'id' => '$2', 'page' => '$3'),
'/^gallery\/[0-9]+\/?$/' => array('subtopic' => 'gallery', 'image' => '$1'), '/^gallery\/add\/?$/' => array('subtopic' => 'gallery', 'action' => 'add'),
'/^gifts\/history\/?$/' => array('subtopic' => 'gifts', 'action' => 'show_history'), '/^gallery\/edit\/?$/' => array('subtopic' => 'gallery', 'action' => 'edit'),
'/^guilds\/[A-Za-z0-9-_%+\']+$/' => array('subtopic' => 'guilds', 'action' => 'show', 'guild' => '$1'), '/^gallery\/[0-9]+\/?$/' => array('subtopic' => 'gallery', 'image' => '$1'),
'/^highscores\/[A-Za-z0-9-_]+\/[A-Za-z0-9-_]+\/[0-9]+\/?$/' => array('subtopic' => 'highscores', 'list' => '$1', 'vocation' => '$2', 'page' => '$3'), '/^gifts\/history\/?$/' => array('subtopic' => 'gifts', 'action' => 'show_history'),
'/^highscores\/[A-Za-z0-9-_]+\/[0-9]+\/?$/' => array('subtopic' => 'highscores', 'list' => '$1', 'page' => '$2'), '/^guilds\/[A-Za-z0-9-_%+\']+$/' => array('subtopic' => 'guilds', 'action' => 'show', 'guild' => '$1'),
'/^highscores\/[A-Za-z0-9-_]+\/[A-Za-z0-9-_]+\/?$/' => array('subtopic' => 'highscores', 'list' => '$1', 'vocation' => '$2'), '/^highscores\/[A-Za-z0-9-_]+\/[A-Za-z0-9-_]+\/[0-9]+\/?$/' => array('subtopic' => 'highscores', 'list' => '$1', 'vocation' => '$2', 'page' => '$3'),
'/^highscores\/[A-Za-z0-9-_\']+\/?$/' => array('subtopic' => 'highscores', 'list' => '$1'), '/^highscores\/[A-Za-z0-9-_]+\/[0-9]+\/?$/' => array('subtopic' => 'highscores', 'list' => '$1', 'page' => '$2'),
'/^news\/add\/?$/' => array('subtopic' => 'news', 'action' => 'add'), '/^highscores\/[A-Za-z0-9-_]+\/[A-Za-z0-9-_]+\/?$/' => array('subtopic' => 'highscores', 'list' => '$1', 'vocation' => '$2'),
'/^news\/edit\/?$/' => array('subtopic' => 'news', 'action' => 'edit'), '/^highscores\/[A-Za-z0-9-_\']+\/?$/' => array('subtopic' => 'highscores', 'list' => '$1'),
'/^news\/archive\/?$/' => array('subtopic' => 'newsarchive'), '/^news\/add\/?$/' => array('subtopic' => 'news', 'action' => 'add'),
'/^news\/archive\/[0-9]+\/?$/' => array('subtopic' => 'newsarchive', 'id' => '$2'), '/^news\/edit\/?$/' => array('subtopic' => 'news', 'action' => 'edit'),
'/^polls\/[0-9]+\/?$/' => array('subtopic' => 'polls', 'id' => '$1'), '/^news\/archive\/?$/' => array('subtopic' => 'newsarchive'),
'/^spells\/[A-Za-z0-9-_%]+\/[A-Za-z0-9-_]+\/?$/' => array('subtopic' => 'spells', 'vocation' => '$1', 'order' => '$2'), '/^news\/archive\/[0-9]+\/?$/' => array('subtopic' => 'newsarchive', 'id' => '$2'),
'/^gifts\/history\/?$/' => array('subtopic' => 'gifts', 'action' => 'show_history'), '/^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) { );
if (preg_match($rule, $uri)) {
$tmp = explode('/', $uri); foreach($rules as $rule => $redirect) {
foreach($redirect as $key => $value) { if (preg_match($rule, $uri)) {
$tmp = explode('/', $uri);
if(strpos($value, '$') !== false) { foreach($redirect as $key => $value) {
$value = str_replace('$' . $value[1], $tmp[$value[1]], $value);
} if(strpos($value, '$') !== false) {
$value = str_replace('$' . $value[1], $tmp[$value[1]], $value);
$_REQUEST[$key] = $value; }
$_GET[$key] = $value;
} $_REQUEST[$key] = $value;
$_GET[$key] = $value;
$found = true; }
break;
} $found = true;
} break;
} }
} }
}
// 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)) { // define page visited, so it can be used within events system
$tmp = URI; $page = isset($_REQUEST['subtopic']) ? $_REQUEST['subtopic'] : (isset($_REQUEST['p']) ? $_REQUEST['p'] : '');
if(!empty($tmp)) { if(empty($page) || !preg_match('/^[A-z0-9\_\-]+$/', $page)) {
$page = $tmp; $tmp = URI;
} if(!empty($tmp)) {
else { $page = $tmp;
if(!$found) }
$page = '404'; else {
else if(!$found)
$page = 'news'; $page = '404';
} else
} $page = 'news';
}
$page = strtolower($page); }
define('PAGE', $page);
$page = strtolower($page);
$template_place_holders = array(); define('PAGE', $page);
require_once(SYSTEM . 'init.php'); $template_place_holders = array();
require_once(SYSTEM . 'template.php');
require_once(SYSTEM . 'login.php'); require_once(SYSTEM . 'init.php');
require_once(SYSTEM . 'status.php'); require_once(SYSTEM . 'template.php');
require_once(SYSTEM . 'login.php');
$twig->addGlobal('config', $config); require_once(SYSTEM . 'status.php');
$twig->addGlobal('status', $status);
$twig->addGlobal('config', $config);
// verify myaac tables exists in database $twig->addGlobal('status', $status);
if(!tableExist('myaac_account_actions')) {
die('Seems that the table <strong>myaac_account_actions</strong> of MyAAC doesn\'t exist in the database. This is a fatal error. You can try to reinstall MyAAC by visiting <a href="' . BASE_URL . 'install">this</a> url.'); // database migrations
} $tmp = '';
if(fetchDatabaseConfig('database_version', $tmp)) { // we got version
// database migrations $tmp = (int)$tmp;
$tmp = ''; if($tmp < DATABASE_VERSION) { // import if older
if(fetchDatabaseConfig('database_version', $tmp)) { // we got version for($i = $tmp + 1; $i <= DATABASE_VERSION; $i++) {
$tmp = (int)$tmp; require(SYSTEM . 'migrations/' . $i . '.php');
if($tmp < DATABASE_VERSION) { // import if older updateDatabaseConfig('database_version', $i);
for($i = $tmp + 1; $i <= DATABASE_VERSION; $i++) { }
require(SYSTEM . 'migrations/' . $i . '.php'); }
updateDatabaseConfig('database_version', $i); }
} else { // register first version
} registerDatabaseConfig('database_version', 0);
} for($i = 1; $i <= DATABASE_VERSION; $i++) {
else { // register first version require(SYSTEM . 'migrations/' . $i . '.php');
registerDatabaseConfig('database_version', 0); updateDatabaseConfig('database_version', $i);
for($i = 1; $i <= DATABASE_VERSION; $i++) { }
require(SYSTEM . 'migrations/' . $i . '.php'); }
updateDatabaseConfig('database_version', $i);
} // event system
} require_once(SYSTEM . 'hooks.php');
$hooks = new Hooks();
// event system $hooks->load();
require_once(SYSTEM . 'hooks.php'); $hooks->trigger(HOOK_STARTUP);
$hooks = new Hooks();
$hooks->load(); // anonymous usage statistics
$hooks->trigger(HOOK_STARTUP); // sent only when user agrees
if(isset($config['anonymous_usage_statistics']) && $config['anonymous_usage_statistics']) {
// anonymous usage statistics $report_time = 30 * 24 * 60 * 60; // report one time per 30 days
// sent only when user agrees $should_report = true;
if(isset($config['anonymous_usage_statistics']) && $config['anonymous_usage_statistics']) {
$report_time = 30 * 24 * 60 * 60; // report one time per 30 days $value = '';
$should_report = true; if($cache->enabled() && $cache->fetch('last_usage_report', $value)) {
$should_report = time() > (int)$value + $report_time;
$value = ''; }
if($cache->enabled() && $cache->fetch('last_usage_report', $value)) { else {
$should_report = time() > (int)$value + $report_time; $value = '';
} if(fetchDatabaseConfig('last_usage_report', $value)) {
else { $should_report = time() > (int)$value + $report_time;
$value = ''; if($cache->enabled()) {
if(fetchDatabaseConfig('last_usage_report', $value)) { $cache->set('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;
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();
if($should_report) {
require_once(LIBS . 'usage_statistics.php'); updateDatabaseConfig('last_usage_report', time());
Usage_Statistics::report(); if($cache->enabled()) {
$cache->set('last_usage_report', time());
updateDatabaseConfig('last_usage_report', time()); }
if($cache->enabled()) { }
$cache->set('last_usage_report', time()); }
}
} if($config['views_counter'])
} require_once(SYSTEM . 'counter.php');
if($config['views_counter']) if($config['visitors_counter'])
require_once(SYSTEM . 'counter.php'); {
require_once(SYSTEM . 'libs/visitors.php');
if($config['visitors_counter']) $visitors = new Visitors($config['visitors_counter_ttl']);
{ }
require_once(SYSTEM . 'libs/visitors.php');
$visitors = new Visitors($config['visitors_counter_ttl']); // page content loading
} if(!isset($content[0]))
$content = '';
// page content loading $load_it = true;
if(!isset($content[0]))
$content = ''; // check if site has been closed
$load_it = true; $site_closed = false;
if(fetchDatabaseConfig('site_closed', $site_closed)) {
// check if site has been closed $site_closed = ($site_closed == 1);
$site_closed = false; if($site_closed) {
if(fetchDatabaseConfig('site_closed', $site_closed)) { if(!admin())
$site_closed = ($site_closed == 1); {
if($site_closed) { $title = getDatabaseConfig('site_closed_title');
if(!admin()) $content .= '<p class="note">' . getDatabaseConfig('site_closed_message') . '</p><br/>';
{ $load_it = false;
$title = getDatabaseConfig('site_closed_title'); }
$content .= '<p class="note">' . getDatabaseConfig('site_closed_message') . '</p><br/>';
$load_it = false; if(!$logged)
} {
ob_start();
if(!$logged) require(SYSTEM . 'pages/accountmanagement.php');
{ $content .= ob_get_contents();
ob_start(); ob_end_clean();
require(SYSTEM . 'pages/accountmanagement.php'); $load_it = false;
$content .= ob_get_contents(); }
ob_end_clean(); }
$load_it = false; }
} define('SITE_CLOSED', $site_closed);
}
} // backward support for gesior
define('SITE_CLOSED', $site_closed); if($config['backward_support']) {
define('INITIALIZED', true);
// backward support for gesior $SQL = $db;
if($config['backward_support']) { $layout_header = template_header();
define('INITIALIZED', true); $layout_name = $template_path;
$SQL = $db; $news_content = '';
$layout_header = template_header(); $tickers_content = '';
$layout_name = $template_path; $subtopic = PAGE;
$news_content = ''; $main_content = '';
$tickers_content = '';
$subtopic = PAGE; $config['access_admin_panel'] = 2;
$main_content = ''; $group_id_of_acc_logged = 0;
if($logged && $account_logged)
$config['access_admin_panel'] = 2; $group_id_of_acc_logged = $account_logged->getGroupId();
$group_id_of_acc_logged = 0;
if($logged && $account_logged) $config['site'] = &$config;
$group_id_of_acc_logged = $account_logged->getGroupId(); $config['server'] = &$config['lua'];
$config['site']['shop_system'] = $config['gifts_system'];
$config['site'] = &$config;
$config['server'] = &$config['lua']; if(!isset($config['vdarkborder']))
$config['site']['shop_system'] = $config['gifts_system']; $config['vdarkborder'] = '#505050';
if(!isset($config['darkborder']))
if(!isset($config['vdarkborder'])) $config['darkborder'] = '#D4C0A1';
$config['vdarkborder'] = '#505050'; if(!isset($config['lightborder']))
if(!isset($config['darkborder'])) $config['lightborder'] = '#F1E0C6';
$config['darkborder'] = '#D4C0A1';
if(!isset($config['lightborder'])) $config['site']['download_page'] = true;
$config['lightborder'] = '#F1E0C6'; $config['site']['serverinfo_page'] = true;
$config['site']['screenshot_page'] = true;
$config['site']['download_page'] = true;
$config['site']['serverinfo_page'] = true; if($config['forum'] != '')
$config['site']['screenshot_page'] = true; $config['forum_link'] = (strtolower($config['forum']) == 'site' ? getLink('forum') : $config['forum']);
if($config['forum'] != '') foreach($status as $key => $value)
$config['forum_link'] = (strtolower($config['forum']) == 'site' ? getLink('forum') : $config['forum']); $config['status']['serverStatus_' . $key] = $value;
}
foreach($status as $key => $value)
$config['status']['serverStatus_' . $key] = $value; if($load_it)
} {
if(SITE_CLOSED && admin())
if($load_it) $content .= '<p class="note">Site is under maintenance (closed mode). Only privileged users can see it.</p>';
{
if(SITE_CLOSED && admin()) if($config['backward_support'])
$content .= '<p class="note">Site is under maintenance (closed mode). Only privileged users can see it.</p>'; require(SYSTEM . 'compat_pages.php');
if($config['backward_support']) $ignore = false;
require(SYSTEM . 'compat_pages.php');
$logged_access = 1;
$ignore = false; if($logged && $account_logged && $account_logged->isLoaded()) {
$logged_access = $account_logged->getAccess();
$logged_access = 1; }
if($logged && $account_logged && $account_logged->isLoaded()) {
$logged_access = $account_logged->getAccess(); $query =
} $db->query(
'SELECT `id`, `title`, `body`, `php`, `hidden`' .
$query = ' FROM `' . TABLE_PREFIX . 'pages`' .
$db->query( ' WHERE `name` LIKE ' . $db->quote($page) . ' AND `hidden` != 1 AND `access` <= ' . $db->quote($logged_access));
'SELECT `id`, `title`, `body`, `php`, `hidden`' . if($query->rowCount() > 0) // found page
' FROM `' . TABLE_PREFIX . 'pages`' . {
' WHERE `name` LIKE ' . $db->quote($page) . ' AND `hidden` != 1 AND `access` <= ' . $db->quote($logged_access)); $ignore = true;
if($query->rowCount() > 0) // found page $query = $query->fetch();
{ $title = $query['title'];
$ignore = true;
$query = $query->fetch(); if($query['php'] == '1') // execute it as php code
$title = $query['title']; {
$tmp = substr($query['body'], 0, 10);
if($query['php'] == '1') // execute it as php code if(($pos = strpos($tmp, '<?php')) !== false) {
{ $tmp = preg_replace('/<\?php/', '', $query['body'], 1);
$tmp = substr($query['body'], 0, 10); }
if(($pos = strpos($tmp, '<?php')) !== false) { else if(($pos = strpos($tmp, '<?')) !== false) {
$tmp = preg_replace('/<\?php/', '', $query['body'], 1); $tmp = preg_replace('/<\?/', '', $query['body'], 1);
} }
else if(($pos = strpos($tmp, '<?')) !== false) { else
$tmp = preg_replace('/<\?/', '', $query['body'], 1); $tmp = $query['body'];
}
else $php_errors = array();
$tmp = $query['body']; function error_handler($errno, $errstr) {
global $php_errors;
$php_errors = array(); $php_errors[] = array('errno' => $errno, 'errstr' => $errstr);
function error_handler($errno, $errstr) { }
global $php_errors; set_error_handler('error_handler');
$php_errors[] = array('errno' => $errno, 'errstr' => $errstr);
} ob_start();
set_error_handler('error_handler'); eval($tmp);
$content .= ob_get_contents();
ob_start(); ob_end_clean();
eval($tmp);
$content .= ob_get_contents(); restore_error_handler();
ob_end_clean(); if(isset($php_errors[0]) && superAdmin()) {
var_dump($php_errors);
restore_error_handler(); }
if(isset($php_errors[0]) && superAdmin()) { }
var_dump($php_errors); else
} $content .= $query['body']; // plain html
}
else if(hasFlag(FLAG_CONTENT_PAGES) || superAdmin()) {
$content .= $query['body']; // plain html $content = $twig->render('admin.pages.links.html.twig', array(
'page' => array('id' => $query['id'], 'hidden' => $query['hidden'])
if(hasFlag(FLAG_CONTENT_PAGES) || superAdmin()) { )) . $content;
$content = $twig->render('admin.pages.links.html.twig', array( }
'page' => array('id' => $query['id'], 'hidden' => $query['hidden']) }
)) . $content; else
} {
} $file = SYSTEM . 'pages/' . $page . '.php';
else if(!@file_exists($file))
{ {
$file = SYSTEM . 'pages/' . $page . '.php'; $page = '404';
if(!@file_exists($file)) $file = SYSTEM . 'pages/404.php';
{ }
$page = '404'; }
$file = SYSTEM . 'pages/404.php';
} ob_start();
} if($hooks->trigger(HOOK_BEFORE_PAGE)) {
if(!$ignore)
ob_start(); require($file);
if($hooks->trigger(HOOK_BEFORE_PAGE)) { }
if(!$ignore)
require($file); if($config['backward_support'] && isset($main_content[0]))
} $content .= $main_content;
if($config['backward_support'] && isset($main_content[0])) $content .= ob_get_contents();
$content .= $main_content; ob_end_clean();
$hooks->trigger(HOOK_AFTER_PAGE);
$content .= ob_get_contents(); }
ob_end_clean();
$hooks->trigger(HOOK_AFTER_PAGE); if($config['backward_support']) {
} $main_content = $content;
if(!isset($title))
if($config['backward_support']) { $title = ucfirst($page);
$main_content = $content;
if(!isset($title)) $topic = $title;
$title = ucfirst($page); }
$topic = $title; $title_full = (isset($title) ? $title . $config['title_separator'] : '') . $config['lua']['serverName'];
} if(file_exists($template_path . '/index.php'))
require($template_path . '/index.php');
$title_full = (isset($title) ? $title . $config['title_separator'] : '') . $config['lua']['serverName']; else if(file_exists($template_path . '/template.php')) // deprecated
if(file_exists($template_path . '/index.php')) require($template_path . '/template.php');
require($template_path . '/index.php'); else if($config['backward_support'] && file_exists($template_path . '/layout.php'))
else if(file_exists($template_path . '/template.php')) // deprecated {
require($template_path . '/template.php'); require($template_path . '/layout.php');
else if($config['backward_support'] && file_exists($template_path . '/layout.php')) }
{ else
require($template_path . '/layout.php'); {
} // TODO: save more info to log file
else die('ERROR: Cannot load template.');
{ }
// TODO: save more info to log file
die('ERROR: Cannot load template.'); echo '<!-- MyAAC ' . MYAAC_VERSION . ' :: http://www.my-aac.org/ -->' . "\n";
} if(superAdmin()) {
echo '<!-- Generated in: ' . round(microtime(true) - START_TIME, 4) . 'ms -->';
echo base64_decode('PCEtLSBQb3dlcmVkIGJ5IE15QUFDIDo6IGh0dHBzOi8vd3d3Lm15LWFhYy5vcmcvIC0tPg==') . PHP_EOL; echo PHP_EOL . '<!-- Queries done: ' . $db->queries() . ' -->';
if(($config['debug_level'] & 1) == 1) if(function_exists('memory_get_peak_usage')) {
echo '<!-- Generated in :: ' . round(microtime(true) - START_TIME, 4) . ' -->'; 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['database_log']) {
echo PHP_EOL . '<!-- Database Queries Done by MyAAC:' . PHP_EOL . $db->getLog() . '-->';
if(($config['debug_level'] & 4) == 4 && function_exists('memory_get_peak_usage')) }
echo "\n" . '<!-- Peak memory usage: ' . convert_bytes(memory_get_peak_usage(true)) . ' -->'; }
$hooks->trigger(HOOK_FINISH); $hooks->trigger(HOOK_FINISH);
?> ?>

View File

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

View File

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

View File

@@ -1,7 +1,7 @@
CREATE TABLE `myaac_account_actions` CREATE TABLE `myaac_account_actions`
( (
`account_id` INT(11) NOT NULL, `account_id` INT(11) NOT NULL,
`ip` INT(10) UNSIGNED NOT NULL DEFAULT 0, `ip` INT(11) NOT NULL DEFAULT 0,
`ipv6` BINARY(16) NOT NULL DEFAULT 0, `ipv6` BINARY(16) NOT NULL DEFAULT 0,
`date` INT(11) NOT NULL DEFAULT 0, `date` INT(11) NOT NULL DEFAULT 0,
`action` VARCHAR(255) NOT NULL DEFAULT '', `action` VARCHAR(255) NOT NULL DEFAULT '',

View File

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

3
install/ip.txt Normal file
View File

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

View File

@@ -22,11 +22,11 @@ function version_check($name, $ok, $info = '', $warning = false)
$failed = false; $failed = false;
// start validating // start validating
version_check($locale['step_requirements_php_version'], (PHP_VERSION_ID >= 50303), PHP_VERSION); version_check($locale['step_requirements_php_version'], (PHP_VERSION_ID >= 50300), PHP_VERSION);
foreach(array('config.local.php', 'images/guilds', 'images/houses', 'images/gallery') as $value) foreach(array('images/guilds', 'images/houses', 'images/gallery') as $value)
{ {
$is_writable = is_writable(BASE . $value); $perms = (int) substr(decoct(fileperms(BASE . $value)), 2);
version_check($locale['step_requirements_write_perms'] . ': ' . $value, $is_writable); version_check($locale['step_requirements_write_perms'] . ': ' . $value, $perms >= 660);
} }
$ini_register_globals = ini_get_bool('register_globals'); $ini_register_globals = ini_get_bool('register_globals');

View File

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

View File

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

View File

@@ -15,7 +15,7 @@ else {
$password = $_SESSION['var_password']; $password = $_SESSION['var_password'];
$config_salt_enabled = fieldExist('salt', 'accounts'); $config_salt_enabled = $db->hasColumn('accounts', 'salt');
if($config_salt_enabled) if($config_salt_enabled)
{ {
$salt = generateRandomString(10, false, true, true); $salt = generateRandomString(10, false, true, true);
@@ -77,9 +77,9 @@ else {
$account_used->setCustomField('web_flags', FLAG_ADMIN + FLAG_SUPER_ADMIN); $account_used->setCustomField('web_flags', FLAG_ADMIN + FLAG_SUPER_ADMIN);
$account_used->setCustomField('country', 'us'); $account_used->setCustomField('country', 'us');
if(fieldExist('group_id', 'accounts')) if($db->hasColumn('accounts', 'group_id'))
$account_used->setCustomField('group_id', $groups->getHighestId()); $account_used->setCustomField('group_id', $groups->getHighestId());
if(fieldExist('type', 'accounts')) if($db->hasColumn('accounts', 'type'))
$account_used->setCustomField('type', 5); $account_used->setCustomField('type', 5);
if(!$player_db->isLoaded()) if(!$player_db->isLoaded())
@@ -114,87 +114,11 @@ else {
success($locale['step_database_created_news']); 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', 1, " . getSession('account') . ", 1, 0, 150, 150, 4200, 118, 114, 38, 57, 130, 0, 0, 0, 0, 100, 1, 1000, 1000, 7, '', 400, 1, 1255179613, 2453925456, 1, 1255179614, 0, 0, UNIX_TIMESTAMP(), 1, '');"))
$success = false;
}
$query = $db->query('SELECT `id` FROM `players` WHERE `name` = ' . $db->quote('Sorcerer Sample'));
if($query->rowCount() == 0) {
if(!query($insert_into_players . "(null, 'Sorcerer Sample', 1, " . getSession('account') . ", 8, 1, 185, 185, 4200, 118, 114, 38, 57, 130, 0, 35, 35, 0, 100, 1, 1000, 1000, 7, '', 470, 1, 1255179571, 2453925456, 1, 1255179612, 0, 0, UNIX_TIMESTAMP(), 1, '');"))
$success = false;
}
$query = $db->query('SELECT `id` FROM `players` WHERE `name` = ' . $db->quote('Druid Sample'));
if($query->rowCount() == 0) {
if(!query($insert_into_players . "(null, 'Druid Sample', 1, " . getSession('account') . ", 8, 2, 185, 185, 4200, 118, 114, 38, 57, 130, 0, 35, 35, 0, 100, 1, 1000, 1000, 7, '', 470, 1, 1255179655, 2453925456, 1, 1255179658, 0, 0, UNIX_TIMESTAMP(), 1, '');"))
$success = false;
}
$query = $db->query('SELECT `id` FROM `players` WHERE `name` = ' . $db->quote('Paladin Sample'));
if($query->rowCount() == 0) {
if(!query($insert_into_players . "(null, 'Paladin Sample', 1, " . getSession('account') . ", 8, 3, 185, 185, 4200, 118, 114, 38, 57, 129, 0, 35, 35, 0, 100, 1, 1000, 1000, 7, '', 470, 1, 1255179854, 2453925456, 1, 1255179858, 0, 0, UNIX_TIMESTAMP(), 1, '');"))
$success = false;
}
$query = $db->query('SELECT `id` FROM `players` WHERE `name` = ' . $db->quote('Knight Sample'));
if($query->rowCount() == 0) {
if(!query($insert_into_players . "(null, 'Knight Sample', 1, " . getSession('account') . ", 8, 4, 185, 185, 4200, 118, 114, 38, 57, 131, 0, 35, 35, 0, 100, 1, 1000, 1000, 7, '', 470, 1, 1255179620, 2453925456, 1, 1255179654, 0, 0, UNIX_TIMESTAMP(), 1, '');"))
$success = false;
}
if($success) {
success($locale['step_database_imported_players']);
}
require(LIBS . 'creatures.php'); echo $twig->render('install.installer.html.twig', array(
if(Creatures::loadFromXML()) { 'url' => 'tools/7-finish.php',
success($locale['step_database_loaded_monsters']); 'message' => $locale['importing_spinner']
));
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
$database_migration_20 = true;
require_once(SYSTEM . 'migrations/20.php');
$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>');
}
// add z_polls tables
require_once(SYSTEM . 'migrations/22.php');
$locale['step_finish_desc'] = str_replace('$ADMIN_PANEL$', generateLink(ADMIN_URL, $locale['step_finish_admin_panel'], true), $locale['step_finish_desc']);
$locale['step_finish_desc'] = str_replace('$HOMEPAGE$', generateLink(BASE_URL, $locale['step_finish_homepage'], true), $locale['step_finish_desc']);
$locale['step_finish_desc'] = str_replace('$LINK$', generateLink('http://my-aac.org', 'http://my-aac.org', true), $locale['step_finish_desc']);
success($locale['step_finish_desc']);
if(!isset($_SESSION['installed'])) { if(!isset($_SESSION['installed'])) {
file_get_contents('http://my-aac.org/report_install.php?v=' . MYAAC_VERSION . '&b=' . urlencode(BASE_URL)); file_get_contents('http://my-aac.org/report_install.php?v=' . MYAAC_VERSION . '&b=' . urlencode(BASE_URL));
@@ -206,6 +130,9 @@ else {
unset($_SESSION[$key]); unset($_SESSION[$key]);
} }
unset($_SESSION['saved']); unset($_SESSION['saved']);
if(file_exists(CACHE . 'install.txt')) {
unlink(CACHE . 'install.txt');
}
} }
} }
?> ?>

View File

@@ -1,15 +1,16 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" dir="<?php echo $locale['direction']; ?>" lang="<?php echo $locale['lang']; ?>" xml:lang="<?php echo $locale['lang']; ?>"> <html xmlns="http://www.w3.org/1999/xhtml" dir="<?php echo $locale['direction']; ?>" lang="<?php echo $locale['lang']; ?>" xml:lang="<?php echo $locale['lang']; ?>">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=<?php echo $locale['encoding']; ?>" /> <meta http-equiv="Content-Type" content="text/html; charset=<?php echo $locale['encoding']; ?>" />
<title>MyAAC - <?php echo $locale['installation']; ?></title> <title>MyAAC - <?php echo $locale['installation']; ?></title>
<link rel="stylesheet" type="text/css" href="template/style.css" /> <link rel="stylesheet" type="text/css" href="template/style.css" />
<script type="text/javascript" src="<?php echo BASE_URL; ?>tools/jquery.js"></script>
</head> </head>
<body> <body>
<div id="wrapper"> <div id="wrapper">
<!--div class="buffer"--> <!--div class="buffer"-->
<div id="header"> <div id="header">
<h1>MyAAC <?php echo $locale['installation']; ?></h1> <h1>MyAAC v<?php echo MYAAC_VERSION . ' ' . $locale['installation']; ?></h1>
</div> </div>
<div id="body"> <div id="body">

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,2 +0,0 @@
User-agent: *
Disallow:

View File

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

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

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

View File

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

View File

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

View File

@@ -69,7 +69,7 @@ function getPlayerLink($name, $generate = true)
if(is_numeric($name)) if(is_numeric($name))
{ {
$player = $ots->createObject('Player'); $player = new OTS_Player();
$player->load(intval($name)); $player->load(intval($name));
if($player->isLoaded()) if($player->isLoaded())
$name = $player->getName(); $name = $player->getName();
@@ -308,22 +308,6 @@ function encrypt($str)
return $str; return $str;
} }
function tableExist($table)
{
global $db, $config;
$query = $db->query("SELECT `TABLE_NAME` FROM `information_schema`.`tables` WHERE `TABLE_SCHEMA` = " . $db->quote($config['database_name']) . " AND `TABLE_NAME` = " . $db->quote($table) . ";");
return $query->rowCount() > 0;
}
function fieldExist($field, $table)
{
global $db;
if(count($db->query("SHOW COLUMNS FROM `" . $table . "` LIKE '" . $field . "'")->fetchAll()))
return true;
return false;
}
//delete player with name //delete player with name
function delete_player($name) function delete_player($name)
{ {
@@ -382,9 +366,9 @@ function delete_guild($id)
global $db, $ots; global $db, $ots;
foreach($rank_list as $rank_in_guild) { foreach($rank_list as $rank_in_guild) {
if(tableExist('guild_members')) if($db->hasTable('guild_members'))
$players_with_rank = $db->query('SELECT `players`.`id` as `id`, `guild_members`.`rank_id` as `rank_id` FROM `players`, `guild_members` WHERE `guild_members`.`rank_id` = ' . $rank_in_guild->getId() . ' AND `players`.`id` = `guild_members`.`player_id` ORDER BY `name`;'); $players_with_rank = $db->query('SELECT `players`.`id` as `id`, `guild_members`.`rank_id` as `rank_id` FROM `players`, `guild_members` WHERE `guild_members`.`rank_id` = ' . $rank_in_guild->getId() . ' AND `players`.`id` = `guild_members`.`player_id` ORDER BY `name`;');
else if(tableExist('guild_membership')) else if($db->hasTable('guild_membership'))
$players_with_rank = $db->query('SELECT `players`.`id` as `id`, `guild_membership`.`rank_id` as `rank_id` FROM `players`, `guild_membership` WHERE `guild_membership`.`rank_id` = ' . $rank_in_guild->getId() . ' AND `players`.`id` = `guild_membership`.`player_id` ORDER BY `name`;'); $players_with_rank = $db->query('SELECT `players`.`id` as `id`, `guild_membership`.`rank_id` as `rank_id` FROM `players`, `guild_membership` WHERE `guild_membership`.`rank_id` = ' . $rank_in_guild->getId() . ' AND `players`.`id` = `guild_membership`.`player_id` ORDER BY `name`;');
else else
$players_with_rank = $db->query('SELECT `id`, `rank_id` FROM `players` WHERE `rank_id` = ' . $rank_in_guild->getId() . ' AND `deleted` = 0;'); $players_with_rank = $db->query('SELECT `id`, `rank_id` FROM `players` WHERE `rank_id` = ' . $rank_in_guild->getId() . ' AND `deleted` = 0;');
@@ -392,7 +376,7 @@ function delete_guild($id)
$players_with_rank_number = $players_with_rank->rowCount(); $players_with_rank_number = $players_with_rank->rowCount();
if($players_with_rank_number > 0) { if($players_with_rank_number > 0) {
foreach($players_with_rank as $result) { foreach($players_with_rank as $result) {
$player = $ots->createObject('Player'); $player = new OTS_Player();
$player->load($result['id']); $player->load($result['id']);
if(!$player->isLoaded()) if(!$player->isLoaded())
continue; continue;
@@ -473,7 +457,7 @@ function template_header($is_admin = false)
$ret .= ' $ret .= '
<meta name="description" content="' . $config['meta_description'] . '" /> <meta name="description" content="' . $config['meta_description'] . '" />
<meta name="keywords" content="' . $config['meta_keywords'] . ', myaac, wodzaac" /> <meta name="keywords" content="' . $config['meta_keywords'] . ', myaac, wodzaac" />
<meta name="generator" content="MyAAC" /> <meta name="generator" content="MyAAC ' . MYAAC_VERSION . '" />
<link rel="stylesheet" type="text/css" href="' . BASE_URL . 'tools/messages.css" /> <link rel="stylesheet" type="text/css" href="' . BASE_URL . 'tools/messages.css" />
<script type="text/javascript" src="' . BASE_URL . 'tools/jquery.js"></script> <script type="text/javascript" src="' . BASE_URL . 'tools/jquery.js"></script>
<noscript> <noscript>
@@ -569,7 +553,7 @@ function getCreatureName($killer, $showStatus = false, $extendedInfo = false)
if(is_numeric($killer)) if(is_numeric($killer))
{ {
$player = $ots->createObject('Player'); $player = new OTS_Player();
$player->load($killer); $player->load($killer);
if($player->isLoaded()) if($player->isLoaded())
{ {
@@ -810,16 +794,11 @@ function getWorldName($id)
*/ */
function _mail($to, $subject, $body, $altBody = '', $add_html_tags = true) function _mail($to, $subject, $body, $altBody = '', $add_html_tags = true)
{ {
/** @var PHPMailer $mailer */
global $mailer, $config; global $mailer, $config;
if(!$mailer) if(!$mailer)
{ {
require(SYSTEM . 'libs/phpmailer/PHPMailerAutoload.php'); require(SYSTEM . 'libs/phpmailer/PHPMailerAutoload.php');
$mailer = new PHPMailer(); $mailer = new PHPMailer();
$mailer->setLanguage('en', LIBS . 'phpmailer/language/');
}
else {
$mailer->clearAllRecipients();
} }
$signature_html = ''; $signature_html = '';
@@ -827,9 +806,9 @@ function _mail($to, $subject, $body, $altBody = '', $add_html_tags = true)
$signature_html = $config['mail_signature']['html']; $signature_html = $config['mail_signature']['html'];
if($add_html_tags && isset($body[0])) if($add_html_tags && isset($body[0]))
$body = '<html><head></head><body>' . $body . '<br/><br/>' . $signature_html . '</body></html>'; $tmp_body = '<html><head></head><body>' . $body . '<br/><br/>' . $signature_html . '</body></html>';
else else
$body .= '<br/><br/>' . $signature_html; $tmp_body .= '<br/><br/>' . $signature_html;
if($config['smtp_enabled']) if($config['smtp_enabled'])
{ {
@@ -839,7 +818,6 @@ function _mail($to, $subject, $body, $altBody = '', $add_html_tags = true)
$mailer->SMTPAuth = $config['smtp_auth']; $mailer->SMTPAuth = $config['smtp_auth'];
$mailer->Username = $config['smtp_user']; $mailer->Username = $config['smtp_user'];
$mailer->Password = $config['smtp_pass']; $mailer->Password = $config['smtp_pass'];
$mailer->SMTPSecure = isset($config['smtp_secure']) ? $config['smtp_secure'] : '';
} }
else else
$mailer->IsMail(); $mailer->IsMail();
@@ -851,7 +829,7 @@ function _mail($to, $subject, $body, $altBody = '', $add_html_tags = true)
$mailer->FromName = $config['lua']['serverName']; $mailer->FromName = $config['lua']['serverName'];
$mailer->Subject = $subject; $mailer->Subject = $subject;
$mailer->AddAddress($to); $mailer->AddAddress($to);
$mailer->Body = $body; $mailer->Body = $tmp_body;
$signature_plain = ''; $signature_plain = '';
if(isset($config['mail_signature']['plain'])) if(isset($config['mail_signature']['plain']))
@@ -859,6 +837,9 @@ function _mail($to, $subject, $body, $altBody = '', $add_html_tags = true)
if(isset($altBody[0])) if(isset($altBody[0]))
$mailer->AltBody = $altBody . $signature_plain; $mailer->AltBody = $altBody . $signature_plain;
else { // automatically generate plain html
$mailer->AltBody = strip_tags(preg_replace('/<a(.*)href="([^"]*)"(.*)>/','$2', $body)) . "\n" . $signature_plain;
}
return $mailer->Send(); return $mailer->Send();
} }
@@ -921,10 +902,6 @@ function load_config_lua($filename)
$result[$key] = (string) substr(substr($value, 1), 0, -1); $result[$key] = (string) substr(substr($value, 1), 0, -1);
elseif(in_array($value, array('true', 'false'))) elseif(in_array($value, array('true', 'false')))
$result[$key] = ($value == 'true') ? true : false; $result[$key] = ($value == 'true') ? true : false;
elseif(substr($value, 0 , 1) == '{' && substr($value, -1 , 1) == '}') {
// arrays are not supported yet
// just ignore the error
}
else else
{ {
foreach($result as $tmp_key => $tmp_value) // load values definied by other keys, like: dailyFragsToBlackSkull = dailyFragsToRedSkull foreach($result as $tmp_key => $tmp_value) // load values definied by other keys, like: dailyFragsToBlackSkull = dailyFragsToRedSkull
@@ -984,10 +961,10 @@ function getTopPlayers($limit = 5) {
if($fetch_from_db) if($fetch_from_db)
{ {
$deleted = 'deleted'; $deleted = 'deleted';
if(fieldExist('deletion', 'players')) if($db->hasColumn('players', 'deletion'))
$deleted = 'deletion'; $deleted = 'deletion';
$is_tfs10 = tableExist('players_online'); $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(); $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) { if($is_tfs10) {

View File

@@ -42,12 +42,12 @@ class Hook
$ret = $tmp($params); $ret = $tmp($params);
}*/ }*/
global $db, $config, $template_path, $ots, $content, $twig; global $db, $config, $template_path, $ots, $content;
if(file_exists(BASE . $this->_file)) { if(file_exists(BASE . $this->_file)) {
$ret = require(BASE . $this->_file); require(BASE . $this->_file);
} }
return $ret === null || $ret == 1 || $ret; return true;
} }
public function name() {return $this->_name;} public function name() {return $this->_name;}
@@ -71,17 +71,11 @@ class Hooks
if(isset(self::$_hooks[$type])) if(isset(self::$_hooks[$type]))
{ {
foreach(self::$_hooks[$type] as $name => $hook) foreach(self::$_hooks[$type] as $name => $hook)
if(!$hook->execute($params)) { $ret = $hook->execute($params);
$ret = false;
}
} }
return $ret; return $ret;
} }
public function exist($type) {
return isset(self::$_hooks[$type]);
}
public function load() public function load()
{ {

View File

@@ -38,7 +38,8 @@ Twig_Autoloader::register();
$twig_loader = new Twig_Loader_Filesystem(SYSTEM . 'templates'); $twig_loader = new Twig_Loader_Filesystem(SYSTEM . 'templates');
$twig = new Twig_Environment($twig_loader, array( $twig = new Twig_Environment($twig_loader, array(
'cache' => CACHE . 'twig/', 'cache' => CACHE . 'twig/',
'auto_reload' => true 'auto_reload' => true,
//'debug' => true
)); ));
$function = new Twig_SimpleFunction('getStyle', function ($i) { $function = new Twig_SimpleFunction('getStyle', function ($i) {
@@ -163,7 +164,7 @@ require_once(SYSTEM . 'libs/pot/OTS.php');
$ots = POT::getInstance(); $ots = POT::getInstance();
require_once(SYSTEM . 'database.php'); require_once(SYSTEM . 'database.php');
define('USE_ACCOUNT_NAME', fieldExist('name', 'accounts')); define('USE_ACCOUNT_NAME', $db->hasColumn('accounts', 'name'));
// load vocation names // load vocation names
$tmp = ''; $tmp = '';
if($cache->enabled() && $cache->fetch('vocations', $tmp)) { if($cache->enabled() && $cache->fetch('vocations', $tmp)) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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