diff options
43 files changed, 2045 insertions, 497 deletions
diff --git a/.gitignore b/.gitignore index c757210654..06b13923f5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@  *~  /phpunit.xml +/phpBB/cache/twig/*  /phpBB/cache/*.html  /phpBB/cache/*.php  /phpBB/cache/*.lock diff --git a/phpBB/adm/style/acp_forums.html b/phpBB/adm/style/acp_forums.html index 38369ee207..7b1466cfbd 100644 --- a/phpBB/adm/style/acp_forums.html +++ b/phpBB/adm/style/acp_forums.html @@ -437,7 +437,7 @@  		</div>  	<!-- ENDIF --> -	<p><strong>{NAVIGATION}<!-- IF S_NO_FORUMS --> [<a href="{U_EDIT}">{L_EDIT}</a> | <a href="{U_DELETE}">{L_DELETE}</a><!-- IF not S_LINK --> | <a href="{U_SYNC}">{L_RESYNC}</a><!-- ENDIF --->]<!-- ENDIF --></strong></p> +	<p><strong>{NAVIGATION}<!-- IF S_NO_FORUMS --> [<a href="{U_EDIT}">{L_EDIT}</a> | <a href="{U_DELETE}">{L_DELETE}</a><!-- IF not S_LINK --> | <a href="{U_SYNC}">{L_RESYNC}</a><!-- ENDIF -->]<!-- ENDIF --></strong></p>  	<!-- IF .forums -->  		<table cellspacing="1"> diff --git a/phpBB/composer.json b/phpBB/composer.json index abc1df57b7..a114d5c0e0 100644 --- a/phpBB/composer.json +++ b/phpBB/composer.json @@ -6,7 +6,8 @@  		"symfony/event-dispatcher": "2.1.*",  		"symfony/http-kernel": "2.1.*",  		"symfony/routing": "2.1.*", -		"symfony/yaml": "2.1.*" +		"symfony/yaml": "2.1.*", +		"twig/twig": "1.13.*"  	},  	"require-dev": {  		"fabpot/goutte": "v0.1.0", diff --git a/phpBB/composer.lock b/phpBB/composer.lock index e3b564fb1a..a20c6303ee 100644 --- a/phpBB/composer.lock +++ b/phpBB/composer.lock @@ -3,21 +3,21 @@          "This file locks the dependencies of your project to a known state",          "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"      ], -    "hash": "3792dc25490f24210ece3b40789c5b98", +    "hash": "e4a4f4848a7201d7e044446001afda29",      "packages": [          {              "name": "symfony/config", -            "version": "v2.1.10", +            "version": "v2.1.11",              "target-dir": "Symfony/Component/Config",              "source": {                  "type": "git",                  "url": "https://github.com/symfony/Config.git", -                "reference": "v2.1.10" +                "reference": "v2.1.11"              },              "dist": {                  "type": "zip", -                "url": "https://api.github.com/repos/symfony/Config/zipball/v2.1.10", -                "reference": "v2.1.10", +                "url": "https://api.github.com/repos/symfony/Config/zipball/v2.1.11", +                "reference": "v2.1.11",                  "shasum": ""              },              "require": { @@ -29,7 +29,6 @@                      "Symfony\\Component\\Config": ""                  }              }, -            "notification-url": "https://packagist.org/downloads/",              "license": [                  "MIT"              ], @@ -45,21 +44,21 @@              ],              "description": "Symfony Config Component",              "homepage": "http://symfony.com", -            "time": "2013-04-22 04:28:40" +            "time": "2013-05-09 15:22:40"          },          {              "name": "symfony/dependency-injection", -            "version": "v2.1.10", +            "version": "v2.1.11",              "target-dir": "Symfony/Component/DependencyInjection",              "source": {                  "type": "git",                  "url": "https://github.com/symfony/DependencyInjection.git", -                "reference": "v2.1.10" +                "reference": "v2.1.11"              },              "dist": {                  "type": "zip", -                "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/v2.1.10", -                "reference": "v2.1.10", +                "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/v2.1.11", +                "reference": "v2.1.11",                  "shasum": ""              },              "require": { @@ -79,7 +78,6 @@                      "Symfony\\Component\\DependencyInjection": ""                  }              }, -            "notification-url": "https://packagist.org/downloads/",              "license": [                  "MIT"              ], @@ -99,17 +97,17 @@          },          {              "name": "symfony/event-dispatcher", -            "version": "v2.1.10", +            "version": "v2.1.11",              "target-dir": "Symfony/Component/EventDispatcher",              "source": {                  "type": "git",                  "url": "https://github.com/symfony/EventDispatcher.git", -                "reference": "v2.1.10" +                "reference": "v2.1.11"              },              "dist": {                  "type": "zip", -                "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/v2.1.10", -                "reference": "v2.1.10", +                "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/v2.1.11", +                "reference": "v2.1.11",                  "shasum": ""              },              "require": { @@ -128,7 +126,6 @@                      "Symfony\\Component\\EventDispatcher": ""                  }              }, -            "notification-url": "https://packagist.org/downloads/",              "license": [                  "MIT"              ], @@ -148,17 +145,17 @@          },          {              "name": "symfony/http-foundation", -            "version": "v2.1.10", +            "version": "v2.1.11",              "target-dir": "Symfony/Component/HttpFoundation",              "source": {                  "type": "git",                  "url": "https://github.com/symfony/HttpFoundation.git", -                "reference": "v2.1.10" +                "reference": "v2.1.11"              },              "dist": {                  "type": "zip", -                "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/v2.1.10", -                "reference": "v2.1.10", +                "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/v2.1.11", +                "reference": "v2.1.11",                  "shasum": ""              },              "require": { @@ -171,7 +168,6 @@                      "SessionHandlerInterface": "Symfony/Component/HttpFoundation/Resources/stubs"                  }              }, -            "notification-url": "https://packagist.org/downloads/",              "license": [                  "MIT"              ], @@ -187,21 +183,21 @@              ],              "description": "Symfony HttpFoundation Component",              "homepage": "http://symfony.com", -            "time": "2013-04-30 17:01:33" +            "time": "2013-05-26 18:42:07"          },          {              "name": "symfony/http-kernel", -            "version": "v2.1.10", +            "version": "v2.1.11",              "target-dir": "Symfony/Component/HttpKernel",              "source": {                  "type": "git",                  "url": "https://github.com/symfony/HttpKernel.git", -                "reference": "v2.1.10" +                "reference": "v2.1.11"              },              "dist": {                  "type": "zip", -                "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/v2.1.10", -                "reference": "v2.1.10", +                "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/v2.1.11", +                "reference": "v2.1.11",                  "shasum": ""              },              "require": { @@ -233,7 +229,6 @@                      "Symfony\\Component\\HttpKernel": ""                  }              }, -            "notification-url": "https://packagist.org/downloads/",              "license": [                  "MIT"              ], @@ -249,21 +244,21 @@              ],              "description": "Symfony HttpKernel Component",              "homepage": "http://symfony.com", -            "time": "2013-05-06 11:01:51" +            "time": "2013-06-02 12:29:05"          },          {              "name": "symfony/routing", -            "version": "v2.1.9", +            "version": "v2.1.11",              "target-dir": "Symfony/Component/Routing",              "source": {                  "type": "git",                  "url": "https://github.com/symfony/Routing.git", -                "reference": "v2.1.9" +                "reference": "v2.1.11"              },              "dist": {                  "type": "zip", -                "url": "https://api.github.com/repos/symfony/Routing/zipball/v2.1.9", -                "reference": "v2.1.9", +                "url": "https://api.github.com/repos/symfony/Routing/zipball/v2.1.11", +                "reference": "v2.1.11",                  "shasum": ""              },              "require": { @@ -286,7 +281,6 @@                      "Symfony\\Component\\Routing": ""                  }              }, -            "notification-url": "https://packagist.org/downloads/",              "license": [                  "MIT"              ], @@ -302,21 +296,21 @@              ],              "description": "Symfony Routing Component",              "homepage": "http://symfony.com", -            "time": "2013-03-23 07:47:35" +            "time": "2013-05-06 10:48:41"          },          {              "name": "symfony/yaml", -            "version": "v2.1.9", +            "version": "v2.1.11",              "target-dir": "Symfony/Component/Yaml",              "source": {                  "type": "git",                  "url": "https://github.com/symfony/Yaml.git", -                "reference": "v2.1.9" +                "reference": "v2.1.11"              },              "dist": {                  "type": "zip", -                "url": "https://api.github.com/repos/symfony/Yaml/zipball/v2.1.9", -                "reference": "v2.1.9", +                "url": "https://api.github.com/repos/symfony/Yaml/zipball/v2.1.11", +                "reference": "v2.1.11",                  "shasum": ""              },              "require": { @@ -328,7 +322,6 @@                      "Symfony\\Component\\Yaml": ""                  }              }, -            "notification-url": "https://packagist.org/downloads/",              "license": [                  "MIT"              ], @@ -344,7 +337,55 @@              ],              "description": "Symfony Yaml Component",              "homepage": "http://symfony.com", -            "time": "2013-03-23 01:54:33" +            "time": "2013-05-10 00:09:46" +        }, +        { +            "name": "twig/twig", +            "version": "v1.13.1", +            "source": { +                "type": "git", +                "url": "https://github.com/fabpot/Twig.git", +                "reference": "v1.13.1" +            }, +            "dist": { +                "type": "zip", +                "url": "https://api.github.com/repos/fabpot/Twig/zipball/v1.13.1", +                "reference": "v1.13.1", +                "shasum": "" +            }, +            "require": { +                "php": ">=5.2.4" +            }, +            "type": "library", +            "extra": { +                "branch-alias": { +                    "dev-master": "1.13-dev" +                } +            }, +            "autoload": { +                "psr-0": { +                    "Twig_": "lib/" +                } +            }, +            "license": [ +                "BSD-3" +            ], +            "authors": [ +                { +                    "name": "Fabien Potencier", +                    "email": "fabien@symfony.com" +                }, +                { +                    "name": "Armin Ronacher", +                    "email": "armin.ronacher@active-4.com" +                } +            ], +            "description": "Twig, the flexible, fast, and secure template language for PHP", +            "homepage": "http://twig.sensiolabs.org", +            "keywords": [ +                "templating" +            ], +            "time": "2013-06-06 06:06:01"          }      ],      "packages-dev": [ @@ -552,16 +593,16 @@          },          {              "name": "phpunit/php-code-coverage", -            "version": "1.2.9", +            "version": "1.2.11",              "source": {                  "type": "git",                  "url": "https://github.com/sebastianbergmann/php-code-coverage.git", -                "reference": "1.2.9" +                "reference": "1.2.11"              },              "dist": {                  "type": "zip", -                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/1.2.9", -                "reference": "1.2.9", +                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/1.2.11", +                "reference": "1.2.11",                  "shasum": ""              },              "require": { @@ -570,6 +611,9 @@                  "phpunit/php-text-template": ">=1.1.1@stable",                  "phpunit/php-token-stream": ">=1.1.3@stable"              }, +            "require-dev": { +                "phpunit/phpunit": "3.7.*" +            },              "suggest": {                  "ext-dom": "*",                  "ext-xdebug": ">=2.0.5" @@ -601,7 +645,7 @@                  "testing",                  "xunit"              ], -            "time": "2013-02-26 18:55:56" +            "time": "2013-05-23 18:23:24"          },          {              "name": "phpunit/php-file-iterator", @@ -783,16 +827,16 @@          },          {              "name": "phpunit/phpunit", -            "version": "3.7.19", +            "version": "3.7.21",              "source": {                  "type": "git",                  "url": "https://github.com/sebastianbergmann/phpunit.git", -                "reference": "3.7.19" +                "reference": "3.7.21"              },              "dist": {                  "type": "zip", -                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3.7.19", -                "reference": "3.7.19", +                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3.7.21", +                "reference": "3.7.21",                  "shasum": ""              },              "require": { @@ -806,7 +850,7 @@                  "phpunit/php-text-template": ">=1.1.1",                  "phpunit/php-timer": ">=1.0.2,<1.1.0",                  "phpunit/phpunit-mock-objects": ">=1.2.0,<1.3.0", -                "symfony/yaml": ">=2.0.0,<2.3.0" +                "symfony/yaml": ">=2.0,<3.0"              },              "require-dev": {                  "pear-pear/pear": "1.9.4" @@ -853,7 +897,7 @@                  "testing",                  "xunit"              ], -            "time": "2013-03-25 11:45:06" +            "time": "2013-05-23 18:54:29"          },          {              "name": "phpunit/phpunit-mock-objects", @@ -906,17 +950,17 @@          },          {              "name": "symfony/browser-kit", -            "version": "v2.1.10", +            "version": "v2.1.11",              "target-dir": "Symfony/Component/BrowserKit",              "source": {                  "type": "git",                  "url": "https://github.com/symfony/BrowserKit.git", -                "reference": "v2.1.10" +                "reference": "v2.1.11"              },              "dist": {                  "type": "zip", -                "url": "https://api.github.com/repos/symfony/BrowserKit/zipball/v2.1.10", -                "reference": "v2.1.10", +                "url": "https://api.github.com/repos/symfony/BrowserKit/zipball/v2.1.11", +                "reference": "v2.1.11",                  "shasum": ""              },              "require": { @@ -956,17 +1000,17 @@          },          {              "name": "symfony/css-selector", -            "version": "v2.1.10", +            "version": "v2.1.11",              "target-dir": "Symfony/Component/CssSelector",              "source": {                  "type": "git",                  "url": "https://github.com/symfony/CssSelector.git", -                "reference": "v2.1.10" +                "reference": "v2.1.11"              },              "dist": {                  "type": "zip", -                "url": "https://api.github.com/repos/symfony/CssSelector/zipball/v2.1.10", -                "reference": "v2.1.10", +                "url": "https://api.github.com/repos/symfony/CssSelector/zipball/v2.1.11", +                "reference": "v2.1.11",                  "shasum": ""              },              "require": { @@ -994,21 +1038,21 @@              ],              "description": "Symfony CssSelector Component",              "homepage": "http://symfony.com", -            "time": "2013-01-09 08:51:07" +            "time": "2013-05-17 00:31:34"          },          {              "name": "symfony/dom-crawler", -            "version": "v2.1.10", +            "version": "v2.1.11",              "target-dir": "Symfony/Component/DomCrawler",              "source": {                  "type": "git",                  "url": "https://github.com/symfony/DomCrawler.git", -                "reference": "v2.1.10" +                "reference": "v2.1.11"              },              "dist": {                  "type": "zip", -                "url": "https://api.github.com/repos/symfony/DomCrawler/zipball/v2.1.10", -                "reference": "v2.1.10", +                "url": "https://api.github.com/repos/symfony/DomCrawler/zipball/v2.1.11", +                "reference": "v2.1.11",                  "shasum": ""              },              "require": { @@ -1042,21 +1086,21 @@              ],              "description": "Symfony DomCrawler Component",              "homepage": "http://symfony.com", -            "time": "2013-03-27 17:13:16" +            "time": "2013-05-16 00:06:15"          },          {              "name": "symfony/finder", -            "version": "v2.1.10", +            "version": "v2.1.11",              "target-dir": "Symfony/Component/Finder",              "source": {                  "type": "git",                  "url": "https://github.com/symfony/Finder.git", -                "reference": "v2.1.10" +                "reference": "v2.1.11"              },              "dist": {                  "type": "zip", -                "url": "https://api.github.com/repos/symfony/Finder/zipball/v2.1.10", -                "reference": "v2.1.10", +                "url": "https://api.github.com/repos/symfony/Finder/zipball/v2.1.11", +                "reference": "v2.1.11",                  "shasum": ""              },              "require": { @@ -1084,21 +1128,21 @@              ],              "description": "Symfony Finder Component",              "homepage": "http://symfony.com", -            "time": "2013-03-06 19:26:55" +            "time": "2013-05-25 15:47:15"          },          {              "name": "symfony/process", -            "version": "v2.1.9", +            "version": "v2.1.11",              "target-dir": "Symfony/Component/Process",              "source": {                  "type": "git",                  "url": "https://github.com/symfony/Process.git", -                "reference": "v2.1.9" +                "reference": "v2.1.11"              },              "dist": {                  "type": "zip", -                "url": "https://api.github.com/repos/symfony/Process/zipball/v2.1.9", -                "reference": "v2.1.9", +                "url": "https://api.github.com/repos/symfony/Process/zipball/v2.1.11", +                "reference": "v2.1.11",                  "shasum": ""              },              "require": { @@ -1126,7 +1170,7 @@              ],              "description": "Symfony Process Component",              "homepage": "http://symfony.com", -            "time": "2013-03-23 07:44:01" +            "time": "2013-05-06 10:21:56"          }      ],      "aliases": [ diff --git a/phpBB/config/services.yml b/phpBB/config/services.yml index bb96953bcf..4713cb21a6 100644 --- a/phpBB/config/services.yml +++ b/phpBB/config/services.yml @@ -254,7 +254,7 @@ services:          class: phpbb_style_path_provider      template: -        class: phpbb_template +        class: phpbb_template_twig          arguments:              - %core.root_path%              - %core.php_ext% diff --git a/phpBB/includes/bbcode.php b/phpBB/includes/bbcode.php index c198abeb54..5a4161bb6c 100644 --- a/phpBB/includes/bbcode.php +++ b/phpBB/includes/bbcode.php @@ -134,7 +134,7 @@ class bbcode  			$style_resource_locator = new phpbb_style_resource_locator();  			$style_path_provider = new phpbb_style_extension_path_provider($phpbb_extension_manager, new phpbb_style_path_provider(), $phpbb_root_path); -			$template = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator, new phpbb_template_context(), $phpbb_extension_manager); +			$template = new phpbb_template_twig($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator, new phpbb_template_context(), $phpbb_extension_manager);  			$style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator, $style_path_provider, $template);  			$style->set_style();  			$template->set_filenames(array('bbcode.html' => 'bbcode.html')); diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php index a646f35fdd..f0736fbb45 100644 --- a/phpBB/includes/functions_messenger.php +++ b/phpBB/includes/functions_messenger.php @@ -55,10 +55,10 @@ class messenger  		$this->vars = $this->msg = $this->replyto = $this->from = '';  		$this->mail_priority = MAIL_NORMAL_PRIORITY;  	} -	 +  	/**  	* Set addresses for to/im as available -	*  +	*  	* @param array $user User row  	*/  	function set_addresses($user) @@ -228,7 +228,7 @@ class messenger  		{  			$style_resource_locator = new phpbb_style_resource_locator();  			$style_path_provider = new phpbb_style_extension_path_provider($phpbb_extension_manager, new phpbb_style_path_provider(), $phpbb_root_path); -			$tpl = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator, new phpbb_template_context(), $phpbb_extension_manager); +			$tpl = new phpbb_template_twig($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator, new phpbb_template_context(), $phpbb_extension_manager);  			$style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator, $style_path_provider, $tpl);  			$this->tpl_msg[$template_lang . $template_file] = $tpl; diff --git a/phpBB/includes/style/style.php b/phpBB/includes/style/style.php index 4703c3a219..5aeeac40e4 100644 --- a/phpBB/includes/style/style.php +++ b/phpBB/includes/style/style.php @@ -135,15 +135,29 @@ class phpbb_style  		$this->provider->set_styles($paths);  		$this->locator->set_paths($this->provider); -		$this->template->set_style_names($names); -  		if ($template_path !== false)  		{  			$this->locator->set_template_path($template_path); + +			$appended_paths = array(); +			foreach ($paths as $path) +			{ +				$appended_paths[] = $path . '/' . $template_path; +			} + +			$this->template->set_style_names($names, $appended_paths);  		}  		else  		{  			$this->locator->set_default_template_path(); + +			$appended_paths = array(); +			foreach ($paths as $path) +			{ +				$appended_paths[] = $path . '/template/'; +			} + +			$this->template->set_style_names($names, $appended_paths);  		}  		$this->template->cachepath = $this->phpbb_root_path . 'cache/tpl_' . str_replace('_', '-', $name) . '_'; diff --git a/phpBB/includes/template/context.php b/phpBB/includes/template/context.php index ec09da1cf3..3abab4f31b 100644 --- a/phpBB/includes/template/context.php +++ b/phpBB/includes/template/context.php @@ -83,6 +83,26 @@ class phpbb_template_context  	}  	/** +	* Get (non-referenced) rootref +	* +	* @return array +	*/ +	public function get_rootref() +	{ +		return $this->rootref; +	} + +	/** +	* Get (non-referenced) tpldata +	* +	* @return array +	*/ +	public function get_tpldata() +	{ +		return $this->tpldata; +	} + +	/**  	* Returns a reference to template data array.  	*  	* This function is public so that template renderer may invoke it. diff --git a/phpBB/includes/template/phpbb.php b/phpBB/includes/template/phpbb.php new file mode 100644 index 0000000000..8f4d163f8c --- /dev/null +++ b/phpBB/includes/template/phpbb.php @@ -0,0 +1,515 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2005 phpBB Group, sections (c) 2001 ispi of Lincoln Inc +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ +	exit; +} + +/** +* @todo +* IMG_ for image substitution? +* {IMG_[key]:[alt]:[type]} +* {IMG_ICON_CONTACT:CONTACT:full} -> $user->img('icon_contact', 'CONTACT', 'full'); +* +* More in-depth... +* yadayada +*/ + +/** +* Base Template class. +* @package phpBB3 +*/ +class phpbb_template_phpbb implements phpbb_template +{ +	/** +	* Template context. +	* Stores template data used during template rendering. +	* @var phpbb_template_context +	*/ +	private $context; + +	/** +	* Path of the cache directory for the template +	* @var string +	*/ +	public $cachepath = ''; + +	/** +	* phpBB root path +	* @var string +	*/ +	private $phpbb_root_path; + +	/** +	* PHP file extension +	* @var string +	*/ +	private $php_ext; + +	/** +	* phpBB config instance +	* @var phpbb_config +	*/ +	private $config; + +	/** +	* Current user +	* @var phpbb_user +	*/ +	private $user; + +	/** +	* Template locator +	* @var phpbb_template_locator +	*/ +	private $locator; + +	/** +	* Extension manager. +	* +	* @var phpbb_extension_manager +	*/ +	private $extension_manager; + +	/** +	* Name of the style that the template being compiled and/or rendered +	* belongs to, and its parents, in inheritance tree order. +	* +	* Used to invoke style-specific template events. +	* +	* @var array +	*/ +	private $style_names; + +	/** +	* Constructor. +	* +	* @param string $phpbb_root_path phpBB root path +	* @param user $user current user +	* @param phpbb_template_locator $locator template locator +	* @param phpbb_template_context $context template context +	* @param phpbb_extension_manager $extension_manager extension manager, if null then template events will not be invoked +	*/ +	public function __construct($phpbb_root_path, $php_ext, $config, $user, phpbb_template_locator $locator, phpbb_template_context $context, phpbb_extension_manager $extension_manager = null) +	{ +		$this->phpbb_root_path = $phpbb_root_path; +		$this->php_ext = $php_ext; +		$this->config = $config; +		$this->user = $user; +		$this->locator = $locator; +		$this->context = $context; +		$this->extension_manager = $extension_manager; +	} + +	/** +	* Sets the template filenames for handles. +	* +	* @param array $filename_array Should be a hash of handle => filename pairs. +	*/ +	public function set_filenames(array $filename_array) +	{ +		$this->locator->set_filenames($filename_array); + +		return true; +	} + +	/** +	* Sets the style names corresponding to style hierarchy being compiled +	* and/or rendered. +	* +	* @param array $style_names List of style names in inheritance tree order +	* @return null +	*/ +	public function set_style_names(array $style_names) +	{ +		$this->style_names = $style_names; +	} + +	/** +	* Clears all variables and blocks assigned to this template. +	*/ +	public function destroy() +	{ +		$this->context->clear(); +	} + +	/** +	* Reset/empty complete block +	* +	* @param string $blockname Name of block to destroy +	*/ +	public function destroy_block_vars($blockname) +	{ +		$this->context->destroy_block_vars($blockname); +	} + +	/** +	* Display a template for provided handle. +	* +	* The template will be loaded and compiled, if necessary, first. +	* +	* This function calls hooks. +	* +	* @param string $handle Handle to display +	* @return bool True on success, false on failure +	*/ +	public function display($handle) +	{ +		$result = $this->call_hook($handle, __FUNCTION__); +		if ($result !== false) +		{ +			return $result[0]; +		} + +		return $this->load_and_render($handle); +	} + +	/** +	* Loads a template for $handle, compiling it if necessary, and +	* renders the template. +	* +	* @param string $handle Template handle to render +	* @return bool True on success, false on failure +	*/ +	private function load_and_render($handle) +	{ +		$renderer = $this->_tpl_load($handle); + +		if ($renderer) +		{ +			$renderer->render($this->context, $this->get_lang()); +			return true; +		} +		else +		{ +			return false; +		} +	} + +	/** +	* Calls hook if any is defined. +	* +	* @param string $handle Template handle being displayed. +	* @param string $method Method name of the caller. +	*/ +	private function call_hook($handle, $method) +	{ +		global $phpbb_hook; + +		if (!empty($phpbb_hook) && $phpbb_hook->call_hook(array(__CLASS__, $method), $handle, $this)) +		{ +			if ($phpbb_hook->hook_return(array(__CLASS__, $method))) +			{ +				$result = $phpbb_hook->hook_return_result(array(__CLASS__, $method)); +				return array($result); +			} +		} + +		return false; +	} + +	/** +	* Obtains language array. +	* This is either lang property of $user property, or if +	* it is not set an empty array. +	* @return array language entries +	*/ +	public function get_lang() +	{ +		if (isset($this->user->lang)) +		{ +			$lang = $this->user->lang; +		} +		else +		{ +			$lang = array(); +		} +		return $lang; +	} + +	/** +	* Display the handle and assign the output to a template variable +	* or return the compiled result. +	* +	* @param string $handle Handle to operate on +	* @param string $template_var Template variable to assign compiled handle to +	* @param bool $return_content If true return compiled handle, otherwise assign to $template_var +	* @return bool|string false on failure, otherwise if $return_content is true return string of the compiled handle, otherwise return true +	*/ +	public function assign_display($handle, $template_var = '', $return_content = true) +	{ +		ob_start(); +		$result = $this->display($handle); +		$contents = ob_get_clean(); +		if ($result === false) +		{ +			return false; +		} + +		if ($return_content) +		{ +			return $contents; +		} + +		$this->assign_var($template_var, $contents); + +		return true; +	} + +	/** +	* Obtains a template renderer for a template identified by specified +	* handle. The template renderer can display the template later. +	* +	* Template source will first be compiled into php code. +	* If template cache is writable the compiled php code will be stored +	* on filesystem and template will not be subsequently recompiled. +	* If template cache is not writable template source will be recompiled +	* every time it is needed. DEBUG define and load_tplcompile +	* configuration setting may be used to force templates to be always +	* recompiled. +	* +	* Returns an object implementing phpbb_template_renderer, or null +	* if template loading or compilation failed. Call render() on the +	* renderer to display the template. This will result in template +	* contents sent to the output stream (unless, of course, output +	* buffering is in effect). +	* +	* @param string $handle Handle of the template to load +	* @return phpbb_template_renderer Template renderer object, or null on failure +	* @uses phpbb_template_compile is used to compile template source +	*/ +	private function _tpl_load($handle) +	{ +		$output_file = $this->_compiled_file_for_handle($handle); + +		$recompile = defined('DEBUG') || +			!file_exists($output_file) || +			@filesize($output_file) === 0; + +		if ($recompile || $this->config['load_tplcompile']) +		{ +			// Set only if a recompile or an mtime check are required. +			$source_file = $this->locator->get_source_file_for_handle($handle); + +			if (!$recompile && @filemtime($output_file) < @filemtime($source_file)) +			{ +				$recompile = true; +			} +		} + +		// Recompile page if the original template is newer, otherwise load the compiled version +		if (!$recompile) +		{ +			return new phpbb_template_renderer_include($output_file, $this); +		} + +		$compile = new phpbb_template_compile($this->config['tpl_allow_php'], $this->style_names, $this->locator, $this->phpbb_root_path, $this->extension_manager, $this->user); + +		if ($compile->compile_file_to_file($source_file, $output_file) !== false) +		{ +			$renderer = new phpbb_template_renderer_include($output_file, $this); +		} +		else if (($code = $compile->compile_file($source_file)) !== false) +		{ +			$renderer = new phpbb_template_renderer_eval($code, $this); +		} +		else +		{ +			$renderer = null; +		} + +		return $renderer; +	} + +	/** +	* Determines compiled file path for handle $handle. +	* +	* @param string $handle Template handle (i.e. "friendly" template name) +	* @return string Compiled file path +	*/ +	private function _compiled_file_for_handle($handle) +	{ +		$source_file = $this->locator->get_filename_for_handle($handle); +		$compiled_file = $this->cachepath . str_replace('/', '.', $source_file) . '.' . $this->php_ext; +		return $compiled_file; +	} + +	/** +	* Assign key variable pairs from an array +	* +	* @param array $vararray A hash of variable name => value pairs +	*/ +	public function assign_vars(array $vararray) +	{ +		foreach ($vararray as $key => $val) +		{ +			$this->assign_var($key, $val); +		} +	} + +	/** +	* Assign a single scalar value to a single key. +	* +	* Value can be a string, an integer or a boolean. +	* +	* @param string $varname Variable name +	* @param string $varval Value to assign to variable +	*/ +	public function assign_var($varname, $varval) +	{ +		$this->context->assign_var($varname, $varval); +	} + +	/** +	* Append text to the string value stored in a key. +	* +	* Text is appended using the string concatenation operator (.). +	* +	* @param string $varname Variable name +	* @param string $varval Value to append to variable +	*/ +	public function append_var($varname, $varval) +	{ +		$this->context->append_var($varname, $varval); +	} + +	// Docstring is copied from phpbb_template_context method with the same name. +	/** +	* Assign key variable pairs from an array to a specified block +	* @param string $blockname Name of block to assign $vararray to +	* @param array $vararray A hash of variable name => value pairs +	*/ +	public function assign_block_vars($blockname, array $vararray) +	{ +		return $this->context->assign_block_vars($blockname, $vararray); +	} + +	// Docstring is copied from phpbb_template_context method with the same name. +	/** +	* Change already assigned key variable pair (one-dimensional - single loop entry) +	* +	* An example of how to use this function: +	* {@example alter_block_array.php} +	* +	* @param	string	$blockname	the blockname, for example 'loop' +	* @param	array	$vararray	the var array to insert/add or merge +	* @param	mixed	$key		Key to search for +	* +	* array: KEY => VALUE [the key/value pair to search for within the loop to determine the correct position] +	* +	* int: Position [the position to change or insert at directly given] +	* +	* If key is false the position is set to 0 +	* If key is true the position is set to the last entry +	* +	* @param	string	$mode		Mode to execute (valid modes are 'insert' and 'change') +	* +	*	If insert, the vararray is inserted at the given position (position counting from zero). +	*	If change, the current block gets merged with the vararray (resulting in new key/value pairs be added and existing keys be replaced by the new value). +	* +	* Since counting begins by zero, inserting at the last position will result in this array: array(vararray, last positioned array) +	* and inserting at position 1 will result in this array: array(first positioned array, vararray, following vars) +	* +	* @return bool false on error, true on success +	*/ +	public function alter_block_array($blockname, array $vararray, $key = false, $mode = 'insert') +	{ +		return $this->context->alter_block_array($blockname, $vararray, $key, $mode); +	} + +	/** +	* Include a separate template. +	* +	* This function is marked public due to the way the template +	* implementation uses it. It is actually an implementation function +	* and should not be considered part of template class's public API. +	* +	* @param string $filename Template filename to include +	* @param bool $include True to include the file, false to just load it +	* @uses template_compile is used to compile uncached templates +	*/ +	public function _tpl_include($filename, $include = true) +	{ +		$this->locator->set_filenames(array($filename => $filename)); + +		if (!$this->load_and_render($filename)) +		{ +			// trigger_error cannot be used here, as the output already started +			echo 'template->_tpl_include(): Failed including ' . htmlspecialchars($handle) . "\n"; +		} +	} + +	/** +	* Include a PHP file. +	* +	* If a relative path is passed in $filename, it is considered to be +	* relative to board root ($phpbb_root_path). Absolute paths are +	* also allowed. +	* +	* This function is marked public due to the way the template +	* implementation uses it. It is actually an implementation function +	* and should not be considered part of template class's public API. +	* +	* @param string $filename Path to PHP file to include +	*/ +	public function _php_include($filename) +	{ +		if (phpbb_is_absolute($filename)) +		{ +			$file = $filename; +		} +		else +		{ +			$file = $this->phpbb_root_path . $filename; +		} + +		if (!file_exists($file)) +		{ +			// trigger_error cannot be used here, as the output already started +			echo 'template->_php_include(): File ' . htmlspecialchars($file) . " does not exist\n"; +			return; +		} +		include($file); +	} + +	/** +	* Include JS file +	* +	* @param string $file file name +	* @param bool $locate True if file needs to be located +	* @param bool $relative True if path is relative to phpBB root directory. Ignored if $locate == true +	*/ +	public function _js_include($file, $locate = false, $relative = false) +	{ +		// Locate file +		if ($locate) +		{ +			$located = $this->locator->get_first_file_location(array($file), false, true); +			if ($located) +			{ +				$file = $located; +			} +		} +		else if ($relative) +		{ +			$file = $this->phpbb_root_path . $file; +		} + +		$file .= (strpos($file, '?') === false) ? '?' : '&'; +		$file .= 'assets_version=' . $this->config['assets_version']; + +		// Add HTML code +		$code = '<script src="' . htmlspecialchars($file) . '"></script>'; +		$this->context->append_var('SCRIPTS', $code); +	} +} diff --git a/phpBB/includes/template/template.php b/phpBB/includes/template/template.php index bbec768613..5dadd34084 100644 --- a/phpBB/includes/template/template.php +++ b/phpBB/includes/template/template.php @@ -2,7 +2,7 @@  /**  *  * @package phpBB3 -* @copyright (c) 2005 phpBB Group, sections (c) 2001 ispi of Lincoln Inc +* @copyright (c) 2013 phpBB Group  * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2  *  */ @@ -15,113 +15,14 @@ if (!defined('IN_PHPBB'))  	exit;  } -/** -* @todo -* IMG_ for image substitution? -* {IMG_[key]:[alt]:[type]} -* {IMG_ICON_CONTACT:CONTACT:full} -> $user->img('icon_contact', 'CONTACT', 'full'); -* -* More in-depth... -* yadayada -*/ - -/** -* Base Template class. -* @package phpBB3 -*/ -class phpbb_template +interface phpbb_template  {  	/** -	* Template context. -	* Stores template data used during template rendering. -	* @var phpbb_template_context -	*/ -	private $context; - -	/** -	* Path of the cache directory for the template -	* @var string -	*/ -	public $cachepath = ''; - -	/** -	* phpBB root path -	* @var string -	*/ -	private $phpbb_root_path; - -	/** -	* PHP file extension -	* @var string -	*/ -	private $php_ext; - -	/** -	* phpBB config instance -	* @var phpbb_config -	*/ -	private $config; - -	/** -	* Current user -	* @var phpbb_user -	*/ -	private $user; - -	/** -	* Template locator -	* @var phpbb_template_locator -	*/ -	private $locator; - -	/** -	* Extension manager. -	* -	* @var phpbb_extension_manager -	*/ -	private $extension_manager; - -	/** -	* Name of the style that the template being compiled and/or rendered -	* belongs to, and its parents, in inheritance tree order. -	* -	* Used to invoke style-specific template events. -	* -	* @var array -	*/ -	private $style_names; - -	/** -	* Constructor. -	* -	* @param string $phpbb_root_path phpBB root path -	* @param user $user current user -	* @param phpbb_template_locator $locator template locator -	* @param phpbb_template_context $context template context -	* @param phpbb_extension_manager $extension_manager extension manager, if null then template events will not be invoked -	*/ -	public function __construct($phpbb_root_path, $php_ext, $config, $user, phpbb_template_locator $locator, phpbb_template_context $context, phpbb_extension_manager $extension_manager = null) -	{ -		$this->phpbb_root_path = $phpbb_root_path; -		$this->php_ext = $php_ext; -		$this->config = $config; -		$this->user = $user; -		$this->locator = $locator; -		$this->context = $context; -		$this->extension_manager = $extension_manager; -	} - -	/**  	* Sets the template filenames for handles.  	*  	* @param array $filename_array Should be a hash of handle => filename pairs.  	*/ -	public function set_filenames(array $filename_array) -	{ -		$this->locator->set_filenames($filename_array); - -		return true; -	} +	public function set_filenames(array $filename_array);  	/**  	* Sets the style names corresponding to style hierarchy being compiled @@ -130,28 +31,19 @@ class phpbb_template  	* @param array $style_names List of style names in inheritance tree order  	* @return null  	*/ -	public function set_style_names(array $style_names) -	{ -		$this->style_names = $style_names; -	} +	public function set_style_names(array $style_names);  	/**  	* Clears all variables and blocks assigned to this template.  	*/ -	public function destroy() -	{ -		$this->context->clear(); -	} +	public function destroy();  	/**  	* Reset/empty complete block  	*  	* @param string $blockname Name of block to destroy  	*/ -	public function destroy_block_vars($blockname) -	{ -		$this->context->destroy_block_vars($blockname); -	} +	public function destroy_block_vars($blockname);  	/**  	* Display a template for provided handle. @@ -163,79 +55,7 @@ class phpbb_template  	* @param string $handle Handle to display  	* @return bool True on success, false on failure  	*/ -	public function display($handle) -	{ -		$result = $this->call_hook($handle, __FUNCTION__); -		if ($result !== false) -		{ -			return $result[0]; -		} - -		return $this->load_and_render($handle); -	} - -	/** -	* Loads a template for $handle, compiling it if necessary, and -	* renders the template. -	* -	* @param string $handle Template handle to render -	* @return bool True on success, false on failure -	*/ -	private function load_and_render($handle) -	{ -		$renderer = $this->_tpl_load($handle); - -		if ($renderer) -		{ -			$renderer->render($this->context, $this->get_lang()); -			return true; -		} -		else -		{ -			return false; -		} -	} - -	/** -	* Calls hook if any is defined. -	* -	* @param string $handle Template handle being displayed. -	* @param string $method Method name of the caller. -	*/ -	private function call_hook($handle, $method) -	{ -		global $phpbb_hook; - -		if (!empty($phpbb_hook) && $phpbb_hook->call_hook(array(__CLASS__, $method), $handle, $this)) -		{ -			if ($phpbb_hook->hook_return(array(__CLASS__, $method))) -			{ -				$result = $phpbb_hook->hook_return_result(array(__CLASS__, $method)); -				return array($result); -			} -		} - -		return false; -	} - -	/** -	* Obtains language array. -	* This is either lang property of $user property, or if -	* it is not set an empty array. -	* @return array language entries -	*/ -	public function get_lang() -	{ -		if (isset($this->user->lang)) -		{ -			$lang = $this->user->lang; -		} -		else -		{ -			$lang = array(); -		} -		return $lang; -	} +	public function display($handle);  	/**  	* Display the handle and assign the output to a template variable @@ -246,116 +66,14 @@ class phpbb_template  	* @param bool $return_content If true return compiled handle, otherwise assign to $template_var  	* @return bool|string false on failure, otherwise if $return_content is true return string of the compiled handle, otherwise return true  	*/ -	public function assign_display($handle, $template_var = '', $return_content = true) -	{ -		ob_start(); -		$result = $this->display($handle); -		$contents = ob_get_clean(); -		if ($result === false) -		{ -			return false; -		} - -		if ($return_content) -		{ -			return $contents; -		} - -		$this->assign_var($template_var, $contents); - -		return true; -	} - -	/** -	* Obtains a template renderer for a template identified by specified -	* handle. The template renderer can display the template later. -	* -	* Template source will first be compiled into php code. -	* If template cache is writable the compiled php code will be stored -	* on filesystem and template will not be subsequently recompiled. -	* If template cache is not writable template source will be recompiled -	* every time it is needed. DEBUG define and load_tplcompile -	* configuration setting may be used to force templates to be always -	* recompiled. -	* -	* Returns an object implementing phpbb_template_renderer, or null -	* if template loading or compilation failed. Call render() on the -	* renderer to display the template. This will result in template -	* contents sent to the output stream (unless, of course, output -	* buffering is in effect). -	* -	* @param string $handle Handle of the template to load -	* @return phpbb_template_renderer Template renderer object, or null on failure -	* @uses phpbb_template_compile is used to compile template source -	*/ -	private function _tpl_load($handle) -	{ -		$output_file = $this->_compiled_file_for_handle($handle); - -		$recompile = defined('DEBUG') || -			!file_exists($output_file) || -			@filesize($output_file) === 0; - -		if ($recompile || $this->config['load_tplcompile']) -		{ -			// Set only if a recompile or an mtime check are required. -			$source_file = $this->locator->get_source_file_for_handle($handle); - -			if (!$recompile && @filemtime($output_file) < @filemtime($source_file)) -			{ -				$recompile = true; -			} -		} - -		// Recompile page if the original template is newer, otherwise load the compiled version -		if (!$recompile) -		{ -			return new phpbb_template_renderer_include($output_file, $this); -		} - -		$compile = new phpbb_template_compile($this->config['tpl_allow_php'], $this->style_names, $this->locator, $this->phpbb_root_path, $this->extension_manager, $this->user); - -		if ($compile->compile_file_to_file($source_file, $output_file) !== false) -		{ -			$renderer = new phpbb_template_renderer_include($output_file, $this); -		} -		else if (($code = $compile->compile_file($source_file)) !== false) -		{ -			$renderer = new phpbb_template_renderer_eval($code, $this); -		} -		else -		{ -			$renderer = null; -		} - -		return $renderer; -	} - -	/** -	* Determines compiled file path for handle $handle. -	* -	* @param string $handle Template handle (i.e. "friendly" template name) -	* @return string Compiled file path -	*/ -	private function _compiled_file_for_handle($handle) -	{ -		$source_file = $this->locator->get_filename_for_handle($handle); -		$compiled_file = $this->cachepath . str_replace('/', '.', $source_file) . '.' . $this->php_ext; -		return $compiled_file; -	} +	public function assign_display($handle, $template_var = '', $return_content = true);  	/**  	* Assign key variable pairs from an array  	*  	* @param array $vararray A hash of variable name => value pairs  	*/ -	public function assign_vars(array $vararray) -	{ -		foreach ($vararray as $key => $val) -		{ -			$this->assign_var($key, $val); -		} -	} +	public function assign_vars(array $vararray);  	/**  	* Assign a single scalar value to a single key. @@ -365,10 +83,7 @@ class phpbb_template  	* @param string $varname Variable name  	* @param string $varval Value to assign to variable  	*/ -	public function assign_var($varname, $varval) -	{ -		$this->context->assign_var($varname, $varval); -	} +	public function assign_var($varname, $varval);  	/**  	* Append text to the string value stored in a key. @@ -378,23 +93,15 @@ class phpbb_template  	* @param string $varname Variable name  	* @param string $varval Value to append to variable  	*/ -	public function append_var($varname, $varval) -	{ -		$this->context->append_var($varname, $varval); -	} +	public function append_var($varname, $varval); -	// Docstring is copied from phpbb_template_context method with the same name.  	/**  	* Assign key variable pairs from an array to a specified block  	* @param string $blockname Name of block to assign $vararray to  	* @param array $vararray A hash of variable name => value pairs  	*/ -	public function assign_block_vars($blockname, array $vararray) -	{ -		return $this->context->assign_block_vars($blockname, $vararray); -	} +	public function assign_block_vars($blockname, array $vararray); -	// Docstring is copied from phpbb_template_context method with the same name.  	/**  	* Change already assigned key variable pair (one-dimensional - single loop entry)  	* @@ -422,94 +129,5 @@ class phpbb_template  	*  	* @return bool false on error, true on success  	*/ -	public function alter_block_array($blockname, array $vararray, $key = false, $mode = 'insert') -	{ -		return $this->context->alter_block_array($blockname, $vararray, $key, $mode); -	} - -	/** -	* Include a separate template. -	* -	* This function is marked public due to the way the template -	* implementation uses it. It is actually an implementation function -	* and should not be considered part of template class's public API. -	* -	* @param string $filename Template filename to include -	* @param bool $include True to include the file, false to just load it -	* @uses template_compile is used to compile uncached templates -	*/ -	public function _tpl_include($filename, $include = true) -	{ -		$this->locator->set_filenames(array($filename => $filename)); - -		if (!$this->load_and_render($filename)) -		{ -			// trigger_error cannot be used here, as the output already started -			echo 'template->_tpl_include(): Failed including ' . htmlspecialchars($handle) . "\n"; -		} -	} - -	/** -	* Include a PHP file. -	* -	* If a relative path is passed in $filename, it is considered to be -	* relative to board root ($phpbb_root_path). Absolute paths are -	* also allowed. -	* -	* This function is marked public due to the way the template -	* implementation uses it. It is actually an implementation function -	* and should not be considered part of template class's public API. -	* -	* @param string $filename Path to PHP file to include -	*/ -	public function _php_include($filename) -	{ -		if (phpbb_is_absolute($filename)) -		{ -			$file = $filename; -		} -		else -		{ -			$file = $this->phpbb_root_path . $filename; -		} - -		if (!file_exists($file)) -		{ -			// trigger_error cannot be used here, as the output already started -			echo 'template->_php_include(): File ' . htmlspecialchars($file) . " does not exist\n"; -			return; -		} -		include($file); -	} - -	/** -	* Include JS file -	* -	* @param string $file file name -	* @param bool $locate True if file needs to be located -	* @param bool $relative True if path is relative to phpBB root directory. Ignored if $locate == true -	*/ -	public function _js_include($file, $locate = false, $relative = false) -	{ -		// Locate file -		if ($locate) -		{ -			$located = $this->locator->get_first_file_location(array($file), false, true); -			if ($located) -			{ -				$file = $located; -			} -		} -		else if ($relative) -		{ -			$file = $this->phpbb_root_path . $file; -		} - -		$file .= (strpos($file, '?') === false) ? '?' : '&'; -		$file .= 'assets_version=' . $this->config['assets_version']; - -		// Add HTML code -		$code = '<script src="' . htmlspecialchars($file) . '"></script>'; -		$this->context->append_var('SCRIPTS', $code); -	} +	public function alter_block_array($blockname, array $vararray, $key = false, $mode = 'insert');  } diff --git a/phpBB/includes/template/twig/environment.php b/phpBB/includes/template/twig/environment.php new file mode 100644 index 0000000000..4c7f0002ba --- /dev/null +++ b/phpBB/includes/template/twig/environment.php @@ -0,0 +1,145 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ +	exit; +} + +class phpbb_template_twig_environment extends Twig_Environment +{ +	/** @var array */ +	protected $phpbbExtensions; + +	/** @var array **/ +	protected $namespaceLookUpOrder = array('__main__'); + +    /** +     * Gets the cache filename for a given template. +     * +     * @param string $name The template name +     * +     * @return string The cache file name +     */ +    public function getCacheFilename($name) +    { +        if (false === $this->cache) { +            return false; +        } + +    	return $this->getCache() . '/' . preg_replace('#[^a-zA-Z0-9_/]#', '_', $name) . '.php'; +    } + +	/** +	* Get the list of enabled phpBB extensions +	* +	* @return array +	*/ +	public function get_phpbb_extensions() +	{ +		return $this->phpbbExtensions; +	} + +    /** +    * Store the list of enabled phpBB extensions +    * +    * @param array $extensions +    * @return Twig_Environment +    */ +    public function set_phpbb_extensions($extensions) +    { +    	$this->phpbbExtensions = $extensions; + +		return $this; +	} + +	/** +	* Get the namespace look up order +	* +	* @return array +	*/ +	public function getNamespaceLookUpOrder() +	{ +		return $this->namespaceLookUpOrder; +	} + +	/** +	* Set the namespace look up order to load templates from +	* +	* @param array $namespace +    * @return Twig_Environment +	*/ +	public function setNamespaceLookUpOrder($namespace) +	{ +		$this->namespaceLookUpOrder = $namespace; + +		return $this; +	} + +    /** +     * Loads a template by name. +     * +     * @param string  $name  The template name +     * @param integer $index The index if it is an embedded template +     * +     * @return Twig_TemplateInterface A template instance representing the given template name +     */ +    public function loadTemplate($name, $index = null) +    { +    	if (strpos($name, '@') === false) +    	{ +    		foreach ($this->namespaceLookUpOrder as $namespace) +    		{ +        		try +    			{ +    				if ($namespace === '__main__') +    				{ +    					return parent::loadTemplate($name, $index); +					} + +    				return parent::loadTemplate('@' . $namespace . '/' . $name, $index); +				} +				catch (Twig_Error_Loader $e) +				{ +				} +			} + +			// We were unable to load any templates +			throw $e; +		} +		else +		{ +    		return parent::loadTemplate($name, $index); +		} +    } + +	/** +	* recursive helper to set variables into $context so that Twig can properly fetch them for display +	* +	* @param array $data Data to set at the end of the chain +	* @param array $blocks Array of blocks to loop into still +	* @param mixed $current_location Current location in $context (recursive!) +	*/ +	public function context_recursive_loop_builder($data, $blocks, &$current_location) +	{ +		$block = array_shift($blocks); + +		if (empty($blocks)) +		{ +			$current_location[$block] = $data; +		} +		else +		{ +			$this->context_recursive_loop_builder($data, $blocks, $current_location[$block]); +		} +	} +} diff --git a/phpBB/includes/template/twig/extension.php b/phpBB/includes/template/twig/extension.php new file mode 100644 index 0000000000..ff37a38c29 --- /dev/null +++ b/phpBB/includes/template/twig/extension.php @@ -0,0 +1,62 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ +	exit; +} + +class phpbb_template_twig_extension extends Twig_Extension +{ +	public function getName() +	{ +		return 'phpbb'; +	} + +	public function getTokenParsers() +	{ +		return array( +			new phpbb_template_twig_tokenparser_if, +			new phpbb_template_twig_tokenparser_begin, +			new phpbb_template_twig_tokenparser_define, +			new phpbb_template_twig_tokenparser_include, +			new phpbb_template_twig_tokenparser_includejs, +			new phpbb_template_twig_tokenparser_event, +		); +	} + +	public function getOperators() +	{ +		return array( +			array(), +			array( +				// @todo check if all these are needed (or others) +				'eq' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Equal', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + +				'ne' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), +				'neq' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), +				'<>' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + +				'===' => array('precedence' => 20, 'class' => 'phpbb_template_twig_node_expression_binary_equalequal', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), +				'!==' => array('precedence' => 20, 'class' => 'phpbb_template_twig_node_expression_binary_notequalequal', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + +				'gt' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Greater', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), +				'gte' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_GreaterEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), +				'lt' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Less', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), +				'lte' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_LessEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + +				'||' => array('precedence' => 10, 'class' => 'Twig_Node_Expression_Binary_Or', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), +				'&&' => array('precedence' => 15, 'class' => 'Twig_Node_Expression_Binary_And', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), +			), +		); +	} +} diff --git a/phpBB/includes/template/twig/lexer.php b/phpBB/includes/template/twig/lexer.php new file mode 100644 index 0000000000..b2828c9e25 --- /dev/null +++ b/phpBB/includes/template/twig/lexer.php @@ -0,0 +1,73 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ +	exit; +} + +class phpbb_template_twig_lexer extends Twig_Lexer +{ +	public function tokenize($code, $filename = null) +	{ +		$valid_starting_tokens = array( +			'BEGIN', +			'BEGINELSE', +			'END', +			'IF', +			'ELSE', +			'ELSEIF', +			'ENDIF', +			'DEFINE', +			'DEFINE', +			'UNDEFINE', +			'ENDDEFINE', +			/*'INCLUDE', +			'INCLUDEPHP',*/ +			'INCLUDEJS', +			'PHP', +			'ENDPHP', +			'EVENT', +		); + +		// Replace <!-- INCLUDE blah.html --> with {% include 'blah.html' %} +		$code = preg_replace('#<!-- INCLUDE(PHP)? (.*?) -->#', "{% INCLUDE$1 '$2' %}", $code); + +		// This strips the $ inside of a tag directly after the token, which was used in <!-- DEFINE $NAME +		$code = preg_replace('#<!-- DEFINE \$(.*)-->#', '<!-- DEFINE $1-->', $code); + +		// This strips the . or $ inside of a tag directly before a variable name, which was used in <!-- IF .blah +		$code = preg_replace_callback('#<!-- IF((.*)[\s][\$|\.]([^\s]+)(.*))-->#', array($this, 'tag_if_cleanup'), $code); + +		// Replace all of our starting tokens, <!-- TOKEN --> with Twig style, {% TOKEN %} +		// This also strips outer parenthesis, <!-- IF (blah) --> becomes <!-- IF blah --> +		$code = preg_replace('#<!-- (' . implode('|', $valid_starting_tokens) . ')(?: (.*?) ?)?-->#', '{% $1 $2 %}', $code); + +		// Replace all of our variables, {VARNAME} or {$VARNAME}, with Twig style, {{ VARNAME }} +		$code = preg_replace('#{\$?([a-zA-Z0-9_\.]+)}#', '{{ $1 }}', $code); + +		return parent::tokenize($code, $filename); +	} + +	/** +	* preg_replace_callback to clean up IF statements +	* +	* This strips the . or $ inside of a tag directly before a variable name. +	* Was used in <!-- IF .blah or <!-- IF $BLAH +	* +	* @param mixed $matches +	*/ +	protected function tag_if_cleanup($matches) +	{ +		return '<!-- IF ' . preg_replace('#\s[\.|\$]([a-zA-Z_0-9]+)#', ' $1', $matches[1]) . ' -->'; +	} +} diff --git a/phpBB/includes/template/twig/loader.php b/phpBB/includes/template/twig/loader.php new file mode 100644 index 0000000000..b153bd81ea --- /dev/null +++ b/phpBB/includes/template/twig/loader.php @@ -0,0 +1,51 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +// @todo remove if not needed +class phpbb_template_twig_loader extends Twig_Loader_Filesystem +{ +	protected $phpbb_locator; + +    /** +    * Constructor. +    * +    * @param string|array $paths A path or an array of paths where to look for templates +    * @param phpbb_template_locator +    */ +    public function __construct($paths = array(), phpbb_template_locator $phpbb_locator) +    { +        if ($paths) { +            $this->setPaths($paths); +        } + +        $this->phpbb_locator = $phpbb_locator; +    } + +    protected function findTemplate($name) +    { +        $name = (string) $name; + +        if (!$name) +        { +        	throw new Twig_Error_Loader(sprintf('Unable to find template "%s".', $name)); +		} + +        $this->phpbb_locator->set_filenames(array( +        	'temp'		=> $name, +        )); +        $location = $this->phpbb_locator->get_source_file_for_handle('temp'); + +        if (!$location) +        { +        	throw new Twig_Error_Loader(sprintf('Unable to find template "%s".', $name)); +		} + +		return $this->cache[$name] = $location; +    } +} diff --git a/phpBB/includes/template/twig/node/begin.php b/phpBB/includes/template/twig/node/begin.php new file mode 100644 index 0000000000..4222295d26 --- /dev/null +++ b/phpBB/includes/template/twig/node/begin.php @@ -0,0 +1,123 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_template_twig_node_begin extends Twig_Node +{ +    public function __construct($beginName, Twig_NodeInterface $body, Twig_NodeInterface $else = null, $lineno, $tag = null) +    { +        parent::__construct(array('body' => $body, 'else' => $else), array('beginName' => $beginName), $lineno, $tag); +    } + +    /** +     * Compiles the node to PHP. +     * +     * @param Twig_Compiler A Twig_Compiler instance +     */ +    public function compile(Twig_Compiler $compiler) +    { +		$compiler +			->write("if (!isset(\$phpbb_blocks)) {\n") +			->indent() +				->write("\$phpbb_blocks = array();\n") +				->write("\$parent = \$context['_phpbb_blocks'];\n") +			->outdent() +			->write("}\n") +			->write("\$phpbb_blocks[] = '" . $this->getAttribute('beginName') . "';\n") +		; + +        $compiler +			->write("foreach (\$parent['" . $this->getAttribute('beginName') . "'] as \$" . $this->getAttribute('beginName') . ") {\n") +			->indent() +				// Set up $context correctly so that Twig can get the correct data with $this->getAttribute +				->write("\$this->getEnvironment()->context_recursive_loop_builder(\$" . $this->getAttribute('beginName') . ", \$phpbb_blocks, \$context);\n") + +				// We store the parent so that we can do this recursively +				->write("\$parent = \$" . $this->getAttribute('beginName') . ";\n") +        ; + +        $compiler->subcompile($this->getNode('body')); + +        $compiler +            ->outdent() +            ->write("}\n") + +            // Remove the last item from the blocks storage as we've completed iterating over them all +            ->write("array_pop(\$phpbb_blocks);\n") + +            // If we've gone through all of the blocks, we're back at the main level and have completed, so unset the var +            ->write("if (empty(\$phpbb_blocks)) { unset(\$phpbb_blocks); }\n") +        ; +    } + +    /** +     * Compiles the node to PHP. +     * +     * Uses anonymous functions to compile the loops, which seems nicer to me, but requires PHP 5.4 (since subcompile uses $this, which is not available in 5.3) +     * +     * @param Twig_Compiler A Twig_Compiler instance +     * +    public function compile(Twig_Compiler $compiler) +    { +        $compiler->addDebugInfo($this); + +		$compiler +			// name -> loop name +			// local context -> parent template variable context +			// global context -> global template variable context +			// variable chain -> full chain of variables to output template vars properly in subloops +			//		e.g. [foo][bar][foobar] +			// current chain location -> current location in subloop +			//		e.g. [foobar] of [foo][bar] +			->write("\$iterator = function (\$name, \$local_context, \$global_context, &\$variable_chain, &\$current_chain_location) {\n") +			->indent() +				//->write("var_dump(\$name, \$local_context);\n") +				// Try to find the loop in the +				// local context (child of local context passed, in case of a child loop) +				// global context (root template var) +				->write("if (isset(\$local_context[\$name])) {\n") +				->indent() +					->write("\$local_context = \$local_context[\$name];\n") +				->outdent() +				->write("}\n") +				->write("else if (isset(\$global_context[\$name])) {\n") +				->indent() +					->write("\$local_context = \$global_context[\$name];\n") +				->outdent() +				->write("} else { return; }\n") + +				->write("if (!is_array(\$local_context) || empty(\$local_context)) { return; }\n") + +				->write("foreach (\$local_context as \$for_context) {\n") +				->indent() +					// Some hackish stuff for Twig to properly subcompile +					->write("\$current_chain_location[\$name] = \$for_context;\n") +					->write("\$context = array_merge(\$global_context, \$variable_chain);\n") + +					// Children +					->subcompile($this->getNode('body')) +				->outdent() +				->write("}\n") +			->outdent() +			->write("};\n") +			->write("if (isset(\$global_context)) {\n") +			->indent() +				// We are already inside an anonymous function +				->write("\$iterator('" . $this->getAttribute('beginName') . "', \$for_context, \$global_context, \$variable_chain, \$current_chain_location[\$name]);\n") +			->outdent() +			->write("} else {\n") +			->indent() +				// We are not inside the anonymous function (first level) +				->write("\$variable_chain = array();\n") +				->write("\$current_chain_location = array();\n") +				->write("\$iterator('" . $this->getAttribute('beginName') . "', array(), \$context, \$variable_chain, \$variable_chain);\n") +			->outdent() +			->write("}\n"); +    } +    */ +} diff --git a/phpBB/includes/template/twig/node/event.php b/phpBB/includes/template/twig/node/event.php new file mode 100644 index 0000000000..12e6ef1329 --- /dev/null +++ b/phpBB/includes/template/twig/node/event.php @@ -0,0 +1,49 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_template_twig_node_event extends Twig_Node +{ +	protected $environment; + +    public function __construct(Twig_Node_Expression $expr, phpbb_template_twig_environment $environment, $lineno, $tag = null) +    { +    	$this->environment = $environment; + +        parent::__construct(array('expr' => $expr), array(), $lineno, $tag); +    } + +    /** +     * Compiles the node to PHP. +     * +     * @param Twig_Compiler A Twig_Compiler instance +     */ +    public function compile(Twig_Compiler $compiler) +    { +        $compiler->addDebugInfo($this); + +    	$location = $this->getNode('expr')->getAttribute('name'); + +    	foreach ($this->environment->get_phpbb_extensions() as $ext_namespace => $ext_path) +    	{ +    		$ext_namespace = str_replace('/', '_', $ext_namespace); + +    		if ($this->environment->getLoader()->exists('@' . $ext_namespace . '/' . $location . '.html')) +    		{ +    			$compiler +    				->write("\$previous_look_up_order = \$this->env->getNamespaceLookUpOrder();\n") + +    				// We set the namespace lookup order to be this extension first, then the main path +    				->write("\$this->env->setNamespaceLookUpOrder(array('" . $ext_namespace . "', '__main__'));\n") +    				->write("\$this->env->loadTemplate('@" . $ext_namespace . "/" . $location . ".html')->display(\$context);\n") +    				->write("\$this->env->setNamespaceLookUpOrder(\$previous_look_up_order);\n") +    			; +			} +		} +    } +} diff --git a/phpBB/includes/template/twig/node/expression/binary/equalequal.php b/phpBB/includes/template/twig/node/expression/binary/equalequal.php new file mode 100644 index 0000000000..3a0c79c839 --- /dev/null +++ b/phpBB/includes/template/twig/node/expression/binary/equalequal.php @@ -0,0 +1,16 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_template_twig_node_expression_binary_equalequal extends Twig_Node_Expression_Binary +{ +    public function operator(Twig_Compiler $compiler) +    { +        return $compiler->raw('==='); +    } +} diff --git a/phpBB/includes/template/twig/node/expression/binary/notequalequal.php b/phpBB/includes/template/twig/node/expression/binary/notequalequal.php new file mode 100644 index 0000000000..b53bc56b2d --- /dev/null +++ b/phpBB/includes/template/twig/node/expression/binary/notequalequal.php @@ -0,0 +1,16 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_template_twig_node_expression_binary_notequalequal extends Twig_Node_Expression_Binary +{ +    public function operator(Twig_Compiler $compiler) +    { +        return $compiler->raw('!=='); +    } +} diff --git a/phpBB/includes/template/twig/node/include.php b/phpBB/includes/template/twig/node/include.php new file mode 100644 index 0000000000..df7a95af44 --- /dev/null +++ b/phpBB/includes/template/twig/node/include.php @@ -0,0 +1,45 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_template_twig_node_include extends Twig_Node_Include +{ +    /** +     * Compiles the node to PHP. +     * +     * @param Twig_Compiler A Twig_Compiler instance +     */ +    public function compile(Twig_Compiler $compiler) +    { +        $compiler->addDebugInfo($this); + +    	$location = $this->getNode('expr')->getAttribute('value'); +    	$namespace = false; + +    	if (strpos($location, '@') === 0) +    	{ +    		$namespace = substr($location, 1, strpos($location, '/') - 1); + +    		$compiler +    			->write("\$previous_look_up_order = \$this->env->getNamespaceLookUpOrder();\n") + +    			// We set the namespace lookup order to be this namespace first, then the main path +    			->write("\$this->env->setNamespaceLookUpOrder(array('" . $namespace . "', '__main__'));\n") +    		; +		} + +        parent::compile($compiler); + +    	if ($namespace) +    	{ +    		$compiler +    			->write("\$this->env->setNamespaceLookUpOrder(\$previous_look_up_order);\n") +    		; +		} +    } +} diff --git a/phpBB/includes/template/twig/node/includejs.php b/phpBB/includes/template/twig/node/includejs.php new file mode 100644 index 0000000000..881636a326 --- /dev/null +++ b/phpBB/includes/template/twig/node/includejs.php @@ -0,0 +1,32 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_template_twig_node_includejs extends Twig_Node +{ +    public function __construct(Twig_Node_Expression $expr, $lineno, $tag = null) +    { +        parent::__construct(array('expr' => $expr), array(), $lineno, $tag); +    } + +    /** +     * Compiles the node to PHP. +     * +     * @param Twig_Compiler A Twig_Compiler instance +     */ +    public function compile(Twig_Compiler $compiler) +    { +        $compiler->addDebugInfo($this); + +        $compiler +        	->write("\$context['SCRIPTS'] .= '<script type=\"text/javascript\" src=\"' . ") +        	->subcompile($this->getNode('expr')) +        	->raw(" . '\">';\n\n") +        ; +    } +} diff --git a/phpBB/includes/template/twig/tokenparser/begin.php b/phpBB/includes/template/twig/tokenparser/begin.php new file mode 100644 index 0000000000..0a2f2da40d --- /dev/null +++ b/phpBB/includes/template/twig/tokenparser/begin.php @@ -0,0 +1,57 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group, sections (c) 2009 Fabien Potencier +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_template_twig_tokenparser_begin extends Twig_TokenParser_For +{ +    /** +     * Parses a token and returns a node. +     * +     * @param Twig_Token $token A Twig_Token instance +     * +     * @return Twig_NodeInterface A Twig_NodeInterface instance +     */ +	public function parse(Twig_Token $token) +	{ +		$lineno = $token->getLine(); +		$beginName = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE)->getValue(); + +		$this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); +		$body = $this->parser->subparse(array($this, 'decideBeginFork')); +		if ($this->parser->getStream()->next()->getValue() == 'BEGINELSE') { +			$this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); +			$else = $this->parser->subparse(array($this, 'decideBeginEnd'), true); +		} else { +			$else = null; +		} +		$this->parser->getStream()->expect(Twig_Token::NAME_TYPE, $beginName); +		$this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); + +		return new phpbb_template_twig_node_begin($beginName, $body, $else, $lineno, $this->getTag()); +	} + +    public function decideBeginFork(Twig_Token $token) +    { +        return $token->test(array('BEGINELSE', 'END')); +    } + +    public function decideBeginEnd(Twig_Token $token) +    { +        return $token->test('END'); +    } + +    /** +     * Gets the tag name associated with this token parser. +     * +     * @return string The tag name +     */ +    public function getTag() +    { +        return 'BEGIN'; +    } +} diff --git a/phpBB/includes/template/twig/tokenparser/define.php b/phpBB/includes/template/twig/tokenparser/define.php new file mode 100644 index 0000000000..83f537a1ea --- /dev/null +++ b/phpBB/includes/template/twig/tokenparser/define.php @@ -0,0 +1,26 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group, sections (c) 2009 Fabien Potencier +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_template_twig_tokenparser_define extends Twig_TokenParser_Set +{ +    public function decideBlockEnd(Twig_Token $token) +    { +        return $token->test('ENDDEFINE'); +    } + +    /** +     * Gets the tag name associated with this token parser. +     * +     * @return string The tag name +     */ +    public function getTag() +    { +        return 'DEFINE'; +    } +} diff --git a/phpBB/includes/template/twig/tokenparser/event.php b/phpBB/includes/template/twig/tokenparser/event.php new file mode 100644 index 0000000000..03810454ed --- /dev/null +++ b/phpBB/includes/template/twig/tokenparser/event.php @@ -0,0 +1,38 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_template_twig_tokenparser_event extends Twig_TokenParser +{ +    /** +     * Parses a token and returns a node. +     * +     * @param Twig_Token $token A Twig_Token instance +     * +     * @return Twig_NodeInterface A Twig_NodeInterface instance +     */ +    public function parse(Twig_Token $token) +    { +        $expr = $this->parser->getExpressionParser()->parseExpression(); + +        $stream = $this->parser->getStream(); +        $stream->expect(Twig_Token::BLOCK_END_TYPE); + +        return new phpbb_template_twig_node_event($expr, $this->parser->getEnvironment(), $token->getLine(), $this->getTag()); +    } + +    /** +     * Gets the tag name associated with this token parser. +     * +     * @return string The tag name +     */ +    public function getTag() +    { +        return 'EVENT'; +    } +} diff --git a/phpBB/includes/template/twig/tokenparser/if.php b/phpBB/includes/template/twig/tokenparser/if.php new file mode 100644 index 0000000000..04ee048f94 --- /dev/null +++ b/phpBB/includes/template/twig/tokenparser/if.php @@ -0,0 +1,78 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group, sections (c) 2009 Fabien Potencier +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_template_twig_tokenparser_if extends Twig_TokenParser_If +{ +    /** +     * Parses a token and returns a node. +     * +     * @param Twig_Token $token A Twig_Token instance +     * +     * @return Twig_NodeInterface A Twig_NodeInterface instance +     */ +    public function parse(Twig_Token $token) +    { +        $lineno = $token->getLine(); +        $expr = $this->parser->getExpressionParser()->parseExpression(); +        $stream = $this->parser->getStream(); +        $stream->expect(Twig_Token::BLOCK_END_TYPE); +        $body = $this->parser->subparse(array($this, 'decideIfFork')); +        $tests = array($expr, $body); +        $else = null; + +        $end = false; +        while (!$end) { +            switch ($stream->next()->getValue()) { +                case 'ELSE': +                    $stream->expect(Twig_Token::BLOCK_END_TYPE); +                    $else = $this->parser->subparse(array($this, 'decideIfEnd')); +                    break; + +                case 'ELSEIF': +                    $expr = $this->parser->getExpressionParser()->parseExpression(); +                    $stream->expect(Twig_Token::BLOCK_END_TYPE); +                    $body = $this->parser->subparse(array($this, 'decideIfFork')); +                    $tests[] = $expr; +                    $tests[] = $body; +                    break; + +                case 'ENDIF': +                    $end = true; +                    break; + +                default: +                    throw new Twig_Error_Syntax(sprintf('Unexpected end of template. Twig was looking for the following tags "ELSE", "ELSEIF", or "ENDIF" to close the "IF" block started at line %d)', $lineno), $stream->getCurrent()->getLine(), $stream->getFilename()); +            } +        } + +        $stream->expect(Twig_Token::BLOCK_END_TYPE); + +        return new Twig_Node_If(new Twig_Node($tests), $else, $lineno, $this->getTag()); +    } + +    public function decideIfFork(Twig_Token $token) +    { +        return $token->test(array('ELSEIF', 'ELSE', 'ENDIF')); +    } + +    public function decideIfEnd(Twig_Token $token) +    { +        return $token->test(array('ENDIF')); +    } + +    /** +     * Gets the tag name associated with this token parser. +     * +     * @return string The tag name +     */ +    public function getTag() +    { +        return 'IF'; +    } +} diff --git a/phpBB/includes/template/twig/tokenparser/include.php b/phpBB/includes/template/twig/tokenparser/include.php new file mode 100644 index 0000000000..0f7e4faf8f --- /dev/null +++ b/phpBB/includes/template/twig/tokenparser/include.php @@ -0,0 +1,37 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group, sections (c) 2009 Fabien Potencier +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_template_twig_tokenparser_include extends Twig_TokenParser_Include +{ +    /** +     * Parses a token and returns a node. +     * +     * @param Twig_Token $token A Twig_Token instance +     * +     * @return Twig_NodeInterface A Twig_NodeInterface instance +     */ +    public function parse(Twig_Token $token) +    { +        $expr = $this->parser->getExpressionParser()->parseExpression(); + +        list($variables, $only, $ignoreMissing) = $this->parseArguments(); + +        return new phpbb_template_twig_node_include($expr, $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag()); +    } + +    /** +     * Gets the tag name associated with this token parser. +     * +     * @return string The tag name +     */ +    public function getTag() +    { +        return 'INCLUDE'; +    } +} diff --git a/phpBB/includes/template/twig/tokenparser/includejs.php b/phpBB/includes/template/twig/tokenparser/includejs.php new file mode 100644 index 0000000000..efa8692f4b --- /dev/null +++ b/phpBB/includes/template/twig/tokenparser/includejs.php @@ -0,0 +1,38 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_template_twig_tokenparser_includejs extends Twig_TokenParser +{ +    /** +     * Parses a token and returns a node. +     * +     * @param Twig_Token $token A Twig_Token instance +     * +     * @return Twig_NodeInterface A Twig_NodeInterface instance +     */ +    public function parse(Twig_Token $token) +    { +        $expr = $this->parser->getExpressionParser()->parseExpression(); + +        $stream = $this->parser->getStream(); +        $stream->expect(Twig_Token::BLOCK_END_TYPE); + +        return new phpbb_template_twig_node_includejs($expr, $token->getLine(), $this->getTag()); +    } + +    /** +     * Gets the tag name associated with this token parser. +     * +     * @return string The tag name +     */ +    public function getTag() +    { +        return 'INCLUDEJS'; +    } +} diff --git a/phpBB/includes/template/twig/twig.php b/phpBB/includes/template/twig/twig.php new file mode 100644 index 0000000000..c894fb5567 --- /dev/null +++ b/phpBB/includes/template/twig/twig.php @@ -0,0 +1,449 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ +	exit; +} + +/** +* Twig Template class. +* @package phpBB3 +*/ +class phpbb_template_twig implements phpbb_template +{ +	/** +	* Template context. +	* Stores template data used during template rendering. +	* @var phpbb_template_context +	*/ +	protected $context; + +	/** +	* Path of the cache directory for the template +	* @var string +	*/ +	public $cachepath = ''; + +	/** +	* phpBB root path +	* @var string +	*/ +	protected $phpbb_root_path; + +	/** +	* PHP file extension +	* @var string +	*/ +	protected $php_ext; + +	/** +	* phpBB config instance +	* @var phpbb_config +	*/ +	protected $config; + +	/** +	* Current user +	* @var phpbb_user +	*/ +	protected $user; + +	/** +	* Template locator +	* @var phpbb_template_locator +	*/ +	protected $locator; + +	/** +	* Extension manager. +	* +	* @var phpbb_extension_manager +	*/ +	protected $extension_manager; + +	/** +	* Name of the style that the template being compiled and/or rendered +	* belongs to, and its parents, in inheritance tree order. +	* +	* Used to invoke style-specific template events. +	* +	* @var array +	*/ +	protected $style_names; + +	/** +	* Twig Environment +	* +	* @var Twig_Environment +	*/ +	protected $twig; + +	/** +	* Constructor. +	* +	* @todo remove unnecessary dependencies +	* +	* @param string $phpbb_root_path phpBB root path +	* @param user $user current user +	* @param phpbb_template_locator $locator template locator +	* @param phpbb_template_context $context template context +	* @param phpbb_extension_manager $extension_manager extension manager, if null then template events will not be invoked +	*/ +	public function __construct($phpbb_root_path, $php_ext, $config, $user, phpbb_template_locator $locator, phpbb_template_context $context, phpbb_extension_manager $extension_manager = null) +	{ +		$this->phpbb_root_path = $phpbb_root_path; +		$this->php_ext = $php_ext; +		$this->config = $config; +		$this->user = $user; +		$this->locator = $locator; +		$this->context = $context; +		$this->extension_manager = $extension_manager; + +		$this->cachepath = $phpbb_root_path . 'cache/twig/'; + +		// Initiate the loader, __main__ namespace paths will be setup later in set_style_names() +		$loader = new Twig_Loader_Filesystem(''); + +		// Add admin namespace +		// @todo use phpbb_admin path +		$loader->addPath($this->phpbb_root_path . 'adm/style/', 'admin'); + +		$this->twig = new phpbb_template_twig_environment($loader, array( +		    'cache'			=> $this->cachepath, +		    'debug'			=> true, // @todo +		    'auto_reload'	=> true, // @todo +    		'autoescape'	=> false, +		)); + +		// Set enabled phpbb extensions +		if ($this->extension_manager) +		{ +			$this->twig->set_phpbb_extensions($this->extension_manager->all_enabled()); +		} + +		// Clear previous cache files (while WIP) +		// @todo remove +		if (is_dir($this->cachepath)) +		{ +			$this->twig->clearCacheFiles(); +		} + +		$this->twig->addExtension(new phpbb_template_twig_extension); + +		$lexer = new phpbb_template_twig_lexer($this->twig); + +		$this->twig->setLexer($lexer); +	} + +	/** +	* Sets the template filenames for handles. +	* +	* @param array $filename_array Should be a hash of handle => filename pairs. +	* @return phpbb_template $this +	*/ +	public function set_filenames(array $filename_array) +	{ +		$this->locator->set_filenames($filename_array); + +		return $this; +	} + +	/** +	* Sets the style names corresponding to style hierarchy being compiled +	* and/or rendered. +	* +	* @param array $style_names List of style names in inheritance tree order +	* @return phpbb_template $this +	*/ +	public function set_style_names(array $style_names, $style_paths = array()) +	{ +		$this->style_names = $style_names; + +		// Set as __main__ namespace +		$this->twig->getLoader()->setPaths($style_paths); + +		// Core style namespace from phpbb_style::set_style() +		if ($style_names === array($this->user->style['style_path']) || $style_names[0] == $this->user->style['style_path']) +		{ +			$this->twig->getLoader()->setPaths($style_paths, 'core'); + +			// Add all namespaces for all extensions +			if ($this->extension_manager instanceof phpbb_extension_manager) +			{ +				$style_names[] = 'all'; + +				foreach ($this->extension_manager->all_enabled() as $ext_namespace => $ext_path) +				{ +					foreach ($style_names as $style_name) +					{ +						if (is_dir($ext_path . 'styles/' . $style_name)) +						{ +							// namespaces cannot contain / +							$this->twig->getLoader()->addPath($ext_path . 'styles/' . $style_name . '/template', str_replace('/', '_', $ext_namespace)); +						} +					} +				} +			} +		} + +		return $this; +	} + +	/** +	* Clears all variables and blocks assigned to this template. +	* +	* @return phpbb_template $this +	*/ +	public function destroy() +	{ +		$this->context = array(); + +		return $this; +	} + +	/** +	* Reset/empty complete block +	* +	* @param string $blockname Name of block to destroy +	*/ +	public function destroy_block_vars($blockname) +	{ +		return $this->context->destroy_block_vars($blockname); +	} + +	/** +	* Display a template for provided handle. +	* +	* The template will be loaded and compiled, if necessary, first. +	* +	* This function calls hooks. +	* +	* @param string $handle Handle to display +	* @return bool True on success, false on failure +	*/ +	public function display($handle) +	{ +		$result = $this->call_hook($handle, __FUNCTION__); +		if ($result !== false) +		{ +			return $result[0]; +		} + +		try +		{ +			$this->twig->display($this->locator->get_filename_for_handle($handle), $this->get_template_vars()); +		} +		catch (Twig_Error $e) +		{ +			throw $e; +		} + +		return true; +	} + +	/** +	* Calls hook if any is defined. +	* +	* @param string $handle Template handle being displayed. +	* @param string $method Method name of the caller. +	*/ +	protected function call_hook($handle, $method) +	{ +		global $phpbb_hook; + +		if (!empty($phpbb_hook) && $phpbb_hook->call_hook(array(__CLASS__, $method), $handle, $this)) +		{ +			if ($phpbb_hook->hook_return(array(__CLASS__, $method))) +			{ +				$result = $phpbb_hook->hook_return_result(array(__CLASS__, $method)); +				return array($result); +			} +		} + +		return false; +	} + +	/** +	* Obtains language array. +	* This is either lang property of $user property, or if +	* it is not set an empty array. +	* @return array language entries +	*/ +	public function get_lang() +	{ +		if (isset($this->user->lang)) +		{ +			$lang = $this->user->lang; +		} +		else +		{ +			$lang = array(); +		} + +		return $lang; +	} + +	/** +	* Display the handle and assign the output to a template variable +	* or return the compiled result. +	* +	* @param string $handle Handle to operate on +	* @param string $template_var Template variable to assign compiled handle to +	* @param bool $return_content If true return compiled handle, otherwise assign to $template_var +	* @return bool|string false on failure, otherwise if $return_content is true return string of the compiled handle, otherwise return true +	*/ +	public function assign_display($handle, $template_var = '', $return_content = true) +	{ +		ob_start(); +		$result = $this->display($handle); +		$contents = ob_get_clean(); +		if ($result === false) +		{ +			return false; +		} + +		if ($return_content) +		{ +			return $contents; +		} + +		$this->assign_var($template_var, $contents); + +		return true; +	} + +	/** +	* Assign key variable pairs from an array +	* +	* @param array $vararray A hash of variable name => value pairs +	*/ +	public function assign_vars(array $vararray) +	{ +		foreach ($vararray as $key => $val) +		{ +			$this->assign_var($key, $val); +		} +	} + +	/** +	* Assign a single scalar value to a single key. +	* +	* Value can be a string, an integer or a boolean. +	* +	* @param string $varname Variable name +	* @param string $varval Value to assign to variable +	*/ +	public function assign_var($varname, $varval) +	{ +		return $this->context->assign_var($varname, $varval); +	} + +	/** +	* Append text to the string value stored in a key. +	* +	* Text is appended using the string concatenation operator (.). +	* +	* @param string $varname Variable name +	* @param string $varval Value to append to variable +	*/ +	public function append_var($varname, $varval) +	{ +		return $this->context->append_var($varname, $varval); +	} + +	// Docstring is copied from phpbb_template_context method with the same name. +	/** +	* Assign key variable pairs from an array to a specified block +	* @param string $blockname Name of block to assign $vararray to +	* @param array $vararray A hash of variable name => value pairs +	*/ +	public function assign_block_vars($blockname, array $vararray) +	{ +		return $this->context->assign_block_vars($blockname, $vararray); +	} + +	// Docstring is copied from phpbb_template_context method with the same name. +	/** +	* Change already assigned key variable pair (one-dimensional - single loop entry) +	* +	* An example of how to use this function: +	* {@example alter_block_array.php} +	* +	* @param	string	$blockname	the blockname, for example 'loop' +	* @param	array	$vararray	the var array to insert/add or merge +	* @param	mixed	$key		Key to search for +	* +	* array: KEY => VALUE [the key/value pair to search for within the loop to determine the correct position] +	* +	* int: Position [the position to change or insert at directly given] +	* +	* If key is false the position is set to 0 +	* If key is true the position is set to the last entry +	* +	* @param	string	$mode		Mode to execute (valid modes are 'insert' and 'change') +	* +	*	If insert, the vararray is inserted at the given position (position counting from zero). +	*	If change, the current block gets merged with the vararray (resulting in new key/value pairs be added and existing keys be replaced by the new value). +	* +	* Since counting begins by zero, inserting at the last position will result in this array: array(vararray, last positioned array) +	* and inserting at position 1 will result in this array: array(first positioned array, vararray, following vars) +	* +	* @return bool false on error, true on success +	*/ +	public function alter_block_array($blockname, array $vararray, $key = false, $mode = 'insert') +	{ +		return $this->context->alter_block_array($blockname, $vararray, $key, $mode); +	} + +	/** +	* Get template vars in a format Twig will use (from the context) +	* +	* @return array +	*/ +	protected function get_template_vars() +	{ +		$vars = array(); + +		// Work-around for now +		foreach ($this->user->lang as $key => $value) +		{ +			if (!is_string($value)) +			{ +				continue; +			} + +			$vars['L_' . strtoupper($key)] = $value; +			$vars['LA_' . strtoupper($key)] = addslashes($value); +		} + +		$vars = array_merge( +			$vars, +			$this->context->get_rootref(), +			array( +				'_phpbb_blocks'	=>  $this->context->get_tpldata(), +			) +		); + +		// Must do this so that <!-- IF .blah --> works correctly +		// (only for the base loops, the rest are properly handled by the begin node) +		foreach ($this->context->get_tpldata() as $block_name => $block_values) +		{ +			$vars[$block_name] = !empty($block_values); +		} + +		// cleanup +		unset($vars['_phpbb_blocks']['.']); + +		return $vars; +	} +} diff --git a/phpBB/install/index.php b/phpBB/install/index.php index f745f51974..e16109086d 100644 --- a/phpBB/install/index.php +++ b/phpBB/install/index.php @@ -214,7 +214,7 @@ $config = new phpbb_config(array(  $phpbb_style_resource_locator = new phpbb_style_resource_locator();  $phpbb_style_path_provider = new phpbb_style_path_provider(); -$template = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $phpbb_style_resource_locator, new phpbb_template_context()); +$template = new phpbb_template_twig($phpbb_root_path, $phpEx, $config, $user, $phpbb_style_resource_locator, new phpbb_template_context());  $phpbb_style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $phpbb_style_resource_locator, $phpbb_style_path_provider, $template);  $phpbb_style->set_ext_dir_prefix('adm/');  $phpbb_style->set_custom_style('admin', $phpbb_admin_path . 'style', array(), ''); diff --git a/phpBB/styles/prosilver/template/memberlist_search.html b/phpBB/styles/prosilver/template/memberlist_search.html index a4468b4af4..97769b6155 100644 --- a/phpBB/styles/prosilver/template/memberlist_search.html +++ b/phpBB/styles/prosilver/template/memberlist_search.html @@ -38,7 +38,7 @@ function insert_single(user)  // ]]>  </script>  <!-- ENDIF --> -<!-- INCLUDEJS template/forum_fn.js --> +<!-- INCLUDEJS T_TEMPLATE_PATH ~ '/forum_fn.js' -->  <h2 class="solo">{L_FIND_USERNAME}</h2>  <form method="post" action="{S_MODE_ACTION}" id="search_memberlist"> diff --git a/phpBB/styles/prosilver/template/overall_footer.html b/phpBB/styles/prosilver/template/overall_footer.html index ba0412ddd3..01fc3f83da 100644 --- a/phpBB/styles/prosilver/template/overall_footer.html +++ b/phpBB/styles/prosilver/template/overall_footer.html @@ -55,7 +55,7 @@  <!-- IF S_JQUERY_FALLBACK --><script type="text/javascript">window.jQuery || document.write(unescape('%3Cscript src="{T_ASSETS_PATH}/javascript/jquery.js?assets_version={T_ASSETS_VERSION}" type="text/javascript"%3E%3C/script%3E'));</script><!-- ENDIF -->  <script type="text/javascript" src="{T_SUPER_TEMPLATE_PATH}/forum_fn.js?assets_version={T_ASSETS_VERSION}"></script>  <script type="text/javascript" src="{T_ASSETS_PATH}/javascript/core.js?assets_version={T_ASSETS_VERSION}"></script> -<!-- INCLUDEJS template/ajax.js --> +<!-- INCLUDEJS T_TEMPLATE_PATH ~ '/ajax.js' -->  {SCRIPTS}  <!-- EVENT overall_footer_after --> diff --git a/phpBB/styles/prosilver/template/posting_buttons.html b/phpBB/styles/prosilver/template/posting_buttons.html index fadbc9b3ca..b3e2b85492 100644 --- a/phpBB/styles/prosilver/template/posting_buttons.html +++ b/phpBB/styles/prosilver/template/posting_buttons.html @@ -39,7 +39,7 @@  	{  		dE('colour_palette');  		e = document.getElementById('colour_palette'); -		 +  		if (e.style.display == 'block')  		{  			document.getElementById('bbpalette').value = '{LA_FONT_COLOR_HIDE}'; @@ -52,7 +52,7 @@  // ]]>  </script> -<!-- INCLUDEJS template/editor.js --> +<!-- INCLUDEJS T_TEMPLATE_PATH ~ '/editor.js' -->  <!-- IF S_BBCODE_ALLOWED -->  <div id="colour_palette" style="display: none;"> diff --git a/phpBB/styles/prosilver/template/timezone_option.html b/phpBB/styles/prosilver/template/timezone_option.html index a77e82f9a1..95b30dbcd1 100644 --- a/phpBB/styles/prosilver/template/timezone_option.html +++ b/phpBB/styles/prosilver/template/timezone_option.html @@ -15,6 +15,6 @@  			{S_TZ_OPTIONS}  		</select> -		<!-- INCLUDEJS template/timezone.js --> +		<!-- INCLUDEJS T_TEMPLATE_PATH ~ '/timezone.js' -->  	</dd>  </dl> diff --git a/phpBB/styles/prosilver/template/ucp_avatar_options.html b/phpBB/styles/prosilver/template/ucp_avatar_options.html index e7f4a48e11..4f4aef3ff9 100644 --- a/phpBB/styles/prosilver/template/ucp_avatar_options.html +++ b/phpBB/styles/prosilver/template/ucp_avatar_options.html @@ -47,4 +47,4 @@  	</div>  </div> -<!-- INCLUDEJS template/avatars.js --> +<!-- INCLUDEJS T_TEMPLATE_PATH ~ '/avatars.js' --> diff --git a/phpBB/styles/subsilver2/template/timezone_option.html b/phpBB/styles/subsilver2/template/timezone_option.html index 26ba2388c9..d71166f517 100644 --- a/phpBB/styles/subsilver2/template/timezone_option.html +++ b/phpBB/styles/subsilver2/template/timezone_option.html @@ -15,6 +15,6 @@  			{S_TZ_OPTIONS}  		</select> -		<!-- INCLUDEJS template/timezone.js --> +		<!-- INCLUDEJS T_TEMPLATE_PATH ~ '/timezone.js' -->  	</td>  </tr> diff --git a/phpBB/styles/subsilver2/template/ucp_groups_manage.html b/phpBB/styles/subsilver2/template/ucp_groups_manage.html index 8064e1e6e9..5595d19b9e 100644 --- a/phpBB/styles/subsilver2/template/ucp_groups_manage.html +++ b/phpBB/styles/subsilver2/template/ucp_groups_manage.html @@ -95,7 +95,7 @@  	</tr>  	</table> -<!-- INCLUDEJS template/avatars.js --> +<!-- INCLUDEJS T_TEMPLATE_PATH ~ '/avatars.js' -->  <!-- ELSEIF S_LIST --> diff --git a/phpBB/styles/subsilver2/template/ucp_profile_avatar.html b/phpBB/styles/subsilver2/template/ucp_profile_avatar.html index 697cceabb9..58ef499c41 100644 --- a/phpBB/styles/subsilver2/template/ucp_profile_avatar.html +++ b/phpBB/styles/subsilver2/template/ucp_profile_avatar.html @@ -48,6 +48,6 @@  	</tr>  </table> -<!-- INCLUDEJS template/avatars.js --> +<!-- INCLUDEJS T_TEMPLATE_PATH ~ '/avatars.js' -->  <!-- INCLUDE ucp_footer.html --> diff --git a/tests/controller/helper_url_test.php b/tests/controller/helper_url_test.php index 2c22700ca6..42c416b1d2 100644 --- a/tests/controller/helper_url_test.php +++ b/tests/controller/helper_url_test.php @@ -45,12 +45,12 @@ class phpbb_controller_helper_url_test extends phpbb_test_case  	*/  	public function test_helper_url($route, $params, $is_amp, $session_id, $expected, $description)  	{ -		global $phpbb_dispatcher; +		global $phpbb_dispatcher, $phpbb_root_path, $phpEx;  		$phpbb_dispatcher = new phpbb_mock_event_dispatcher;  		$this->style_resource_locator = new phpbb_style_resource_locator();  		$this->user = $this->getMock('phpbb_user'); -		$this->template = new phpbb_template($phpbb_root_path, $phpEx, $config, $this->user, $this->style_resource_locator, new phpbb_template_context()); +		$this->template = new phpbb_template_twig($phpbb_root_path, $phpEx, $config, $this->user, $this->style_resource_locator, new phpbb_template_context());  		$helper = new phpbb_controller_helper($this->template, $this->user, '', 'php');  		$this->assertEquals($helper->url($route, $params, $is_amp, $session_id), $expected); diff --git a/tests/extension/metadata_manager_test.php b/tests/extension/metadata_manager_test.php index d410333f09..9dfb45b38e 100644 --- a/tests/extension/metadata_manager_test.php +++ b/tests/extension/metadata_manager_test.php @@ -42,7 +42,7 @@ class phpbb_extension_metadata_manager_test extends phpbb_database_test_case  		$this->user = new phpbb_user();  		$this->table_prefix = 'phpbb_'; -		$this->template = new phpbb_template( +		$this->template = new phpbb_template_twig(  			$this->phpbb_root_path,  			$this->phpEx,  			$this->config, diff --git a/tests/template/template_events_test.php b/tests/template/template_events_test.php index 0ac50c7f2b..571e55e04e 100644 --- a/tests/template/template_events_test.php +++ b/tests/template/template_events_test.php @@ -111,7 +111,7 @@ Kappa test event in silver_inherit',  		$this->extension_manager = new phpbb_mock_filesystem_extension_manager(  			dirname(__FILE__) . "/datasets/$dataset/"  		); -		$this->template = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator, new phpbb_template_context, $this->extension_manager); +		$this->template = new phpbb_template_twig($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator, new phpbb_template_context, $this->extension_manager);  		$this->style_provider = new phpbb_style_path_provider();  		$this->style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator, $this->style_provider, $this->template);  		$this->style->set_custom_style('silver', array($this->template_path), $style_names, ''); diff --git a/tests/template/template_spacing_test.php b/tests/template/template_spacing_test.php index 83f8711b38..b0f44bc827 100644 --- a/tests/template/template_spacing_test.php +++ b/tests/template/template_spacing_test.php @@ -79,7 +79,7 @@ class phpbb_template_template_spacing_test extends phpbb_template_template_test_  		$this->extension_manager = new phpbb_mock_filesystem_extension_manager(  			dirname(__FILE__) . "/datasets/$dataset/"  		); -		$this->template = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator, new phpbb_template_context, $this->extension_manager); +		$this->template = new phpbb_template_twig($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator, new phpbb_template_context, $this->extension_manager);  		$this->style_provider = new phpbb_style_path_provider();  		$this->style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator, $this->style_provider, $this->template);  		$this->style->set_custom_style('silver', array($this->template_path), $style_names, ''); diff --git a/tests/template/template_test_case.php b/tests/template/template_test_case.php index 3c997cb00e..e39896b970 100644 --- a/tests/template/template_test_case.php +++ b/tests/template/template_test_case.php @@ -67,7 +67,7 @@ class phpbb_template_template_test_case extends phpbb_test_case  		$this->template_path = $this->test_path . '/templates';  		$this->style_resource_locator = new phpbb_style_resource_locator();  		$this->style_provider = new phpbb_style_path_provider(); -		$this->template = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator, new phpbb_template_context()); +		$this->template = new phpbb_template_twig($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator, new phpbb_template_context());  		$this->style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator, $this->style_provider, $this->template);  		$this->style->set_custom_style('tests', $this->template_path, array(), '');  	} diff --git a/tests/template/template_test_case_with_tree.php b/tests/template/template_test_case_with_tree.php index 7585be5728..e9862bcecc 100644 --- a/tests/template/template_test_case_with_tree.php +++ b/tests/template/template_test_case_with_tree.php @@ -22,7 +22,7 @@ class phpbb_template_template_test_case_with_tree extends phpbb_template_templat  		$this->parent_template_path = $this->test_path . '/parent_templates';  		$this->style_resource_locator = new phpbb_style_resource_locator();  		$this->style_provider = new phpbb_style_path_provider(); -		$this->template = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator, new phpbb_template_context()); +		$this->template = new phpbb_template_twig($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator, new phpbb_template_context());  		$this->style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator, $this->style_provider, $this->template);  		$this->style->set_custom_style('tests', array($this->template_path, $this->parent_template_path), array(), '');  	}  | 
