From 7ea0019a7167561b029ea727cf8be2e8f490dda7 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Sun, 9 Jun 2013 17:45:29 -0500 Subject: [PATCH 001/156] [feature/twig] Adding Twig dependency to composer.json PHPBB3-11598 --- phpBB/composer.json | 3 +- phpBB/composer.lock | 958 +++++--------------------------------------- 2 files changed, 110 insertions(+), 851 deletions(-) diff --git a/phpBB/composer.json b/phpBB/composer.json index abc1df57b7..c31d721301 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.*" }, "require-dev": { "fabpot/goutte": "v0.1.0", diff --git a/phpBB/composer.lock b/phpBB/composer.lock index e3b564fb1a..75b9c360f0 100644 --- a/phpBB/composer.lock +++ b/phpBB/composer.lock @@ -1,35 +1,32 @@ { - "_readme": [ - "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": "bd651ccd1316ecdc6d72a22357d8c46f", "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": { "php": ">=5.3.3" }, + "time": "2013-05-09 15:22:40", "type": "library", + "installation-source": "dist", "autoload": { "psr-0": { "Symfony\\Component\\Config": "" } }, - "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -44,42 +41,42 @@ } ], "description": "Symfony Config Component", - "homepage": "http://symfony.com", - "time": "2013-04-22 04:28:40" + "homepage": "http://symfony.com" }, { "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": { "php": ">=5.3.3" }, "require-dev": { - "symfony/config": "2.1.*", - "symfony/yaml": "2.1.*" + "symfony/yaml": "2.1.*", + "symfony/config": "2.1.*" }, "suggest": { - "symfony/config": "2.1.*", - "symfony/yaml": "2.1.*" + "symfony/yaml": "2.1.*", + "symfony/config": "2.1.*" }, + "time": "2013-05-03 05:08:13", "type": "library", + "installation-source": "dist", "autoload": { "psr-0": { "Symfony\\Component\\DependencyInjection": "" } }, - "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -94,22 +91,21 @@ } ], "description": "Symfony DependencyInjection Component", - "homepage": "http://symfony.com", - "time": "2013-05-03 05:08:13" + "homepage": "http://symfony.com" }, { "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": { @@ -122,13 +118,14 @@ "symfony/dependency-injection": "2.1.*", "symfony/http-kernel": "2.1.*" }, + "time": "2013-02-11 11:26:14", "type": "library", + "installation-source": "dist", "autoload": { "psr-0": { "Symfony\\Component\\EventDispatcher": "" } }, - "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -143,35 +140,35 @@ } ], "description": "Symfony EventDispatcher Component", - "homepage": "http://symfony.com", - "time": "2013-02-11 11:26:14" + "homepage": "http://symfony.com" }, { "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": { "php": ">=5.3.3" }, + "time": "2013-05-26 18:42:07", "type": "library", + "installation-source": "dist", "autoload": { "psr-0": { "Symfony\\Component\\HttpFoundation": "", "SessionHandlerInterface": "Symfony/Component/HttpFoundation/Resources/stubs" } }, - "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -186,22 +183,21 @@ } ], "description": "Symfony HttpFoundation Component", - "homepage": "http://symfony.com", - "time": "2013-04-30 17:01:33" + "homepage": "http://symfony.com" }, { "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": { @@ -227,13 +223,14 @@ "symfony/dependency-injection": "2.1.*", "symfony/finder": "2.1.*" }, + "time": "2013-06-02 12:29:05", "type": "library", + "installation-source": "dist", "autoload": { "psr-0": { "Symfony\\Component\\HttpKernel": "" } }, - "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -248,45 +245,45 @@ } ], "description": "Symfony HttpKernel Component", - "homepage": "http://symfony.com", - "time": "2013-05-06 11:01:51" + "homepage": "http://symfony.com" }, { "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": { "php": ">=5.3.3" }, "require-dev": { - "doctrine/common": ">=2.2,<3.0", "symfony/config": "2.1.*", + "symfony/yaml": "2.1.*", "symfony/http-kernel": "2.1.*", - "symfony/yaml": "2.1.*" + "doctrine/common": ">=2.2,<3.0" }, "suggest": { - "doctrine/common": "~2.2", "symfony/config": "2.1.*", - "symfony/yaml": "2.1.*" + "symfony/yaml": "2.1.*", + "doctrine/common": "~2.2" }, + "time": "2013-05-06 10:48:41", "type": "library", + "installation-source": "dist", "autoload": { "psr-0": { "Symfony\\Component\\Routing": "" } }, - "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -301,34 +298,34 @@ } ], "description": "Symfony Routing Component", - "homepage": "http://symfony.com", - "time": "2013-03-23 07:47:35" + "homepage": "http://symfony.com" }, { "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": { "php": ">=5.3.3" }, + "time": "2013-05-10 00:09:46", "type": "library", + "installation-source": "dist", "autoload": { "psr-0": { "Symfony\\Component\\Yaml": "" } }, - "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -343,803 +340,64 @@ } ], "description": "Symfony Yaml Component", - "homepage": "http://symfony.com", - "time": "2013-03-23 01:54:33" - } - ], - "packages-dev": [ - { - "name": "fabpot/goutte", - "version": "v0.1.0", - "source": { - "type": "git", - "url": "https://github.com/fabpot/Goutte", - "reference": "v0.1.0" - }, - "dist": { - "type": "zip", - "url": "https://github.com/fabpot/Goutte/archive/v0.1.0.zip", - "reference": "v0.1.0", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "guzzle/guzzle": "3.0.*", - "php": ">=5.3.0", - "symfony/browser-kit": "2.1.*", - "symfony/css-selector": "2.1.*", - "symfony/dom-crawler": "2.1.*", - "symfony/finder": "2.1.*", - "symfony/process": "2.1.*" - }, - "type": "application", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "psr-0": { - "Goutte": "." - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - } - ], - "description": "A simple PHP Web Scraper", - "homepage": "https://github.com/fabpot/Goutte", - "keywords": [ - "scraper" - ], - "time": "2012-12-02 13:44:35" - }, - { - "name": "guzzle/guzzle", - "version": "v3.0.7", - "source": { - "type": "git", - "url": "https://github.com/guzzle/guzzle", - "reference": "v3.0.7" - }, - "dist": { - "type": "zip", - "url": "https://github.com/guzzle/guzzle/archive/v3.0.7.zip", - "reference": "v3.0.7", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "php": ">=5.3.2", - "symfony/event-dispatcher": ">=2.1" - }, - "replace": { - "guzzle/batch": "self.version", - "guzzle/cache": "self.version", - "guzzle/common": "self.version", - "guzzle/http": "self.version", - "guzzle/inflection": "self.version", - "guzzle/iterator": "self.version", - "guzzle/log": "self.version", - "guzzle/parser": "self.version", - "guzzle/plugin": "self.version", - "guzzle/plugin-async": "self.version", - "guzzle/plugin-backoff": "self.version", - "guzzle/plugin-cache": "self.version", - "guzzle/plugin-cookie": "self.version", - "guzzle/plugin-curlauth": "self.version", - "guzzle/plugin-history": "self.version", - "guzzle/plugin-log": "self.version", - "guzzle/plugin-md5": "self.version", - "guzzle/plugin-mock": "self.version", - "guzzle/plugin-oauth": "self.version", - "guzzle/service": "self.version", - "guzzle/stream": "self.version" - }, - "require-dev": { - "doctrine/common": "*", - "monolog/monolog": "1.*", - "phpunit/phpunit": "3.7.*", - "symfony/class-loader": "*", - "zend/zend-cache1": "1.12", - "zend/zend-log1": "1.12", - "zendframework/zend-cache": "2.0.*", - "zendframework/zend-log": "2.0.*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-0": { - "Guzzle\\Tests": "tests/", - "Guzzle": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "Guzzle Community", - "homepage": "https://github.com/guzzle/guzzle/contributors" - } - ], - "description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients", - "homepage": "http://guzzlephp.org/", - "keywords": [ - "client", - "curl", - "framework", - "http", - "http client", - "rest", - "web service" - ], - "time": "2012-12-19 23:06:35" - }, - { - "name": "phpunit/dbunit", - "version": "1.2.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/dbunit.git", - "reference": "1.2.3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/dbunit/zipball/1.2.3", - "reference": "1.2.3", - "shasum": "" - }, - "require": { - "ext-pdo": "*", - "ext-simplexml": "*", - "php": ">=5.3.3", - "phpunit/phpunit": ">=3.7.0@stable" - }, - "bin": [ - "dbunit.php" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, - "autoload": { - "classmap": [ - "PHPUnit/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "", - "../../symfony/yaml/" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "DbUnit port for PHP/PHPUnit to support database interaction testing.", - "homepage": "https://github.com/sebastianbergmann/dbunit/", - "keywords": [ - "database", - "testing", - "xunit" - ], - "time": "2013-03-01 11:50:46" - }, - { - "name": "phpunit/php-code-coverage", - "version": "1.2.9", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "1.2.9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/1.2.9", - "reference": "1.2.9", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "phpunit/php-file-iterator": ">=1.3.0@stable", - "phpunit/php-text-template": ">=1.1.1@stable", - "phpunit/php-token-stream": ">=1.1.3@stable" - }, - "suggest": { - "ext-dom": "*", - "ext-xdebug": ">=2.0.5" - }, - "type": "library", - "autoload": { - "classmap": [ - "PHP/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ], - "time": "2013-02-26 18:55:56" - }, - { - "name": "phpunit/php-file-iterator", - "version": "1.3.3", - "source": { - "type": "git", - "url": "git://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "1.3.3" - }, - "dist": { - "type": "zip", - "url": "https://github.com/sebastianbergmann/php-file-iterator/zipball/1.3.3", - "reference": "1.3.3", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "File/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "http://www.phpunit.de/", - "keywords": [ - "filesystem", - "iterator" - ], - "time": "2012-10-11 04:44:38" - }, - { - "name": "phpunit/php-text-template", - "version": "1.1.4", - "source": { - "type": "git", - "url": "git://github.com/sebastianbergmann/php-text-template.git", - "reference": "1.1.4" - }, - "dist": { - "type": "zip", - "url": "https://github.com/sebastianbergmann/php-text-template/zipball/1.1.4", - "reference": "1.1.4", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "Text/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "time": "2012-10-31 11:15:28" - }, - { - "name": "phpunit/php-timer", - "version": "1.0.4", - "source": { - "type": "git", - "url": "git://github.com/sebastianbergmann/php-timer.git", - "reference": "1.0.4" - }, - "dist": { - "type": "zip", - "url": "https://github.com/sebastianbergmann/php-timer/zipball/1.0.4", - "reference": "1.0.4", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "PHP/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Utility class for timing", - "homepage": "http://www.phpunit.de/", - "keywords": [ - "timer" - ], - "time": "2012-10-11 04:45:58" - }, - { - "name": "phpunit/php-token-stream", - "version": "1.1.5", - "source": { - "type": "git", - "url": "git://github.com/sebastianbergmann/php-token-stream.git", - "reference": "1.1.5" - }, - "dist": { - "type": "zip", - "url": "https://github.com/sebastianbergmann/php-token-stream/zipball/1.1.5", - "reference": "1.1.5", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "PHP/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "http://www.phpunit.de/", - "keywords": [ - "tokenizer" - ], - "time": "2012-10-11 04:47:14" - }, - { - "name": "phpunit/phpunit", - "version": "3.7.19", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "3.7.19" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3.7.19", - "reference": "3.7.19", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-pcre": "*", - "ext-reflection": "*", - "ext-spl": "*", - "php": ">=5.3.3", - "phpunit/php-code-coverage": ">=1.2.1,<1.3.0", - "phpunit/php-file-iterator": ">=1.3.1", - "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" - }, - "require-dev": { - "pear-pear/pear": "1.9.4" - }, - "suggest": { - "ext-json": "*", - "ext-simplexml": "*", - "ext-tokenizer": "*", - "phpunit/php-invoker": ">=1.1.0,<1.2.0" - }, - "bin": [ - "composer/bin/phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.7.x-dev" - } - }, - "autoload": { - "classmap": [ - "PHPUnit/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "", - "../../symfony/yaml/" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "http://www.phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "time": "2013-03-25 11:45:06" - }, - { - "name": "phpunit/phpunit-mock-objects", - "version": "1.2.3", - "source": { - "type": "git", - "url": "git://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "1.2.3" - }, - "dist": { - "type": "zip", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects/archive/1.2.3.zip", - "reference": "1.2.3", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "phpunit/php-text-template": ">=1.1.1@stable" - }, - "suggest": { - "ext-soap": "*" - }, - "type": "library", - "autoload": { - "classmap": [ - "PHPUnit/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Mock Object library for PHPUnit", - "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", - "keywords": [ - "mock", - "xunit" - ], - "time": "2013-01-13 10:24:48" - }, - { - "name": "symfony/browser-kit", - "version": "v2.1.10", - "target-dir": "Symfony/Component/BrowserKit", - "source": { - "type": "git", - "url": "https://github.com/symfony/BrowserKit.git", - "reference": "v2.1.10" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/BrowserKit/zipball/v2.1.10", - "reference": "v2.1.10", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "symfony/dom-crawler": "2.1.*" - }, - "require-dev": { - "symfony/css-selector": "2.1.*", - "symfony/process": "2.1.*" - }, - "suggest": { - "symfony/process": "2.1.*" - }, - "type": "library", - "autoload": { - "psr-0": { - "Symfony\\Component\\BrowserKit": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony BrowserKit Component", - "homepage": "http://symfony.com", - "time": "2013-04-29 20:22:06" - }, - { - "name": "symfony/css-selector", - "version": "v2.1.10", - "target-dir": "Symfony/Component/CssSelector", - "source": { - "type": "git", - "url": "https://github.com/symfony/CssSelector.git", - "reference": "v2.1.10" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/CssSelector/zipball/v2.1.10", - "reference": "v2.1.10", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "psr-0": { - "Symfony\\Component\\CssSelector": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony CssSelector Component", - "homepage": "http://symfony.com", - "time": "2013-01-09 08:51:07" - }, - { - "name": "symfony/dom-crawler", - "version": "v2.1.10", - "target-dir": "Symfony/Component/DomCrawler", - "source": { - "type": "git", - "url": "https://github.com/symfony/DomCrawler.git", - "reference": "v2.1.10" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/DomCrawler/zipball/v2.1.10", - "reference": "v2.1.10", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "symfony/css-selector": "2.1.*" - }, - "suggest": { - "symfony/css-selector": "2.1.*" - }, - "type": "library", - "autoload": { - "psr-0": { - "Symfony\\Component\\DomCrawler": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony DomCrawler Component", - "homepage": "http://symfony.com", - "time": "2013-03-27 17:13:16" - }, - { - "name": "symfony/finder", - "version": "v2.1.10", - "target-dir": "Symfony/Component/Finder", - "source": { - "type": "git", - "url": "https://github.com/symfony/Finder.git", - "reference": "v2.1.10" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Finder/zipball/v2.1.10", - "reference": "v2.1.10", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "psr-0": { - "Symfony\\Component\\Finder": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony Finder Component", - "homepage": "http://symfony.com", - "time": "2013-03-06 19:26:55" - }, - { - "name": "symfony/process", - "version": "v2.1.9", - "target-dir": "Symfony/Component/Process", - "source": { - "type": "git", - "url": "https://github.com/symfony/Process.git", - "reference": "v2.1.9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Process/zipball/v2.1.9", - "reference": "v2.1.9", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "psr-0": { - "Symfony\\Component\\Process": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony Process Component", - "homepage": "http://symfony.com", - "time": "2013-03-23 07:44:01" + "homepage": "http://symfony.com" + }, + { + "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" + }, + "time": "2013-06-06 06:06:01", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.13-dev" + } + }, + "installation-source": "dist", + "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" + ] } ], + "packages-dev": null, "aliases": [ ], "minimum-stability": "beta", "stability-flags": [ - ], - "platform": [ - - ], - "platform-dev": [ - ] } From 1da4be04b021af62e24f91bf0f82849c78bd04b9 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Sun, 9 Jun 2013 22:09:00 -0500 Subject: [PATCH 002/156] [feature/twig] WIP extension/lexer/some tokenparsers/nodes PHPBB3-11598 --- phpBB/includes/template/twig/extension.php | 45 +++++++++ phpBB/includes/template/twig/lexer.php | 42 +++++++++ phpBB/includes/template/twig/node/begin.php | 77 +++++++++++++++ .../template/twig/tokenparser/begin.php | 71 ++++++++++++++ .../template/twig/tokenparser/event.php | 33 +++++++ .../includes/template/twig/tokenparser/if.php | 94 +++++++++++++++++++ .../template/twig/tokenparser/include.php | 33 +++++++ 7 files changed, 395 insertions(+) create mode 100644 phpBB/includes/template/twig/extension.php create mode 100644 phpBB/includes/template/twig/lexer.php create mode 100644 phpBB/includes/template/twig/node/begin.php create mode 100644 phpBB/includes/template/twig/tokenparser/begin.php create mode 100644 phpBB/includes/template/twig/tokenparser/event.php create mode 100644 phpBB/includes/template/twig/tokenparser/if.php create mode 100644 phpBB/includes/template/twig/tokenparser/include.php diff --git a/phpBB/includes/template/twig/extension.php b/phpBB/includes/template/twig/extension.php new file mode 100644 index 0000000000..29020fcf8e --- /dev/null +++ b/phpBB/includes/template/twig/extension.php @@ -0,0 +1,45 @@ + array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Equal', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + '!==' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotEqual', '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..45b97acf8c --- /dev/null +++ b/phpBB/includes/template/twig/lexer.php @@ -0,0 +1,42 @@ + + * + * This does not seem very efficient, but I have not been able to find a better + * method which works properly (maybe lexData can do it better, @todo test this) + */ + $last_element = end($this->tokens); + if ($last_element->getValue() === '.') + { + $last_element2 = prev($this->tokens); + + if ($last_element2->getValue() === 'IF') + { + array_pop($this->tokens); + } + } + + parent::lexExpression(); + } +} diff --git a/phpBB/includes/template/twig/node/begin.php b/phpBB/includes/template/twig/node/begin.php new file mode 100644 index 0000000000..1d47e35d87 --- /dev/null +++ b/phpBB/includes/template/twig/node/begin.php @@ -0,0 +1,77 @@ + + */ +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(\$blocks)) {\n") + ->indent() + ->write("\$blocks = array();") + ->write("\$nestingLevel = 0;") + ->outdent() + ->write("}\n") + ->write("\$blocks[\$nestingLevel] = array();\n") + ; + + if (null !== $this->getNode('else')) { + $compiler->write("\$blocks[\$nestingLevel]['iterated'] = false;\n"); + } + + $compiler + ->write("foreach (\$context['_phpbb_blocks']['") + ->write($this->getAttribute('beginName')) + ->write("'] as \$blocks[\$nestingLevel]['i'] => \$blocks[\$nestingLevel]['values']) {") + ->indent() + ; + + $compiler->subcompile($this->getNode('body')); + + if (null !== $this->getNode('else')) { + $compiler->write("\$blocks[\$nestingLevel]['iterated'] = true;\n"); + } + + $compiler + ->outdent() + ->write("}\n") + ; + + if (null !== $this->getNode('else')) { + $compiler + ->write("if (!\$blocks[\$nestingLevel]['iterated']) {\n") + ->indent() + ->subcompile($this->getNode('else')) + ->outdent() + ->write("}\n") + ; + } + + $compiler->write("\$nestingLevel--;\n"); + } +} \ No newline at end of file diff --git a/phpBB/includes/template/twig/tokenparser/begin.php b/phpBB/includes/template/twig/tokenparser/begin.php new file mode 100644 index 0000000000..939f3b8f16 --- /dev/null +++ b/phpBB/includes/template/twig/tokenparser/begin.php @@ -0,0 +1,71 @@ + + * + * + */ +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() == 'ELSE') { + $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 decideForEnd(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/event.php b/phpBB/includes/template/twig/tokenparser/event.php new file mode 100644 index 0000000000..cd211098d6 --- /dev/null +++ b/phpBB/includes/template/twig/tokenparser/event.php @@ -0,0 +1,33 @@ + + * {% include 'header.html' %} + * Body + * {% include 'footer.html' %} + * + */ +class phpbb_template_twig_tokenparser_event extends Twig_TokenParser_Include +{ + /** + * 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..e47744093e --- /dev/null +++ b/phpBB/includes/template/twig/tokenparser/if.php @@ -0,0 +1,94 @@ + + * {% if users %} + * + * {% endif %} + * + */ +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..d9421095d1 --- /dev/null +++ b/phpBB/includes/template/twig/tokenparser/include.php @@ -0,0 +1,33 @@ + + * {% include 'header.html' %} + * Body + * {% include 'footer.html' %} + * + */ +class phpbb_template_twig_tokenparser_include extends Twig_TokenParser_Include +{ + /** + * Gets the tag name associated with this token parser. + * + * @return string The tag name + */ + public function getTag() + { + return 'INCLUDE'; + } +} From 87cc8af26565dc1547383aa8c969cc5be48f0944 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Sun, 9 Jun 2013 23:32:39 -0500 Subject: [PATCH 003/156] [feature/twig] Support our old INCLUDE statements (no quotes) Better code for handling IF .blah PHPBB3-11598 --- phpBB/includes/template/twig/lexer.php | 36 ++++++++++++++++---------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/phpBB/includes/template/twig/lexer.php b/phpBB/includes/template/twig/lexer.php index 45b97acf8c..70a21307ec 100644 --- a/phpBB/includes/template/twig/lexer.php +++ b/phpBB/includes/template/twig/lexer.php @@ -19,24 +19,34 @@ class phpbb_template_twig_lexer extends Twig_Lexer { protected function lexExpression() { + parent::lexExpression(); + + // Last element parsed + $last_element = end($this->tokens); + + /** + * Check for old fashioned INCLUDE statements without enclosed quotes + */ + if ($last_element->getValue() === 'INCLUDE') + { + if (preg_match('#^\s*([a-zA-Z0-9_]+\.[a-zA-Z0-9]+)#', substr($this->code, $this->cursor), $match)) + { + $this->pushToken(Twig_Token::STRING_TYPE, stripcslashes($match[1])); + $this->moveCursor($match[0]); + } + } + /** * This is some compatibility code to continue supporting expressions such as: * - * - * This does not seem very efficient, but I have not been able to find a better - * method which works properly (maybe lexData can do it better, @todo test this) */ - $last_element = end($this->tokens); - if ($last_element->getValue() === '.') + if ($last_element->getValue() === 'IF') { - $last_element2 = prev($this->tokens); - - if ($last_element2->getValue() === 'IF') - { - array_pop($this->tokens); - } + if (preg_match('#^\s*\.([a-zA-Z0-9\.]+)#', substr($this->code, $this->cursor), $match)) + { + $this->pushToken(Twig_Token::STRING_TYPE, stripcslashes($match[1])); + $this->moveCursor($match[0]); + } } - - parent::lexExpression(); } } From 9f8f500ba33963a28c656af8a28a9a6521af4616 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Mon, 10 Jun 2013 00:59:06 -0500 Subject: [PATCH 004/156] [feature/twig] Working on DEFINE PHPBB3-11598 --- phpBB/includes/template/twig/extension.php | 1 + phpBB/includes/template/twig/lexer.php | 15 ++++++- .../template/twig/tokenparser/define.php | 45 +++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 phpBB/includes/template/twig/tokenparser/define.php diff --git a/phpBB/includes/template/twig/extension.php b/phpBB/includes/template/twig/extension.php index 29020fcf8e..bf4b0e8c54 100644 --- a/phpBB/includes/template/twig/extension.php +++ b/phpBB/includes/template/twig/extension.php @@ -29,6 +29,7 @@ class phpbb_template_twig_extension extends Twig_Extension new phpbb_template_twig_tokenparser_include, new phpbb_template_twig_tokenparser_event, new phpbb_template_twig_tokenparser_begin, + new phpbb_template_twig_tokenparser_define, ); } diff --git a/phpBB/includes/template/twig/lexer.php b/phpBB/includes/template/twig/lexer.php index 70a21307ec..f60c58249c 100644 --- a/phpBB/includes/template/twig/lexer.php +++ b/phpBB/includes/template/twig/lexer.php @@ -42,11 +42,24 @@ class phpbb_template_twig_lexer extends Twig_Lexer */ if ($last_element->getValue() === 'IF') { - if (preg_match('#^\s*\.([a-zA-Z0-9\.]+)#', substr($this->code, $this->cursor), $match)) + if (preg_match('#^\s*\.([a-zA-Z0-9_\.]+)#', substr($this->code, $this->cursor), $match)) { $this->pushToken(Twig_Token::STRING_TYPE, stripcslashes($match[1])); $this->moveCursor($match[0]); } } + + /** + * This is some compatibility code to continue supporting expressions such as: + * + */ + if ($last_element->getValue() === 'DEFINE') + { + if (preg_match('#^\s*\$([A-Z0-9]+)#', substr($this->code, $this->cursor), $match)) + { + $this->pushToken(Twig_Token::STRING_TYPE, stripcslashes($match[1])); + $this->moveCursor($match[1]); + } + } } } diff --git a/phpBB/includes/template/twig/tokenparser/define.php b/phpBB/includes/template/twig/tokenparser/define.php new file mode 100644 index 0000000000..8eb33c7ff9 --- /dev/null +++ b/phpBB/includes/template/twig/tokenparser/define.php @@ -0,0 +1,45 @@ + + * {% set foo = 'foo' %} + * + * {% set foo = [1, 2] %} + * + * {% set foo = {'foo': 'bar'} %} + * + * {% set foo = 'foo' ~ 'bar' %} + * + * {% set foo, bar = 'foo', 'bar' %} + * + * {% set foo %}Some content{% endset %} + * + */ +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'; + } +} From b775f67128c1c851a2e3343b230d2861e5431528 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Mon, 10 Jun 2013 10:00:22 -0500 Subject: [PATCH 005/156] [feature/twig] More work on the lexer Committing what I have now to save it as I'm trying another method next PHPBB3-11598 --- phpBB/includes/template/twig/extension.php | 1 + phpBB/includes/template/twig/lexer.php | 17 +++++++++++-- .../template/twig/tokenparser/event.php | 25 +++++++++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/template/twig/extension.php b/phpBB/includes/template/twig/extension.php index bf4b0e8c54..a607bac150 100644 --- a/phpBB/includes/template/twig/extension.php +++ b/phpBB/includes/template/twig/extension.php @@ -39,6 +39,7 @@ class phpbb_template_twig_extension extends Twig_Extension array(), array( 'eq' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Equal', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + //'and' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_And', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), '!==' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), ), ); diff --git a/phpBB/includes/template/twig/lexer.php b/phpBB/includes/template/twig/lexer.php index f60c58249c..21d8fb770e 100644 --- a/phpBB/includes/template/twig/lexer.php +++ b/phpBB/includes/template/twig/lexer.php @@ -19,11 +19,12 @@ class phpbb_template_twig_lexer extends Twig_Lexer { protected function lexExpression() { + var_dump(substr($this->code, $this->cursor, 40), $this->states); parent::lexExpression(); // Last element parsed $last_element = end($this->tokens); - + /** * Check for old fashioned INCLUDE statements without enclosed quotes */ @@ -42,7 +43,7 @@ class phpbb_template_twig_lexer extends Twig_Lexer */ if ($last_element->getValue() === 'IF') { - if (preg_match('#^\s*\.([a-zA-Z0-9_\.]+)#', substr($this->code, $this->cursor), $match)) + if (preg_match('#^\s*(not\s)?\.([a-zA-Z0-9_\.]+)#', substr($this->code, $this->cursor), $match)) { $this->pushToken(Twig_Token::STRING_TYPE, stripcslashes($match[1])); $this->moveCursor($match[0]); @@ -61,5 +62,17 @@ class phpbb_template_twig_lexer extends Twig_Lexer $this->moveCursor($match[1]); } } + + /** + * Check for old fashioned INCLUDE statements without enclosed quotes + */ + if ($last_element->getValue() === 'INCLUDE') + { + if (preg_match('#^\s*([a-zA-Z0-9_]+\.[a-zA-Z0-9]+)#', substr($this->code, $this->cursor), $match)) + { + $this->pushToken(Twig_Token::STRING_TYPE, stripcslashes($match[1])); + $this->moveCursor($match[0]); + } + } } } diff --git a/phpBB/includes/template/twig/tokenparser/event.php b/phpBB/includes/template/twig/tokenparser/event.php index cd211098d6..27a8350af1 100644 --- a/phpBB/includes/template/twig/tokenparser/event.php +++ b/phpBB/includes/template/twig/tokenparser/event.php @@ -21,6 +21,31 @@ */ class phpbb_template_twig_tokenparser_event extends Twig_TokenParser_Include { + protected function parseArguments() + { + $stream = $this->parser->getStream(); + + $ignoreMissing = true; + + $variables = null; + if ($stream->test(Twig_Token::NAME_TYPE, 'with')) { + $stream->next(); + + $variables = $this->parser->getExpressionParser()->parseExpression(); + } + + $only = false; + if ($stream->test(Twig_Token::NAME_TYPE, 'only')) { + $stream->next(); + + $only = true; + } + + $stream->expect(Twig_Token::BLOCK_END_TYPE); + + return array($variables, $only, $ignoreMissing); + } + /** * Gets the tag name associated with this token parser. * From 15114067e6c88e4ec8fa9d1ff66fd0de28b1144f Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Mon, 10 Jun 2013 11:17:11 -0500 Subject: [PATCH 006/156] [feature/twig] Replace phpBB template code with Twig syntax, then parse w/Twig Fixing begin token/node, adding includejs token/node PHPBB3-11598 --- phpBB/includes/template/twig/extension.php | 6 +- phpBB/includes/template/twig/lexer.php | 85 +++++++------------ phpBB/includes/template/twig/node/begin.php | 19 +++-- .../includes/template/twig/node/includejs.php | 50 +++++++++++ .../template/twig/tokenparser/begin.php | 4 +- .../template/twig/tokenparser/includejs.php | 49 +++++++++++ 6 files changed, 146 insertions(+), 67 deletions(-) create mode 100644 phpBB/includes/template/twig/node/includejs.php create mode 100644 phpBB/includes/template/twig/tokenparser/includejs.php diff --git a/phpBB/includes/template/twig/extension.php b/phpBB/includes/template/twig/extension.php index a607bac150..c121a21800 100644 --- a/phpBB/includes/template/twig/extension.php +++ b/phpBB/includes/template/twig/extension.php @@ -26,10 +26,11 @@ class phpbb_template_twig_extension extends Twig_Extension { return array( new phpbb_template_twig_tokenparser_if, - new phpbb_template_twig_tokenparser_include, - new phpbb_template_twig_tokenparser_event, 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, ); } @@ -39,7 +40,6 @@ class phpbb_template_twig_extension extends Twig_Extension array(), array( 'eq' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Equal', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - //'and' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_And', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), '!==' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), ), ); diff --git a/phpBB/includes/template/twig/lexer.php b/phpBB/includes/template/twig/lexer.php index 21d8fb770e..a880377583 100644 --- a/phpBB/includes/template/twig/lexer.php +++ b/phpBB/includes/template/twig/lexer.php @@ -17,62 +17,41 @@ if (!defined('IN_PHPBB')) class phpbb_template_twig_lexer extends Twig_Lexer { - protected function lexExpression() + public function tokenize($code, $filename = null) { - var_dump(substr($this->code, $this->cursor, 40), $this->states); - parent::lexExpression(); - - // Last element parsed - $last_element = end($this->tokens); + $valid_starting_tokens = array( + 'BEGIN', + 'BEGINELSE', + 'END', + 'IF', + 'ELSE', + 'ELSEIF', + 'ENDIF', + 'DEFINE', + 'DEFINE', + 'UNDEFINE', + 'ENDDEFINE', + /*'INCLUDE', + 'INCLUDEPHP', + 'INCLUDEJS',*/ + 'PHP', + 'ENDPHP', + 'EVENT', + ); - /** - * Check for old fashioned INCLUDE statements without enclosed quotes - */ - if ($last_element->getValue() === 'INCLUDE') - { - if (preg_match('#^\s*([a-zA-Z0-9_]+\.[a-zA-Z0-9]+)#', substr($this->code, $this->cursor), $match)) - { - $this->pushToken(Twig_Token::STRING_TYPE, stripcslashes($match[1])); - $this->moveCursor($match[0]); - } - } + // Replace with {% include 'blah.html' %} + $code = preg_replace('##', "{% INCLUDE$1 '$2' %}", $code); - /** - * This is some compatibility code to continue supporting expressions such as: - * - */ - if ($last_element->getValue() === 'IF') - { - if (preg_match('#^\s*(not\s)?\.([a-zA-Z0-9_\.]+)#', substr($this->code, $this->cursor), $match)) - { - $this->pushToken(Twig_Token::STRING_TYPE, stripcslashes($match[1])); - $this->moveCursor($match[0]); - } - } - - /** - * This is some compatibility code to continue supporting expressions such as: - * - */ - if ($last_element->getValue() === 'DEFINE') - { - if (preg_match('#^\s*\$([A-Z0-9]+)#', substr($this->code, $this->cursor), $match)) - { - $this->pushToken(Twig_Token::STRING_TYPE, stripcslashes($match[1])); - $this->moveCursor($match[1]); - } - } + // Replace all of our starting tokens, with Twig style, {% TOKEN %} + // This also strips the $ inside of a tag directly after the token, which was used in becomes + $code = preg_replace('##', '{% $1 $2$4 %}', $code); - /** - * Check for old fashioned INCLUDE statements without enclosed quotes - */ - if ($last_element->getValue() === 'INCLUDE') - { - if (preg_match('#^\s*([a-zA-Z0-9_]+\.[a-zA-Z0-9]+)#', substr($this->code, $this->cursor), $match)) - { - $this->pushToken(Twig_Token::STRING_TYPE, stripcslashes($match[1])); - $this->moveCursor($match[0]); - } - } + // Replace all of our variables, {VARNAME} or {$VARNAME}, with Twig style, {{ VARNAME }} + $code = preg_replace('#{\$?([A-Z_][A-Z_0-9]+)}#', '{{ $1 }}', $code); +//echo $code; +//exit; + return parent::tokenize($code, $filename); } } diff --git a/phpBB/includes/template/twig/node/begin.php b/phpBB/includes/template/twig/node/begin.php index 1d47e35d87..52e0a96f2a 100644 --- a/phpBB/includes/template/twig/node/begin.php +++ b/phpBB/includes/template/twig/node/begin.php @@ -31,40 +31,41 @@ class phpbb_template_twig_node_begin extends Twig_Node public function compile(Twig_Compiler $compiler) { $compiler - ->write("if (!isset(\$blocks)) {\n") + ->write("if (!isset(\$loops)) {\n") ->indent() - ->write("\$blocks = array();") + ->write("\$loops = array();") ->write("\$nestingLevel = 0;") ->outdent() ->write("}\n") - ->write("\$blocks[\$nestingLevel] = array();\n") + ->write("\$loops[\$nestingLevel] = array();\n") ; if (null !== $this->getNode('else')) { - $compiler->write("\$blocks[\$nestingLevel]['iterated'] = false;\n"); + $compiler->write("\$loops[\$nestingLevel]['iterated'] = false;\n"); } $compiler - ->write("foreach (\$context['_phpbb_blocks']['") + ->write("if (isset(\$context['loop'])) {") + ->write("foreach (\$context['loop']['") ->write($this->getAttribute('beginName')) - ->write("'] as \$blocks[\$nestingLevel]['i'] => \$blocks[\$nestingLevel]['values']) {") + ->write("'] as \$loops[\$nestingLevel]['i'] => \$loops[\$nestingLevel]['values']) {") ->indent() ; $compiler->subcompile($this->getNode('body')); if (null !== $this->getNode('else')) { - $compiler->write("\$blocks[\$nestingLevel]['iterated'] = true;\n"); + $compiler->write("\$loops[\$nestingLevel]['iterated'] = true;\n"); } $compiler ->outdent() - ->write("}\n") + ->write("}}\n") ; if (null !== $this->getNode('else')) { $compiler - ->write("if (!\$blocks[\$nestingLevel]['iterated']) {\n") + ->write("if (!\$loops[\$nestingLevel]['iterated']) {\n") ->indent() ->subcompile($this->getNode('else')) ->outdent() diff --git a/phpBB/includes/template/twig/node/includejs.php b/phpBB/includes/template/twig/node/includejs.php new file mode 100644 index 0000000000..e30ab75125 --- /dev/null +++ b/phpBB/includes/template/twig/node/includejs.php @@ -0,0 +1,50 @@ + + */ +class phpbb_template_twig_node_includejs 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); + + $compiler + ->write("try {\n") + ->indent() + ; + + $this->addGetTemplate($compiler); + + $compiler->raw('->display('); + + $this->addTemplateArguments($compiler); + + $compiler->raw(");\n"); + + $compiler + ->write("} catch (Twig_Error_Loader \$e) {\n") + ->indent() + ->write("// ignore missing template\n") + ->outdent() + ->write("}\n\n") + ; + } +} diff --git a/phpBB/includes/template/twig/tokenparser/begin.php b/phpBB/includes/template/twig/tokenparser/begin.php index 939f3b8f16..4a9933d680 100644 --- a/phpBB/includes/template/twig/tokenparser/begin.php +++ b/phpBB/includes/template/twig/tokenparser/begin.php @@ -37,7 +37,7 @@ class phpbb_template_twig_tokenparser_begin extends Twig_TokenParser_For $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); $body = $this->parser->subparse(array($this, 'decideBeginFork')); - if ($this->parser->getStream()->next()->getValue() == 'ELSE') { + 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 { @@ -54,7 +54,7 @@ class phpbb_template_twig_tokenparser_begin extends Twig_TokenParser_For return $token->test(array('BEGINELSE', 'END')); } - public function decideForEnd(Twig_Token $token) + public function decideBeginEnd(Twig_Token $token) { return $token->test('END'); } diff --git a/phpBB/includes/template/twig/tokenparser/includejs.php b/phpBB/includes/template/twig/tokenparser/includejs.php new file mode 100644 index 0000000000..36a1fcb585 --- /dev/null +++ b/phpBB/includes/template/twig/tokenparser/includejs.php @@ -0,0 +1,49 @@ + + * {% include 'header.html' %} + * Body + * {% include 'footer.html' %} + * + */ +class phpbb_template_twig_tokenparser_includejs 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_includejs($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 'INCLUDEJS'; + } +} From eac3c1f75c370e9ddb7319db0b11c7c8fa161709 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Mon, 10 Jun 2013 11:57:51 -0500 Subject: [PATCH 007/156] [feature/twig] BEGIN loops now work PHPBB3-11598 --- phpBB/includes/template/twig/lexer.php | 2 +- phpBB/includes/template/twig/node/begin.php | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/phpBB/includes/template/twig/lexer.php b/phpBB/includes/template/twig/lexer.php index a880377583..4402760a7b 100644 --- a/phpBB/includes/template/twig/lexer.php +++ b/phpBB/includes/template/twig/lexer.php @@ -49,7 +49,7 @@ class phpbb_template_twig_lexer extends Twig_Lexer $code = preg_replace('##', '{% $1 $2$4 %}', $code); // Replace all of our variables, {VARNAME} or {$VARNAME}, with Twig style, {{ VARNAME }} - $code = preg_replace('#{\$?([A-Z_][A-Z_0-9]+)}#', '{{ $1 }}', $code); + $code = preg_replace('#{\$?([a-zA-Z0-9_\.]+)}#', '{{ $1 }}', $code); //echo $code; //exit; return parent::tokenize($code, $filename); diff --git a/phpBB/includes/template/twig/node/begin.php b/phpBB/includes/template/twig/node/begin.php index 52e0a96f2a..1f4de9deda 100644 --- a/phpBB/includes/template/twig/node/begin.php +++ b/phpBB/includes/template/twig/node/begin.php @@ -45,10 +45,9 @@ class phpbb_template_twig_node_begin extends Twig_Node } $compiler - ->write("if (isset(\$context['loop'])) {") - ->write("foreach (\$context['loop']['") - ->write($this->getAttribute('beginName')) - ->write("'] as \$loops[\$nestingLevel]['i'] => \$loops[\$nestingLevel]['values']) {") + ->write("if (isset(\$context['loop']['" . $this->getAttribute('beginName') . "'])) {") + ->write("foreach (\$context['loop']['". $this->getAttribute('beginName'). "'] as \$" . $this->getAttribute('beginName') . ") {") + ->write("\$context['". $this->getAttribute('beginName'). "'] = \$" . $this->getAttribute('beginName') . ";") ->indent() ; From b035697800a4a208cd4e6be68bfd4033cc85af38 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Mon, 10 Jun 2013 12:59:47 -0500 Subject: [PATCH 008/156] [feature/twig] Replace phpBB template with Twig Move phpbb_template class to phpbb_template_phpbb Changed phpbb_template class to an interface Switch services.yml to load phpbb_template_twig instead of phpbb_template PHPBB3-11598 --- phpBB/config/services.yml | 2 +- phpBB/includes/template/phpbb.php | 515 ++++++++++++++++++++++++++ phpBB/includes/template/template.php | 408 +------------------- phpBB/includes/template/twig/twig.php | 369 ++++++++++++++++++ 4 files changed, 898 insertions(+), 396 deletions(-) create mode 100644 phpBB/includes/template/phpbb.php create mode 100644 phpBB/includes/template/twig/twig.php 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/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 @@ + $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 = ''; + $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 = ''; - $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/twig.php b/phpBB/includes/template/twig/twig.php new file mode 100644 index 0000000000..f48bedcbf2 --- /dev/null +++ b/phpBB/includes/template/twig/twig.php @@ -0,0 +1,369 @@ +phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + $this->config = $config; + $this->user = $user; + $this->locator = $locator; + $this->extension_manager = $extension_manager; + + $loader = new Twig_Loader_Filesystem($phpbb_root_path . 'styles/prosilver/template/'); + $this->twig = new Twig_Environment($loader, array( + //'cache' => $phpbb_root_path . 'cache/twig/', + 'debug' => true, + 'auto_reload' => true, + 'autoescape' => false, + )); + + $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. + */ + 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 = array(); + } + + /** + * Reset/empty complete block + * + * @param string $blockname Name of block to destroy + */ + public function destroy_block_vars($blockname) + { + if (!isset($this->context['loop'][$blockname])) + { + return; + } + + unset($this->context['loop'][$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 + { + echo $this->twig->render($this->locator->get_filename_for_handle($handle), $this->context); + } + catch (Twig_Error $e) + { + return false; + } + + 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) + { + $this->context[$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[$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) + { + $this->context['loop'][$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') + { + switch ($mode) + { + case 'insert' : + $this->context['loop'][$blockname][$key] = $vararray; + break; + + case 'change' : + if (!isset($this->context['loop'][$blockname][$key])) + { + return false; + } + + $this->context['loop'][$blockname][$key] = array_merge($this->context['loop'][$blockname][$key], $vararray); + break; + } + + return true; + } +} From 9acde23a0562ebd57092ed5701bb6a63e623b891 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Tue, 11 Jun 2013 09:41:15 -0500 Subject: [PATCH 009/156] [feature/twig] Language output assignments, using context class again PHPBB3-11598 --- phpBB/includes/template/context.php | 20 ++++++++ phpBB/includes/template/twig/twig.php | 74 +++++++++++++++------------ 2 files changed, 62 insertions(+), 32 deletions(-) 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 @@ -82,6 +82,26 @@ class phpbb_template_context return true; } + /** + * 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. * diff --git a/phpBB/includes/template/twig/twig.php b/phpBB/includes/template/twig/twig.php index f48bedcbf2..81c03b6ef1 100644 --- a/phpBB/includes/template/twig/twig.php +++ b/phpBB/includes/template/twig/twig.php @@ -24,9 +24,9 @@ class phpbb_template_twig implements phpbb_template /** * Template context. * Stores template data used during template rendering. - * @var array + * @var phpbb_template_context */ - protected $context = array(); + protected $context; /** * Path of the cache directory for the template @@ -38,38 +38,38 @@ class phpbb_template_twig implements phpbb_template * phpBB root path * @var string */ - private $phpbb_root_path; + protected $phpbb_root_path; /** * PHP file extension * @var string */ - private $php_ext; + protected $php_ext; /** * phpBB config instance * @var phpbb_config */ - private $config; + protected $config; /** * Current user * @var phpbb_user */ - private $user; + protected $user; /** * Template locator * @var phpbb_template_locator */ - private $locator; + protected $locator; /** * Extension manager. * * @var phpbb_extension_manager */ - private $extension_manager; + protected $extension_manager; /** * Name of the style that the template being compiled and/or rendered @@ -79,7 +79,7 @@ class phpbb_template_twig implements phpbb_template * * @var array */ - private $style_names; + protected $style_names; /** * Twig Environment @@ -104,6 +104,7 @@ class phpbb_template_twig implements phpbb_template $this->config = $config; $this->user = $user; $this->locator = $locator; + $this->context = $context; $this->extension_manager = $extension_manager; $loader = new Twig_Loader_Filesystem($phpbb_root_path . 'styles/prosilver/template/'); @@ -160,12 +161,7 @@ class phpbb_template_twig implements phpbb_template */ public function destroy_block_vars($blockname) { - if (!isset($this->context['loop'][$blockname])) - { - return; - } - - unset($this->context['loop'][$blockname]); + return $this->context->destroy_block_vars($blockname); } /** @@ -188,7 +184,7 @@ class phpbb_template_twig implements phpbb_template try { - echo $this->twig->render($this->locator->get_filename_for_handle($handle), $this->context); + echo $this->twig->render($this->locator->get_filename_for_handle($handle), $this->get_template_vars()); } catch (Twig_Error $e) { @@ -291,7 +287,7 @@ class phpbb_template_twig implements phpbb_template */ public function assign_var($varname, $varval) { - $this->context[$varname] = $varval; + return $this->context->assign_var($varname, $varval); } /** @@ -304,7 +300,7 @@ class phpbb_template_twig implements phpbb_template */ public function append_var($varname, $varval) { - $this->context[$varname] .= $varval; + return $this->context->append_var($varname, $varval); } // Docstring is copied from phpbb_template_context method with the same name. @@ -315,7 +311,7 @@ class phpbb_template_twig implements phpbb_template */ public function assign_block_vars($blockname, array $vararray) { - $this->context['loop'][$blockname][] = $vararray; + return $this->context->assign_block_vars($blockname, $vararray); } // Docstring is copied from phpbb_template_context method with the same name. @@ -348,22 +344,36 @@ class phpbb_template_twig implements phpbb_template */ public function alter_block_array($blockname, array $vararray, $key = false, $mode = 'insert') { - switch ($mode) + return $this->context->alter_block_array($blockname, $vararray, $key, $mode); + } + + protected function get_template_vars() + { + $vars = array(); + + // Work-around for now + foreach ($this->user->lang as $key => $value) { - case 'insert' : - $this->context['loop'][$blockname][$key] = $vararray; - break; + if (is_array($value)) + { + continue; + } - case 'change' : - if (!isset($this->context['loop'][$blockname][$key])) - { - return false; - } - - $this->context['loop'][$blockname][$key] = array_merge($this->context['loop'][$blockname][$key], $vararray); - break; + $vars['L_' . strtoupper($key)] = $value; + $vars['LA_' . strtoupper($key)] = addslashes($value); } - return true; + $vars = array_merge( + $vars, + $this->context->get_rootref(), + array( + 'loop' => $this->context->get_tpldata(), + ) + ); + + // cleanup + unset($vars['loop']['.']); + + return $vars; } } From 6f9acb01179a15e55d9594f61278adc068cab251 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Tue, 11 Jun 2013 09:44:01 -0500 Subject: [PATCH 010/156] [feature/twig] Update composer.lock PHPBB3-11598 --- phpBB/composer.lock | 852 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 819 insertions(+), 33 deletions(-) diff --git a/phpBB/composer.lock b/phpBB/composer.lock index 75b9c360f0..1c4bc4988d 100644 --- a/phpBB/composer.lock +++ b/phpBB/composer.lock @@ -1,4 +1,8 @@ { + "_readme": [ + "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": "bd651ccd1316ecdc6d72a22357d8c46f", "packages": [ { @@ -19,9 +23,7 @@ "require": { "php": ">=5.3.3" }, - "time": "2013-05-09 15:22:40", "type": "library", - "installation-source": "dist", "autoload": { "psr-0": { "Symfony\\Component\\Config": "" @@ -41,7 +43,8 @@ } ], "description": "Symfony Config Component", - "homepage": "http://symfony.com" + "homepage": "http://symfony.com", + "time": "2013-05-09 15:22:40" }, { "name": "symfony/dependency-injection", @@ -62,16 +65,14 @@ "php": ">=5.3.3" }, "require-dev": { - "symfony/yaml": "2.1.*", - "symfony/config": "2.1.*" + "symfony/config": "2.1.*", + "symfony/yaml": "2.1.*" }, "suggest": { - "symfony/yaml": "2.1.*", - "symfony/config": "2.1.*" + "symfony/config": "2.1.*", + "symfony/yaml": "2.1.*" }, - "time": "2013-05-03 05:08:13", "type": "library", - "installation-source": "dist", "autoload": { "psr-0": { "Symfony\\Component\\DependencyInjection": "" @@ -91,7 +92,8 @@ } ], "description": "Symfony DependencyInjection Component", - "homepage": "http://symfony.com" + "homepage": "http://symfony.com", + "time": "2013-05-03 05:08:13" }, { "name": "symfony/event-dispatcher", @@ -118,9 +120,7 @@ "symfony/dependency-injection": "2.1.*", "symfony/http-kernel": "2.1.*" }, - "time": "2013-02-11 11:26:14", "type": "library", - "installation-source": "dist", "autoload": { "psr-0": { "Symfony\\Component\\EventDispatcher": "" @@ -140,7 +140,8 @@ } ], "description": "Symfony EventDispatcher Component", - "homepage": "http://symfony.com" + "homepage": "http://symfony.com", + "time": "2013-02-11 11:26:14" }, { "name": "symfony/http-foundation", @@ -160,9 +161,7 @@ "require": { "php": ">=5.3.3" }, - "time": "2013-05-26 18:42:07", "type": "library", - "installation-source": "dist", "autoload": { "psr-0": { "Symfony\\Component\\HttpFoundation": "", @@ -183,7 +182,8 @@ } ], "description": "Symfony HttpFoundation Component", - "homepage": "http://symfony.com" + "homepage": "http://symfony.com", + "time": "2013-05-26 18:42:07" }, { "name": "symfony/http-kernel", @@ -223,9 +223,7 @@ "symfony/dependency-injection": "2.1.*", "symfony/finder": "2.1.*" }, - "time": "2013-06-02 12:29:05", "type": "library", - "installation-source": "dist", "autoload": { "psr-0": { "Symfony\\Component\\HttpKernel": "" @@ -245,7 +243,8 @@ } ], "description": "Symfony HttpKernel Component", - "homepage": "http://symfony.com" + "homepage": "http://symfony.com", + "time": "2013-06-02 12:29:05" }, { "name": "symfony/routing", @@ -266,19 +265,17 @@ "php": ">=5.3.3" }, "require-dev": { + "doctrine/common": ">=2.2,<3.0", "symfony/config": "2.1.*", - "symfony/yaml": "2.1.*", "symfony/http-kernel": "2.1.*", - "doctrine/common": ">=2.2,<3.0" + "symfony/yaml": "2.1.*" }, "suggest": { + "doctrine/common": "~2.2", "symfony/config": "2.1.*", - "symfony/yaml": "2.1.*", - "doctrine/common": "~2.2" + "symfony/yaml": "2.1.*" }, - "time": "2013-05-06 10:48:41", "type": "library", - "installation-source": "dist", "autoload": { "psr-0": { "Symfony\\Component\\Routing": "" @@ -298,7 +295,8 @@ } ], "description": "Symfony Routing Component", - "homepage": "http://symfony.com" + "homepage": "http://symfony.com", + "time": "2013-05-06 10:48:41" }, { "name": "symfony/yaml", @@ -318,9 +316,7 @@ "require": { "php": ">=5.3.3" }, - "time": "2013-05-10 00:09:46", "type": "library", - "installation-source": "dist", "autoload": { "psr-0": { "Symfony\\Component\\Yaml": "" @@ -340,7 +336,8 @@ } ], "description": "Symfony Yaml Component", - "homepage": "http://symfony.com" + "homepage": "http://symfony.com", + "time": "2013-05-10 00:09:46" }, { "name": "twig/twig", @@ -359,14 +356,12 @@ "require": { "php": ">=5.2.4" }, - "time": "2013-06-06 06:06:01", "type": "library", "extra": { "branch-alias": { "dev-master": "1.13-dev" } }, - "installation-source": "dist", "autoload": { "psr-0": { "Twig_": "lib/" @@ -389,15 +384,806 @@ "homepage": "http://twig.sensiolabs.org", "keywords": [ "templating" - ] + ], + "time": "2013-06-06 06:06:01" + } + ], + "packages-dev": [ + { + "name": "fabpot/goutte", + "version": "v0.1.0", + "source": { + "type": "git", + "url": "https://github.com/fabpot/Goutte", + "reference": "v0.1.0" + }, + "dist": { + "type": "zip", + "url": "https://github.com/fabpot/Goutte/archive/v0.1.0.zip", + "reference": "v0.1.0", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "guzzle/guzzle": "3.0.*", + "php": ">=5.3.0", + "symfony/browser-kit": "2.1.*", + "symfony/css-selector": "2.1.*", + "symfony/dom-crawler": "2.1.*", + "symfony/finder": "2.1.*", + "symfony/process": "2.1.*" + }, + "type": "application", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-0": { + "Goutte": "." + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "A simple PHP Web Scraper", + "homepage": "https://github.com/fabpot/Goutte", + "keywords": [ + "scraper" + ], + "time": "2012-12-02 13:44:35" + }, + { + "name": "guzzle/guzzle", + "version": "v3.0.7", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle", + "reference": "v3.0.7" + }, + "dist": { + "type": "zip", + "url": "https://github.com/guzzle/guzzle/archive/v3.0.7.zip", + "reference": "v3.0.7", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "php": ">=5.3.2", + "symfony/event-dispatcher": ">=2.1" + }, + "replace": { + "guzzle/batch": "self.version", + "guzzle/cache": "self.version", + "guzzle/common": "self.version", + "guzzle/http": "self.version", + "guzzle/inflection": "self.version", + "guzzle/iterator": "self.version", + "guzzle/log": "self.version", + "guzzle/parser": "self.version", + "guzzle/plugin": "self.version", + "guzzle/plugin-async": "self.version", + "guzzle/plugin-backoff": "self.version", + "guzzle/plugin-cache": "self.version", + "guzzle/plugin-cookie": "self.version", + "guzzle/plugin-curlauth": "self.version", + "guzzle/plugin-history": "self.version", + "guzzle/plugin-log": "self.version", + "guzzle/plugin-md5": "self.version", + "guzzle/plugin-mock": "self.version", + "guzzle/plugin-oauth": "self.version", + "guzzle/service": "self.version", + "guzzle/stream": "self.version" + }, + "require-dev": { + "doctrine/common": "*", + "monolog/monolog": "1.*", + "phpunit/phpunit": "3.7.*", + "symfony/class-loader": "*", + "zend/zend-cache1": "1.12", + "zend/zend-log1": "1.12", + "zendframework/zend-cache": "2.0.*", + "zendframework/zend-log": "2.0.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-0": { + "Guzzle\\Tests": "tests/", + "Guzzle": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Guzzle Community", + "homepage": "https://github.com/guzzle/guzzle/contributors" + } + ], + "description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "time": "2012-12-19 23:06:35" + }, + { + "name": "phpunit/dbunit", + "version": "1.2.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/dbunit.git", + "reference": "1.2.3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/dbunit/zipball/1.2.3", + "reference": "1.2.3", + "shasum": "" + }, + "require": { + "ext-pdo": "*", + "ext-simplexml": "*", + "php": ">=5.3.3", + "phpunit/phpunit": ">=3.7.0@stable" + }, + "bin": [ + "dbunit.php" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "PHPUnit/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "", + "../../symfony/yaml/" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "DbUnit port for PHP/PHPUnit to support database interaction testing.", + "homepage": "https://github.com/sebastianbergmann/dbunit/", + "keywords": [ + "database", + "testing", + "xunit" + ], + "time": "2013-03-01 11:50:46" + }, + { + "name": "phpunit/php-code-coverage", + "version": "1.2.11", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "1.2.11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/1.2.11", + "reference": "1.2.11", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "phpunit/php-file-iterator": ">=1.3.0@stable", + "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" + }, + "type": "library", + "autoload": { + "classmap": [ + "PHP/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2013-05-23 18:23:24" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.3.3", + "source": { + "type": "git", + "url": "git://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "1.3.3" + }, + "dist": { + "type": "zip", + "url": "https://github.com/sebastianbergmann/php-file-iterator/zipball/1.3.3", + "reference": "1.3.3", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "File/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "http://www.phpunit.de/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2012-10-11 04:44:38" + }, + { + "name": "phpunit/php-text-template", + "version": "1.1.4", + "source": { + "type": "git", + "url": "git://github.com/sebastianbergmann/php-text-template.git", + "reference": "1.1.4" + }, + "dist": { + "type": "zip", + "url": "https://github.com/sebastianbergmann/php-text-template/zipball/1.1.4", + "reference": "1.1.4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "Text/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2012-10-31 11:15:28" + }, + { + "name": "phpunit/php-timer", + "version": "1.0.4", + "source": { + "type": "git", + "url": "git://github.com/sebastianbergmann/php-timer.git", + "reference": "1.0.4" + }, + "dist": { + "type": "zip", + "url": "https://github.com/sebastianbergmann/php-timer/zipball/1.0.4", + "reference": "1.0.4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "PHP/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "http://www.phpunit.de/", + "keywords": [ + "timer" + ], + "time": "2012-10-11 04:45:58" + }, + { + "name": "phpunit/php-token-stream", + "version": "1.1.5", + "source": { + "type": "git", + "url": "git://github.com/sebastianbergmann/php-token-stream.git", + "reference": "1.1.5" + }, + "dist": { + "type": "zip", + "url": "https://github.com/sebastianbergmann/php-token-stream/zipball/1.1.5", + "reference": "1.1.5", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "PHP/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "http://www.phpunit.de/", + "keywords": [ + "tokenizer" + ], + "time": "2012-10-11 04:47:14" + }, + { + "name": "phpunit/phpunit", + "version": "3.7.21", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "3.7.21" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3.7.21", + "reference": "3.7.21", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=5.3.3", + "phpunit/php-code-coverage": ">=1.2.1,<1.3.0", + "phpunit/php-file-iterator": ">=1.3.1", + "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,<3.0" + }, + "require-dev": { + "pear-pear/pear": "1.9.4" + }, + "suggest": { + "ext-json": "*", + "ext-simplexml": "*", + "ext-tokenizer": "*", + "phpunit/php-invoker": ">=1.1.0,<1.2.0" + }, + "bin": [ + "composer/bin/phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.7.x-dev" + } + }, + "autoload": { + "classmap": [ + "PHPUnit/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "", + "../../symfony/yaml/" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "http://www.phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2013-05-23 18:54:29" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "1.2.3", + "source": { + "type": "git", + "url": "git://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "1.2.3" + }, + "dist": { + "type": "zip", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects/archive/1.2.3.zip", + "reference": "1.2.3", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "phpunit/php-text-template": ">=1.1.1@stable" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "autoload": { + "classmap": [ + "PHPUnit/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "time": "2013-01-13 10:24:48" + }, + { + "name": "symfony/browser-kit", + "version": "v2.1.11", + "target-dir": "Symfony/Component/BrowserKit", + "source": { + "type": "git", + "url": "https://github.com/symfony/BrowserKit.git", + "reference": "v2.1.11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/BrowserKit/zipball/v2.1.11", + "reference": "v2.1.11", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "symfony/dom-crawler": "2.1.*" + }, + "require-dev": { + "symfony/css-selector": "2.1.*", + "symfony/process": "2.1.*" + }, + "suggest": { + "symfony/process": "2.1.*" + }, + "type": "library", + "autoload": { + "psr-0": { + "Symfony\\Component\\BrowserKit": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony BrowserKit Component", + "homepage": "http://symfony.com", + "time": "2013-04-29 20:22:06" + }, + { + "name": "symfony/css-selector", + "version": "v2.1.11", + "target-dir": "Symfony/Component/CssSelector", + "source": { + "type": "git", + "url": "https://github.com/symfony/CssSelector.git", + "reference": "v2.1.11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/CssSelector/zipball/v2.1.11", + "reference": "v2.1.11", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "psr-0": { + "Symfony\\Component\\CssSelector": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony CssSelector Component", + "homepage": "http://symfony.com", + "time": "2013-05-17 00:31:34" + }, + { + "name": "symfony/dom-crawler", + "version": "v2.1.11", + "target-dir": "Symfony/Component/DomCrawler", + "source": { + "type": "git", + "url": "https://github.com/symfony/DomCrawler.git", + "reference": "v2.1.11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/DomCrawler/zipball/v2.1.11", + "reference": "v2.1.11", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "symfony/css-selector": "2.1.*" + }, + "suggest": { + "symfony/css-selector": "2.1.*" + }, + "type": "library", + "autoload": { + "psr-0": { + "Symfony\\Component\\DomCrawler": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony DomCrawler Component", + "homepage": "http://symfony.com", + "time": "2013-05-16 00:06:15" + }, + { + "name": "symfony/finder", + "version": "v2.1.11", + "target-dir": "Symfony/Component/Finder", + "source": { + "type": "git", + "url": "https://github.com/symfony/Finder.git", + "reference": "v2.1.11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Finder/zipball/v2.1.11", + "reference": "v2.1.11", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "psr-0": { + "Symfony\\Component\\Finder": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony Finder Component", + "homepage": "http://symfony.com", + "time": "2013-05-25 15:47:15" + }, + { + "name": "symfony/process", + "version": "v2.1.11", + "target-dir": "Symfony/Component/Process", + "source": { + "type": "git", + "url": "https://github.com/symfony/Process.git", + "reference": "v2.1.11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Process/zipball/v2.1.11", + "reference": "v2.1.11", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "psr-0": { + "Symfony\\Component\\Process": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony Process Component", + "homepage": "http://symfony.com", + "time": "2013-05-06 10:21:56" } ], - "packages-dev": null, "aliases": [ ], "minimum-stability": "beta", "stability-flags": [ + ], + "platform": [ + + ], + "platform-dev": [ + ] } From 612dbad63fa6f85fdaa0298e67f89d7c9010dbe6 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Tue, 11 Jun 2013 10:57:00 -0500 Subject: [PATCH 011/156] [feature/twig] Fixing IF .blah correctly PHPBB3-11598 --- phpBB/includes/template/twig/lexer.php | 29 +++++++++++++++++++------- phpBB/includes/template/twig/twig.php | 7 ++++++- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/phpBB/includes/template/twig/lexer.php b/phpBB/includes/template/twig/lexer.php index 4402760a7b..71e3e9c27e 100644 --- a/phpBB/includes/template/twig/lexer.php +++ b/phpBB/includes/template/twig/lexer.php @@ -38,20 +38,35 @@ class phpbb_template_twig_lexer extends Twig_Lexer 'ENDPHP', 'EVENT', ); - + // Replace with {% include 'blah.html' %} $code = preg_replace('##', "{% INCLUDE$1 '$2' %}", $code); + // This strips the $ inside of a tag directly after the token, which was used in #', '', $code); + + // This strips the . inside of a tag directly before a variable name, which was used in #', array($this, 'tag_if_cleanup'), $code); + // Replace all of our starting tokens, with Twig style, {% TOKEN %} - // This also strips the $ inside of a tag directly after the token, which was used in becomes - $code = preg_replace('##', '{% $1 $2$4 %}', $code); - + $code = preg_replace('##', '{% $1 $2 %}', $code); + // Replace all of our variables, {VARNAME} or {$VARNAME}, with Twig style, {{ VARNAME }} $code = preg_replace('#{\$?([a-zA-Z0-9_\.]+)}#', '{{ $1 }}', $code); -//echo $code; -//exit; + return parent::tokenize($code, $filename); } + + /** + * preg_replace_callback to clean up IF statements + * + * This strips the . inside of a tag directly before a variable name, which was used in '; + } } diff --git a/phpBB/includes/template/twig/twig.php b/phpBB/includes/template/twig/twig.php index 81c03b6ef1..a067827f70 100644 --- a/phpBB/includes/template/twig/twig.php +++ b/phpBB/includes/template/twig/twig.php @@ -347,6 +347,11 @@ class phpbb_template_twig implements phpbb_template 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(); @@ -354,7 +359,7 @@ class phpbb_template_twig implements phpbb_template // Work-around for now foreach ($this->user->lang as $key => $value) { - if (is_array($value)) + if (!is_string($value)) { continue; } From 95884edf08d962d0f8cf764f4870f910d4d65009 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Wed, 12 Jun 2013 12:32:56 -0500 Subject: [PATCH 012/156] [feature/twig] Correcting output of INCLUDEJS PHPBB3-11598 --- .../includes/template/twig/node/includejs.php | 51 ++++++------------- .../template/twig/tokenparser/includejs.php | 33 ++++-------- 2 files changed, 27 insertions(+), 57 deletions(-) diff --git a/phpBB/includes/template/twig/node/includejs.php b/phpBB/includes/template/twig/node/includejs.php index e30ab75125..6fe8e155b7 100644 --- a/phpBB/includes/template/twig/node/includejs.php +++ b/phpBB/includes/template/twig/node/includejs.php @@ -1,22 +1,19 @@ - */ -class phpbb_template_twig_node_includejs extends Twig_Node_Include +* +* @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. * @@ -27,24 +24,8 @@ class phpbb_template_twig_node_includejs extends Twig_Node_Include $compiler->addDebugInfo($this); $compiler - ->write("try {\n") - ->indent() - ; - - $this->addGetTemplate($compiler); - - $compiler->raw('->display('); - - $this->addTemplateArguments($compiler); - - $compiler->raw(");\n"); - - $compiler - ->write("} catch (Twig_Error_Loader \$e) {\n") - ->indent() - ->write("// ignore missing template\n") - ->outdent() - ->write("}\n\n") - ; + ->write("\$context['SCRIPTS'] .= ' - +

{L_FIND_USERNAME}

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 @@ - + {SCRIPTS} 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 @@ // ]]> - + - + 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} - + 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 @@ - + 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 @@ - + From 309ed5e5c32cb334986b53ca855e26dd483c2919 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Mon, 24 Jun 2013 13:37:22 -0500 Subject: [PATCH 028/156] [feature/twig] Fixing file header copyrights PHPBB3-11598 --- phpBB/includes/template/twig/node/begin.php | 23 ++++--------- .../template/twig/tokenparser/begin.php | 28 ++++------------ .../template/twig/tokenparser/define.php | 33 ++++--------------- .../includes/template/twig/tokenparser/if.php | 30 ++++------------- .../template/twig/tokenparser/include.php | 26 ++++----------- 5 files changed, 35 insertions(+), 105 deletions(-) diff --git a/phpBB/includes/template/twig/node/begin.php b/phpBB/includes/template/twig/node/begin.php index 34fd16dd73..4222295d26 100644 --- a/phpBB/includes/template/twig/node/begin.php +++ b/phpBB/includes/template/twig/node/begin.php @@ -1,21 +1,12 @@ - */ +* +* @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) diff --git a/phpBB/includes/template/twig/tokenparser/begin.php b/phpBB/includes/template/twig/tokenparser/begin.php index 4a9933d680..0a2f2da40d 100644 --- a/phpBB/includes/template/twig/tokenparser/begin.php +++ b/phpBB/includes/template/twig/tokenparser/begin.php @@ -1,26 +1,12 @@ - *
    - * {% for user in users %} - *
  • {{ user.username|e }}
  • - * {% endfor %} - *
- * - */ +* +* @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 { /** diff --git a/phpBB/includes/template/twig/tokenparser/define.php b/phpBB/includes/template/twig/tokenparser/define.php index 8eb33c7ff9..83f537a1ea 100644 --- a/phpBB/includes/template/twig/tokenparser/define.php +++ b/phpBB/includes/template/twig/tokenparser/define.php @@ -1,31 +1,12 @@ - * {% set foo = 'foo' %} - * - * {% set foo = [1, 2] %} - * - * {% set foo = {'foo': 'bar'} %} - * - * {% set foo = 'foo' ~ 'bar' %} - * - * {% set foo, bar = 'foo', 'bar' %} - * - * {% set foo %}Some content{% endset %} - * - */ +* +* @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) diff --git a/phpBB/includes/template/twig/tokenparser/if.php b/phpBB/includes/template/twig/tokenparser/if.php index e47744093e..04ee048f94 100644 --- a/phpBB/includes/template/twig/tokenparser/if.php +++ b/phpBB/includes/template/twig/tokenparser/if.php @@ -1,28 +1,12 @@ - * {% if users %} - *
    - * {% for user in users %} - *
  • {{ user.username|e }}
  • - * {% endfor %} - *
- * {% endif %} - * - */ +* +* @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 { /** diff --git a/phpBB/includes/template/twig/tokenparser/include.php b/phpBB/includes/template/twig/tokenparser/include.php index 32e1cd331d..0f7e4faf8f 100644 --- a/phpBB/includes/template/twig/tokenparser/include.php +++ b/phpBB/includes/template/twig/tokenparser/include.php @@ -1,24 +1,12 @@ - * {% include 'header.html' %} - * Body - * {% include 'footer.html' %} - * - */ +* +* @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 { /** From a61dd78fc953db2a90b1aa62263a797764cf8bba Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Mon, 24 Jun 2013 13:40:05 -0500 Subject: [PATCH 029/156] [feature/twig] Change composer to load Twig 1.13.* PHPBB3-11598 --- phpBB/composer.json | 2 +- phpBB/composer.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/composer.json b/phpBB/composer.json index c31d721301..a114d5c0e0 100644 --- a/phpBB/composer.json +++ b/phpBB/composer.json @@ -7,7 +7,7 @@ "symfony/http-kernel": "2.1.*", "symfony/routing": "2.1.*", "symfony/yaml": "2.1.*", - "twig/twig": "1.*" + "twig/twig": "1.13.*" }, "require-dev": { "fabpot/goutte": "v0.1.0", diff --git a/phpBB/composer.lock b/phpBB/composer.lock index 1c4bc4988d..a20c6303ee 100644 --- a/phpBB/composer.lock +++ b/phpBB/composer.lock @@ -3,7 +3,7 @@ "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": "bd651ccd1316ecdc6d72a22357d8c46f", + "hash": "e4a4f4848a7201d7e044446001afda29", "packages": [ { "name": "symfony/config", From 2819a2641b5aa6a006fa6c7a65487de89cb1b25a Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Mon, 24 Jun 2013 13:45:23 -0500 Subject: [PATCH 030/156] [feature/twig] Only set extensions if extension manager is loaded PHPBB3-11598 --- phpBB/includes/template/twig/twig.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/phpBB/includes/template/twig/twig.php b/phpBB/includes/template/twig/twig.php index 15e49df200..c894fb5567 100644 --- a/phpBB/includes/template/twig/twig.php +++ b/phpBB/includes/template/twig/twig.php @@ -126,7 +126,10 @@ class phpbb_template_twig implements phpbb_template )); // Set enabled phpbb extensions - $this->twig->set_phpbb_extensions($this->extension_manager->all_enabled()); + if ($this->extension_manager) + { + $this->twig->set_phpbb_extensions($this->extension_manager->all_enabled()); + } // Clear previous cache files (while WIP) // @todo remove From 2dd58413e26434568bd768549e621e72b5ccb33c Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Mon, 24 Jun 2013 13:45:48 -0500 Subject: [PATCH 031/156] [feature/twig] Fix controller/helper_url_test (missing globals) PHPBB3-11598 --- tests/controller/helper_url_test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/controller/helper_url_test.php b/tests/controller/helper_url_test.php index e654c56242..42c416b1d2 100644 --- a/tests/controller/helper_url_test.php +++ b/tests/controller/helper_url_test.php @@ -45,7 +45,7 @@ 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(); From a1f957af84130963ef20855dfee03ba86ab1a9b6 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Mon, 24 Jun 2013 15:28:54 -0500 Subject: [PATCH 032/156] [feature/twig] Working on fixing tests PHPBB3-11598 --- phpBB/includes/style/style.php | 2 +- phpBB/includes/template/template.php | 7 +++ phpBB/includes/template/twig/node/begin.php | 34 ++++++++---- phpBB/includes/template/twig/twig.php | 57 +++++++++++++-------- tests/template/template_test_case.php | 35 ++----------- 5 files changed, 72 insertions(+), 63 deletions(-) diff --git a/phpBB/includes/style/style.php b/phpBB/includes/style/style.php index 5aeeac40e4..493c4512a6 100644 --- a/phpBB/includes/style/style.php +++ b/phpBB/includes/style/style.php @@ -160,7 +160,7 @@ class phpbb_style $this->template->set_style_names($names, $appended_paths); } - $this->template->cachepath = $this->phpbb_root_path . 'cache/tpl_' . str_replace('_', '-', $name) . '_'; + //$this->template->cachepath = $this->phpbb_root_path . 'cache/tpl_' . str_replace('_', '-', $name) . '_'; return true; } diff --git a/phpBB/includes/template/template.php b/phpBB/includes/template/template.php index 5dadd34084..15f0b6ee60 100644 --- a/phpBB/includes/template/template.php +++ b/phpBB/includes/template/template.php @@ -130,4 +130,11 @@ interface phpbb_template * @return bool false on error, true on success */ public function alter_block_array($blockname, array $vararray, $key = false, $mode = 'insert'); + + /** + * Clear the cache + * + * @return phpbb_template + */ + public function clear_cache(); } diff --git a/phpBB/includes/template/twig/node/begin.php b/phpBB/includes/template/twig/node/begin.php index 4222295d26..3c1ce1b89b 100644 --- a/phpBB/includes/template/twig/node/begin.php +++ b/phpBB/includes/template/twig/node/begin.php @@ -32,20 +32,36 @@ class phpbb_template_twig_node_begin extends Twig_Node ; $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") + ->write("if (!empty(\$parent['" . $this->getAttribute('beginName') . "'])) {\n") + ->indent() + ->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") + // 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") + $compiler + ->outdent() + ->write("}\n") + ; + + if (null !== $this->getNode('else')) { + $compiler + ->write("} else {\n") + ->indent() + ->subcompile($this->getNode('else')) + ->outdent() + ; + } + + $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") diff --git a/phpBB/includes/template/twig/twig.php b/phpBB/includes/template/twig/twig.php index c894fb5567..e2c9afbc78 100644 --- a/phpBB/includes/template/twig/twig.php +++ b/phpBB/includes/template/twig/twig.php @@ -114,10 +114,6 @@ class phpbb_template_twig implements phpbb_template // 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 @@ -133,10 +129,7 @@ class phpbb_template_twig implements phpbb_template // Clear previous cache files (while WIP) // @todo remove - if (is_dir($this->cachepath)) - { - $this->twig->clearCacheFiles(); - } + $this->clear_cache(); $this->twig->addExtension(new phpbb_template_twig_extension); @@ -145,6 +138,21 @@ class phpbb_template_twig implements phpbb_template $this->twig->setLexer($lexer); } + /** + * Clear the cache + * + * @return phpbb_template + */ + public function clear_cache() + { + if (is_dir($this->cachepath)) + { + $this->twig->clearCacheFiles(); + } + + return $this; + } + /** * Sets the template filenames for handles. * @@ -177,6 +185,10 @@ class phpbb_template_twig implements phpbb_template { $this->twig->getLoader()->setPaths($style_paths, 'core'); + // Add admin namespace + // @todo use phpbb_admin path + $loader->addPath($this->phpbb_root_path . 'adm/style/', 'admin'); + // Add all namespaces for all extensions if ($this->extension_manager instanceof phpbb_extension_manager) { @@ -415,25 +427,28 @@ class phpbb_template_twig implements phpbb_template $vars = array(); // Work-around for now - foreach ($this->user->lang as $key => $value) + if (!empty($this->user->lang)) { - if (!is_string($value)) + foreach ($this->user->lang as $key => $value) { - continue; + if (!is_string($value)) + { + continue; + } + + $vars['L_' . strtoupper($key)] = $value; + $vars['LA_' . strtoupper($key)] = addslashes($value); } - $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(), + ) + ); } - $vars = array_merge( - $vars, - $this->context->get_rootref(), - array( - '_phpbb_blocks' => $this->context->get_tpldata(), - ) - ); - // Must do this so that 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) diff --git a/tests/template/template_test_case.php b/tests/template/template_test_case.php index e39896b970..5ff15fff53 100644 --- a/tests/template/template_test_case.php +++ b/tests/template/template_test_case.php @@ -77,32 +77,15 @@ class phpbb_template_template_test_case extends phpbb_test_case // Test the engine can be used $this->setup_engine(); - $template_cache_dir = dirname($this->template->cachepath); - if (!is_writable($template_cache_dir)) - { - $this->markTestSkipped("Template cache directory ({$template_cache_dir}) is not writable."); - } - - foreach (glob($this->template->cachepath . '*') as $file) - { - unlink($file); - } - - $this->setup_engine(); + $this->template->clear_cache(); } protected function tearDown() { - if (is_object($this->template)) - { - foreach (glob($this->template->cachepath . '*') as $file) - { - unlink($file); - } - } + $this->template->clear_cache(); } - protected function run_template($file, array $vars, array $block_vars, array $destroy, $expected, $cache_file) + protected function run_template($file, array $vars, array $block_vars, array $destroy, $expected) { $this->template->set_filenames(array('test' => $file)); $this->template->assign_vars($vars); @@ -123,22 +106,10 @@ class phpbb_template_template_test_case extends phpbb_test_case try { $this->assertEquals($expected, $this->display('test'), "Testing $file"); - $this->assertFileExists($cache_file); } catch (ErrorException $e) { - if (file_exists($cache_file)) - { - copy($cache_file, str_replace('ctpl_', 'tests_ctpl_', $cache_file)); - } throw $e; } - - // For debugging. - // When testing eval path the cache file may not exist. - if (self::PRESERVE_CACHE && file_exists($cache_file)) - { - copy($cache_file, str_replace('ctpl_', 'tests_ctpl_', $cache_file)); - } } } From 881bc60fbc4ae8739083db65c814bda0708155b9 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 24 Jun 2013 21:55:45 -0500 Subject: [PATCH 033/156] [feature/twig] Delete invalid constructs template test Invalid tags is no longer a valid test (invalid tags are ignored) Twig contains tests for loading files, so we should not need to test this PHPBB3-11598 --- tests/template/invalid_constructs_test.php | 87 ------------------- .../invalid/include_nonexistent_file.html | 1 - .../templates/invalid/unknown_tag.html | 1 - 3 files changed, 89 deletions(-) delete mode 100644 tests/template/invalid_constructs_test.php delete mode 100644 tests/template/templates/invalid/include_nonexistent_file.html delete mode 100644 tests/template/templates/invalid/unknown_tag.html diff --git a/tests/template/invalid_constructs_test.php b/tests/template/invalid_constructs_test.php deleted file mode 100644 index 19d192b8b6..0000000000 --- a/tests/template/invalid_constructs_test.php +++ /dev/null @@ -1,87 +0,0 @@ -template->cachepath . str_replace('/', '.', $file) . '.php'; - - $this->assertFileNotExists($cache_file); - - $expected = file_get_contents(dirname(__FILE__) . '/templates/' . $expected); - // apparently the template engine does not put - // the trailing newline into compiled templates - $expected = trim($expected); - $this->run_template($file, $vars, $block_vars, $destroy, $expected, $cache_file); - } - - /** - * @dataProvider template_data_error - */ - public function test_template_error($description, $file, $vars, $block_vars, $destroy, $error, $expected) - { - $cache_file = $this->template->cachepath . str_replace('/', '.', $file) . '.php'; - - $this->assertFileNotExists($cache_file); - - $expected = file_get_contents(dirname(__FILE__) . '/templates/' . $expected); - // apparently the template engine does not put - // the trailing newline into compiled templates - $expected = trim($expected); - $this->setExpectedTriggerError($error, $expected); - $this->run_template($file, $vars, $block_vars, $destroy, '', $cache_file); - } -} diff --git a/tests/template/templates/invalid/include_nonexistent_file.html b/tests/template/templates/invalid/include_nonexistent_file.html deleted file mode 100644 index 617d2fdaaa..0000000000 --- a/tests/template/templates/invalid/include_nonexistent_file.html +++ /dev/null @@ -1 +0,0 @@ - diff --git a/tests/template/templates/invalid/unknown_tag.html b/tests/template/templates/invalid/unknown_tag.html deleted file mode 100644 index 1489e5e31a..0000000000 --- a/tests/template/templates/invalid/unknown_tag.html +++ /dev/null @@ -1 +0,0 @@ - From d986e124fe03f7a924bec90c49738db0327f8ad5 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 24 Jun 2013 21:57:01 -0500 Subject: [PATCH 034/156] [feature/twig] Delete renderer_eval_test.php No longer necessary PHPBB3-11598 --- tests/template/renderer_eval_test.php | 31 --------------------------- 1 file changed, 31 deletions(-) delete mode 100644 tests/template/renderer_eval_test.php diff --git a/tests/template/renderer_eval_test.php b/tests/template/renderer_eval_test.php deleted file mode 100644 index 7ebb8b9bda..0000000000 --- a/tests/template/renderer_eval_test.php +++ /dev/null @@ -1,31 +0,0 @@ -">'; - $valid_code = ''; - $context = new phpbb_template_context(); - $template = new phpbb_template_renderer_eval($compiled_code, NULL); - ob_start(); - try - { - $template->render($context, array()); - } - catch (Exception $exception) - { - ob_end_clean(); - throw $exception; - } - $output = ob_get_clean(); - $this->assertEquals($valid_code, $output); - } -} From 814d57d201d654ce0510ede5b43cfad6b06d372e Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 24 Jun 2013 21:58:09 -0500 Subject: [PATCH 035/156] [feature/twig] Delete template_compile_test.php No longer necessary PHPBB3-11598 --- tests/template/template_compile_test.php | 31 ------------------------ 1 file changed, 31 deletions(-) delete mode 100644 tests/template/template_compile_test.php diff --git a/tests/template/template_compile_test.php b/tests/template/template_compile_test.php deleted file mode 100644 index 7393fc1747..0000000000 --- a/tests/template/template_compile_test.php +++ /dev/null @@ -1,31 +0,0 @@ -template_compile = new phpbb_template_compile(false, null, $this->style_resource_locator, ''); - $this->template_path = dirname(__FILE__) . '/templates'; - } - - public function test_in_phpbb() - { - $output = $this->template_compile->compile_file($this->template_path . '/trivial.html'); - $this->assertTrue(strlen($output) > 0); - $statements = explode(';', $output); - $first_statement = $statements[0]; - $this->assertTrue(!!preg_match('#if.*defined.*IN_PHPBB.*exit#', $first_statement)); - } -} From 3ca99f8122c149a66f59dbf3c9884c095db7ad3c Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 24 Jun 2013 22:37:58 -0500 Subject: [PATCH 036/156] [feature/twig] Append assets_version to includejs tag Some fixes for main template parser PHPBB3-11598 --- phpBB/includes/template/twig/environment.php | 26 +++++++++++++++++++ phpBB/includes/template/twig/node/event.php | 1 + .../includes/template/twig/node/includejs.php | 11 ++++++-- .../template/twig/tokenparser/includejs.php | 2 +- phpBB/includes/template/twig/twig.php | 21 ++++++++------- 5 files changed, 49 insertions(+), 12 deletions(-) diff --git a/phpBB/includes/template/twig/environment.php b/phpBB/includes/template/twig/environment.php index 4c7f0002ba..616321e15a 100644 --- a/phpBB/includes/template/twig/environment.php +++ b/phpBB/includes/template/twig/environment.php @@ -20,6 +20,9 @@ class phpbb_template_twig_environment extends Twig_Environment /** @var array */ protected $phpbbExtensions; + /** @var phpbb_config */ + protected $phpbbConfig; + /** @var array **/ protected $namespaceLookUpOrder = array('__main__'); @@ -62,6 +65,29 @@ class phpbb_template_twig_environment extends Twig_Environment return $this; } + /** + * Get phpBB config + * + * @return phpbb_config + */ + public function get_phpbb_config() + { + return $this->phpbbConfig; + } + + /** + * Set phpBB config + * + * @param phpbb_config $config + * @return Twig_Environment + */ + public function set_phpbb_config($config) + { + $this->phpbbConfig = $config; + + return $this; + } + /** * Get the namespace look up order * diff --git a/phpBB/includes/template/twig/node/event.php b/phpBB/includes/template/twig/node/event.php index 12e6ef1329..358c68dae5 100644 --- a/phpBB/includes/template/twig/node/event.php +++ b/phpBB/includes/template/twig/node/event.php @@ -9,6 +9,7 @@ class phpbb_template_twig_node_event extends Twig_Node { + /** @var Twig_Environment */ protected $environment; public function __construct(Twig_Node_Expression $expr, phpbb_template_twig_environment $environment, $lineno, $tag = null) diff --git a/phpBB/includes/template/twig/node/includejs.php b/phpBB/includes/template/twig/node/includejs.php index 881636a326..f4c26affa4 100644 --- a/phpBB/includes/template/twig/node/includejs.php +++ b/phpBB/includes/template/twig/node/includejs.php @@ -9,8 +9,13 @@ class phpbb_template_twig_node_includejs extends Twig_Node { - public function __construct(Twig_Node_Expression $expr, $lineno, $tag = null) + /** @var Twig_Environment */ + 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); } @@ -23,10 +28,12 @@ class phpbb_template_twig_node_includejs extends Twig_Node { $compiler->addDebugInfo($this); + $config = $this->environment->get_phpbb_config(); + $compiler ->write("\$context['SCRIPTS'] .= '';\n\n") ; } } diff --git a/phpBB/includes/template/twig/tokenparser/includejs.php b/phpBB/includes/template/twig/tokenparser/includejs.php index efa8692f4b..0b46f315d2 100644 --- a/phpBB/includes/template/twig/tokenparser/includejs.php +++ b/phpBB/includes/template/twig/tokenparser/includejs.php @@ -23,7 +23,7 @@ class phpbb_template_twig_tokenparser_includejs extends Twig_TokenParser $stream = $this->parser->getStream(); $stream->expect(Twig_Token::BLOCK_END_TYPE); - return new phpbb_template_twig_node_includejs($expr, $token->getLine(), $this->getTag()); + return new phpbb_template_twig_node_includejs($expr, $this->parser->getEnvironment(), $token->getLine(), $this->getTag()); } /** diff --git a/phpBB/includes/template/twig/twig.php b/phpBB/includes/template/twig/twig.php index e2c9afbc78..af8ab615e6 100644 --- a/phpBB/includes/template/twig/twig.php +++ b/phpBB/includes/template/twig/twig.php @@ -127,6 +127,9 @@ class phpbb_template_twig implements phpbb_template $this->twig->set_phpbb_extensions($this->extension_manager->all_enabled()); } + // Set config + $this->twig->set_phpbb_config($this->config); + // Clear previous cache files (while WIP) // @todo remove $this->clear_cache(); @@ -187,7 +190,7 @@ class phpbb_template_twig implements phpbb_template // Add admin namespace // @todo use phpbb_admin path - $loader->addPath($this->phpbb_root_path . 'adm/style/', 'admin'); + $this->twig->getLoader()->addPath($this->phpbb_root_path . 'adm/style/', 'admin'); // Add all namespaces for all extensions if ($this->extension_manager instanceof phpbb_extension_manager) @@ -439,16 +442,16 @@ class phpbb_template_twig implements phpbb_template $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(), - ) - ); } + $vars = array_merge( + $vars, + $this->context->get_rootref(), + array( + '_phpbb_blocks' => $this->context->get_tpldata(), + ) + ); + // Must do this so that 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) From 8bda356dabae89b8dff62796a6bf6e9b57cd85c1 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 24 Jun 2013 22:40:17 -0500 Subject: [PATCH 037/156] [feature/twig] Correct includejs test PHPBB3-11598 --- tests/template/template_includejs_test.php | 15 +++++++-------- tests/template/templates/includejs.html | 12 ++++++------ 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/tests/template/template_includejs_test.php b/tests/template/template_includejs_test.php index 22b020208b..c0169bd385 100644 --- a/tests/template/template_includejs_test.php +++ b/tests/template/template_includejs_test.php @@ -18,16 +18,15 @@ class phpbb_template_template_includejs_test extends phpbb_template_template_tes // Prepare correct result $scripts = array( - '', - '', - '', - '', - '', - '', + '', + '', + '', + '', + '', + '', ); // Run test - $cache_file = $this->template->cachepath . 'includejs.html.php'; - $this->run_template('includejs.html', array('PARENT' => 'parent_only.js', 'SUBDIR' => 'subdir', 'EXT' => 'js'), array(), array(), implode('', $scripts), $cache_file); + $this->run_template('includejs.html', array('PARENT' => 'parent_only.js', 'SUBDIR' => 'subdir', 'EXT' => 'js'), array(), array(), implode('', $scripts)); } } diff --git a/tests/template/templates/includejs.html b/tests/template/templates/includejs.html index ef73700eeb..eca6e90637 100644 --- a/tests/template/templates/includejs.html +++ b/tests/template/templates/includejs.html @@ -1,8 +1,8 @@ - - + + - - - - + + + + {SCRIPTS} From 92391d2f4f5b9a01d7407da7c00102844620761f Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 24 Jun 2013 22:44:12 -0500 Subject: [PATCH 038/156] [feature/twig] Correct template_inheritance_test.php PHPBB3-11598 --- tests/template/template_inheritance_test.php | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/tests/template/template_inheritance_test.php b/tests/template/template_inheritance_test.php index febfed9ef0..cc71ff99e0 100644 --- a/tests/template/template_inheritance_test.php +++ b/tests/template/template_inheritance_test.php @@ -50,15 +50,6 @@ class phpbb_template_template_inheritance_test extends phpbb_template_template_t */ public function test_template($name, $file, array $vars, array $block_vars, array $destroy, $expected) { - $cache_file = $this->template->cachepath . str_replace('/', '.', $file) . '.php'; - - $this->assertFileNotExists($cache_file); - - $this->run_template($file, $vars, $block_vars, $destroy, $expected, $cache_file); - - // Reset the engine state - $this->setup_engine(); - - $this->run_template($file, $vars, $block_vars, $destroy, $expected, $cache_file); + $this->run_template($file, $vars, $block_vars, $destroy, $expected); } } From 1d6a51f51ab0823643a7ad671991fd229b6caef8 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 24 Jun 2013 22:44:57 -0500 Subject: [PATCH 039/156] [feature/twig] Delete template_locate_test.php No longer needed PHPBB3-11598 --- tests/template/template_locate_test.php | 68 ------------------------- 1 file changed, 68 deletions(-) delete mode 100644 tests/template/template_locate_test.php diff --git a/tests/template/template_locate_test.php b/tests/template/template_locate_test.php deleted file mode 100644 index 851dcae8ea..0000000000 --- a/tests/template/template_locate_test.php +++ /dev/null @@ -1,68 +0,0 @@ -test_path . '/parent_templates/parent_only.html', - 'parent_only.html', - false, - true, - ), - array( - 'simple inheritance - only child template exists', - $this->test_path . '/templates/child_only.html', - 'child_only.html', - false, - true, - ), - array( - 'simple inheritance - both parent and child templates exist', - $this->test_path . '/templates/parent_and_child.html', - 'parent_and_child.html', - false, - true, - ), - array( - 'find first template - only child template exists in main style', - 'child_only.html', - array('parent_only.html', 'child_only.html'), - false, - false, - ), - array( - 'find first template - both templates exist in main style', - 'parent_and_child.html', - array('parent_and_child.html', 'child_only.html'), - false, - false, - ), - ); - } - - /** - * @dataProvider template_data - */ - public function test_template($name, $expected, $files, $return_default, $return_full_path) - { - // Reset the engine state - $this->setup_engine(); - - // Locate template - $result = $this->style_resource_locator->get_first_template_location($files, $return_default, $return_full_path); - $this->assertSame($expected, $result); - } -} From dabc0edea2ebf9a15aad944935628fa558a8eeec Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 24 Jun 2013 22:50:09 -0500 Subject: [PATCH 040/156] [feature/twig] Delete template_spacing_test.php No longer needed PHPBB3-11598 --- tests/template/template_spacing_test.php | 87 ------------------------ 1 file changed, 87 deletions(-) delete mode 100644 tests/template/template_spacing_test.php diff --git a/tests/template/template_spacing_test.php b/tests/template/template_spacing_test.php deleted file mode 100644 index b0f44bc827..0000000000 --- a/tests/template/template_spacing_test.php +++ /dev/null @@ -1,87 +0,0 @@ - '{}', - ), - array(), - array(), - '|{}| -{}|{}| -|{} -
test
', - ), - ); - } - - /** - * @dataProvider template_data - */ - public function test_template($desc, $dataset, $style_names, $file, array $vars, array $block_vars, array $destroy, $expected) - { - // Run test - $cache_file = $this->template->cachepath . str_replace('/', '.', $file) . '.php'; - $this->run_template($file, $vars, $block_vars, $destroy, $expected, $cache_file); - } - - /** - * @dataProvider template_data - */ - public function test_event($desc, $dataset, $style_names, $file, array $vars, array $block_vars, array $destroy, $expected) - { - // Reset the engine state - $this->setup_engine_for_events($dataset, $style_names); - - // Run test - $cache_file = $this->template->cachepath . str_replace('/', '.', $file) . '.php'; - $this->run_template($file, $vars, $block_vars, $destroy, $expected, $cache_file); - } - - protected function setup_engine_for_events($dataset, $style_names, array $new_config = array()) - { - global $phpbb_root_path, $phpEx, $user; - - $defaults = $this->config_defaults(); - $config = new phpbb_config(array_merge($defaults, $new_config)); - - $this->template_path = dirname(__FILE__) . "/datasets/$dataset/styles/silver/template"; - $this->style_resource_locator = new phpbb_style_resource_locator(); - $this->extension_manager = new phpbb_mock_filesystem_extension_manager( - dirname(__FILE__) . "/datasets/$dataset/" - ); - $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, ''); - } -} From fe61527c5245d3d627e51c96b7b482c526b7dd28 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 24 Jun 2013 23:29:22 -0500 Subject: [PATCH 041/156] [feature/twig] Remove duplicate test calls PHPBB3-11598 --- tests/template/template_test.php | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/tests/template/template_test.php b/tests/template/template_test.php index a3c0b69123..a4748eb0b3 100644 --- a/tests/template/template_test.php +++ b/tests/template/template_test.php @@ -340,16 +340,7 @@ class phpbb_template_template_test extends phpbb_template_template_test_case */ public function test_template($file, array $vars, array $block_vars, array $destroy, $expected) { - $cache_file = $this->template->cachepath . str_replace('/', '.', $file) . '.php'; - - $this->assertFileNotExists($cache_file); - - $this->run_template($file, $vars, $block_vars, $destroy, $expected, $cache_file); - - // Reset the engine state - $this->setup_engine(); - - $this->run_template($file, $vars, $block_vars, $destroy, $expected, $cache_file); + $this->run_template($file, $vars, $block_vars, $destroy, $expected); } /** @@ -423,11 +414,7 @@ class phpbb_template_template_test extends phpbb_template_template_test_case { $this->setup_engine(array('tpl_allow_php' => true)); - $cache_file = $this->template->cachepath . 'php.html.php'; - - $this->assertFileNotExists($cache_file); - - $this->run_template('php.html', array(), array(), array(), 'test', $cache_file); + $this->run_template('php.html', array(), array(), array(), 'test'); } public function alter_block_array_data() From ea785efb30ced6ab399b290df6f202cb97315f80 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Tue, 25 Jun 2013 14:22:40 -0500 Subject: [PATCH 042/156] [feature/twig] PHP token support PHPBB3-11598 --- phpBB/includes/template/twig/environment.php | 2 + phpBB/includes/template/twig/extension.php | 1 + phpBB/includes/template/twig/node/php.php | 40 ++++++++++++++++ .../template/twig/tokenparser/php.php | 46 +++++++++++++++++++ 4 files changed, 89 insertions(+) create mode 100644 phpBB/includes/template/twig/node/php.php create mode 100644 phpBB/includes/template/twig/tokenparser/php.php diff --git a/phpBB/includes/template/twig/environment.php b/phpBB/includes/template/twig/environment.php index 616321e15a..d9b56a56f6 100644 --- a/phpBB/includes/template/twig/environment.php +++ b/phpBB/includes/template/twig/environment.php @@ -39,6 +39,8 @@ class phpbb_template_twig_environment extends Twig_Environment return false; } + // @todo correct cache file name handling + return $this->getCache() . '/' . preg_replace('#[^a-zA-Z0-9_/]#', '_', $name) . '.php'; } diff --git a/phpBB/includes/template/twig/extension.php b/phpBB/includes/template/twig/extension.php index ff37a38c29..c9b719546f 100644 --- a/phpBB/includes/template/twig/extension.php +++ b/phpBB/includes/template/twig/extension.php @@ -31,6 +31,7 @@ class phpbb_template_twig_extension extends Twig_Extension new phpbb_template_twig_tokenparser_include, new phpbb_template_twig_tokenparser_includejs, new phpbb_template_twig_tokenparser_event, + new phpbb_template_twig_tokenparser_php, ); } diff --git a/phpBB/includes/template/twig/node/php.php b/phpBB/includes/template/twig/node/php.php new file mode 100644 index 0000000000..cf60ef33fc --- /dev/null +++ b/phpBB/includes/template/twig/node/php.php @@ -0,0 +1,40 @@ +environment = $environment; + + parent::__construct(array('text' => $text), array(), $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param Twig_Compiler A Twig_Compiler instance + */ + public function compile(Twig_Compiler $compiler) + { + $compiler->addDebugInfo($this); + + $config = $this->environment->get_phpbb_config(); + + if ($config['tpl_allow_php']) + { + $compiler + ->raw($this->getNode('text')->getAttribute('data')) + ; + } + } +} diff --git a/phpBB/includes/template/twig/tokenparser/php.php b/phpBB/includes/template/twig/tokenparser/php.php new file mode 100644 index 0000000000..7db57081e2 --- /dev/null +++ b/phpBB/includes/template/twig/tokenparser/php.php @@ -0,0 +1,46 @@ +parser->getStream(); + + $stream->expect(Twig_Token::BLOCK_END_TYPE); + + $body = $this->parser->subparse(array($this, 'decideEnd'), true); + + $stream->expect(Twig_Token::BLOCK_END_TYPE); + + return new phpbb_template_twig_node_php($body, $this->parser->getEnvironment(), $token->getLine(), $this->getTag()); + } + + public function decideEnd(Twig_Token $token) + { + return $token->test('ENDPHP'); + } + + /** + * Gets the tag name associated with this token parser. + * + * @return string The tag name + */ + public function getTag() + { + return 'PHP'; + } +} From 68225d9f298f5f9de5f931b28241329931d16574 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Tue, 25 Jun 2013 14:58:55 -0500 Subject: [PATCH 043/156] [feature/twig] Pass parameters required to twig env via constructor Instead of creating set functions PHPBB3-11598 --- phpBB/includes/template/twig/environment.php | 52 +++++++++----------- phpBB/includes/template/twig/twig.php | 27 +++++----- 2 files changed, 36 insertions(+), 43 deletions(-) diff --git a/phpBB/includes/template/twig/environment.php b/phpBB/includes/template/twig/environment.php index d9b56a56f6..5032df9483 100644 --- a/phpBB/includes/template/twig/environment.php +++ b/phpBB/includes/template/twig/environment.php @@ -18,14 +18,26 @@ if (!defined('IN_PHPBB')) class phpbb_template_twig_environment extends Twig_Environment { /** @var array */ - protected $phpbbExtensions; + protected $phpbb_extensions; /** @var phpbb_config */ - protected $phpbbConfig; + protected $phpbb_config; + + /** @var string */ + protected $phpbb_root_path; /** @var array **/ protected $namespaceLookUpOrder = array('__main__'); + public function __construct(phpbb_config $phpbb_config, $phpbb_extensions, $phpbb_root_path, Twig_LoaderInterface $loader = null, $options = array()) + { + $this->phpbb_config = $phpbb_config; + $this->phpbb_extensions = $phpbb_extensions; + $this->phpbb_root_path = $phpbb_root_path; + + return parent::__construct($loader, $options); + } + /** * Gets the cache filename for a given template. * @@ -51,20 +63,7 @@ class phpbb_template_twig_environment extends Twig_Environment */ 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; + return $this->phpbb_extensions; } /** @@ -74,20 +73,17 @@ class phpbb_template_twig_environment extends Twig_Environment */ public function get_phpbb_config() { - return $this->phpbbConfig; + return $this->phpbb_config; } - /** - * Set phpBB config - * - * @param phpbb_config $config - * @return Twig_Environment - */ - public function set_phpbb_config($config) - { - $this->phpbbConfig = $config; - - return $this; + /** + * Get the phpBB root path + * + * @return string + */ + public function get_phpbb_root_path() + { + return $this->phpbb_root_path; } /** diff --git a/phpBB/includes/template/twig/twig.php b/phpBB/includes/template/twig/twig.php index af8ab615e6..97bba3f433 100644 --- a/phpBB/includes/template/twig/twig.php +++ b/phpBB/includes/template/twig/twig.php @@ -114,21 +114,18 @@ class phpbb_template_twig implements phpbb_template // Initiate the loader, __main__ namespace paths will be setup later in set_style_names() $loader = new Twig_Loader_Filesystem(''); - $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()); - } - - // Set config - $this->twig->set_phpbb_config($this->config); + $this->twig = new phpbb_template_twig_environment( + $this->config, + ($this->extension_manager) ? $this->extension_manager->all_enabled() : array(), + $this->phpbb_root_path, + $loader, + array( + 'cache' => $this->cachepath, + 'debug' => true, // @todo + 'auto_reload' => true, // @todo + 'autoescape' => false, + ) + ); // Clear previous cache files (while WIP) // @todo remove From 99b776a4e56a9144bddc153ea993a96588b1c73b Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Tue, 25 Jun 2013 14:59:41 -0500 Subject: [PATCH 044/156] [feature/twig] Add a comment to tpl output if PHP used, but disabled PHPBB3-11598 --- phpBB/includes/template/twig/node/php.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/phpBB/includes/template/twig/node/php.php b/phpBB/includes/template/twig/node/php.php index cf60ef33fc..83481b1d69 100644 --- a/phpBB/includes/template/twig/node/php.php +++ b/phpBB/includes/template/twig/node/php.php @@ -28,13 +28,17 @@ class phpbb_template_twig_node_php extends Twig_Node { $compiler->addDebugInfo($this); - $config = $this->environment->get_phpbb_config(); - - if ($config['tpl_allow_php']) + if (!$config['tpl_allow_php']) { $compiler - ->raw($this->getNode('text')->getAttribute('data')) + ->write("// PHP Disabled\n") ; + + return; } + + $compiler + ->raw($this->getNode('text')->getAttribute('data')) + ; } } From e227f05e9a79994046a13dccefcd032b3011ab5b Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Tue, 25 Jun 2013 15:00:15 -0500 Subject: [PATCH 045/156] [feature/twig] INCLUDEPHP token support PHPBB3-11598 --- phpBB/includes/template/twig/extension.php | 1 + .../template/twig/node/includephp.php | 66 +++++++++++++++++++ .../template/twig/tokenparser/includephp.php | 47 +++++++++++++ 3 files changed, 114 insertions(+) create mode 100644 phpBB/includes/template/twig/node/includephp.php create mode 100644 phpBB/includes/template/twig/tokenparser/includephp.php diff --git a/phpBB/includes/template/twig/extension.php b/phpBB/includes/template/twig/extension.php index c9b719546f..9d465a4db8 100644 --- a/phpBB/includes/template/twig/extension.php +++ b/phpBB/includes/template/twig/extension.php @@ -31,6 +31,7 @@ class phpbb_template_twig_extension extends Twig_Extension new phpbb_template_twig_tokenparser_include, new phpbb_template_twig_tokenparser_includejs, new phpbb_template_twig_tokenparser_event, + new phpbb_template_twig_tokenparser_includephp, new phpbb_template_twig_tokenparser_php, ); } diff --git a/phpBB/includes/template/twig/node/includephp.php b/phpBB/includes/template/twig/node/includephp.php new file mode 100644 index 0000000000..0f964556f0 --- /dev/null +++ b/phpBB/includes/template/twig/node/includephp.php @@ -0,0 +1,66 @@ +environment = $environment; + + parent::__construct(array('expr' => $expr), array('ignore_missing' => (Boolean) $ignoreMissing), $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param Twig_Compiler A Twig_Compiler instance + */ + public function compile(Twig_Compiler $compiler) + { + $compiler->addDebugInfo($this); + + $config = $this->environment->get_phpbb_config(); + + if (!$config['tpl_allow_php']) + { + $compiler + ->write("// INCLUDEPHP Disabled\n") + ; + + return; + } + + if ($this->getAttribute('ignore_missing')) { + $compiler + ->write("try {\n") + ->indent() + ; + } + + $compiler + ->write("include(\$this->getEnvironment()->get_phpbb_root_path() . ") + ->subcompile($this->getNode('expr'), true) + ->raw(");\n") + ; + + if ($this->getAttribute('ignore_missing')) { + $compiler + ->outdent() + ->write("} catch (Twig_Error_Loader \$e) {\n") + ->indent() + ->write("// ignore missing template\n") + ->outdent() + ->write("}\n\n") + ; + } + } +} diff --git a/phpBB/includes/template/twig/tokenparser/includephp.php b/phpBB/includes/template/twig/tokenparser/includephp.php new file mode 100644 index 0000000000..a81d663c09 --- /dev/null +++ b/phpBB/includes/template/twig/tokenparser/includephp.php @@ -0,0 +1,47 @@ +parser->getExpressionParser()->parseExpression(); + + $stream = $this->parser->getStream(); + + $ignoreMissing = false; + if ($stream->test(Twig_Token::NAME_TYPE, 'ignore')) { + $stream->next(); + $stream->expect(Twig_Token::NAME_TYPE, 'missing'); + + $ignoreMissing = true; + } + + $stream->expect(Twig_Token::BLOCK_END_TYPE); + + return new phpbb_template_twig_node_includephp($expr, $this->parser->getEnvironment(), $ignoreMissing, $token->getLine(), $this->getTag()); + } + + /** + * Gets the tag name associated with this token parser. + * + * @return string The tag name + */ + public function getTag() + { + return 'INCLUDEPHP'; + } +} From 8bccba1a2fb5479ead0594b09dad95d4d22a5cec Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Tue, 25 Jun 2013 16:27:58 -0500 Subject: [PATCH 046/156] [feature/twig] INCLUDEPHP token, replace variable usage with $context I could find no better way to do this... PHPBB3-11598 --- phpBB/includes/template/twig/node/includephp.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/phpBB/includes/template/twig/node/includephp.php b/phpBB/includes/template/twig/node/includephp.php index 0f964556f0..6e77fac55d 100644 --- a/phpBB/includes/template/twig/node/includephp.php +++ b/phpBB/includes/template/twig/node/includephp.php @@ -46,10 +46,13 @@ class phpbb_template_twig_node_includephp extends Twig_Node ; } + // Replace variables in the expression + $expr = preg_replace('#{{ ([a-zA-Z0-9_]+) }}#', '\' . ((isset($context["$1"])) ? $context["$1"] : null) . \'', $this->getNode('expr')->getAttribute('value')); + $compiler - ->write("include(\$this->getEnvironment()->get_phpbb_root_path() . ") - ->subcompile($this->getNode('expr'), true) - ->raw(");\n") + ->write("require(\$this->getEnvironment()->get_phpbb_root_path() . '") + ->raw($expr) + ->raw("');\n") ; if ($this->getAttribute('ignore_missing')) { From 1c8c03c4dbd74f2f2abf6d2968bc33a234df5a4e Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Tue, 25 Jun 2013 16:51:50 -0500 Subject: [PATCH 047/156] [feature/twig] INCLUDEPHP token abs paths & fix test PHPBB3-11598 --- phpBB/includes/template/twig/node/includephp.php | 14 +++++++++++--- tests/template/includephp_test.php | 13 ++++--------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/phpBB/includes/template/twig/node/includephp.php b/phpBB/includes/template/twig/node/includephp.php index 6e77fac55d..5315d136d7 100644 --- a/phpBB/includes/template/twig/node/includephp.php +++ b/phpBB/includes/template/twig/node/includephp.php @@ -50,9 +50,17 @@ class phpbb_template_twig_node_includephp extends Twig_Node $expr = preg_replace('#{{ ([a-zA-Z0-9_]+) }}#', '\' . ((isset($context["$1"])) ? $context["$1"] : null) . \'', $this->getNode('expr')->getAttribute('value')); $compiler - ->write("require(\$this->getEnvironment()->get_phpbb_root_path() . '") - ->raw($expr) - ->raw("');\n") + ->write("if (phpbb_is_absolute('$expr')) {\n") + ->indent() + ->write("require('$expr');\n") + ->outdent() + ->write("} else {\n") + ->indent() + ->write("require(\$this->getEnvironment()->get_phpbb_root_path() . '") + ->raw($expr) + ->raw("');\n") + ->outdent() + ->write("}\n") ; if ($this->getAttribute('ignore_missing')) { diff --git a/tests/template/includephp_test.php b/tests/template/includephp_test.php index f1012b6939..edf1e40bb8 100644 --- a/tests/template/includephp_test.php +++ b/tests/template/includephp_test.php @@ -15,9 +15,7 @@ class phpbb_template_includephp_test extends phpbb_template_template_test_case { $this->setup_engine(array('tpl_allow_php' => true)); - $cache_file = $this->template->cachepath . 'includephp_relative.html.php'; - - $this->run_template('includephp_relative.html', array(), array(), array(), "Path is relative to board root.\ntesting included php", $cache_file); + $this->run_template('includephp_relative.html', array(), array(), array(), "Path is relative to board root.\ntesting included php"); $this->template->set_filenames(array('test' => 'includephp_relative.html')); $this->assertEquals("Path is relative to board root.\ntesting included php", $this->display('test'), "Testing INCLUDEPHP"); @@ -27,9 +25,7 @@ class phpbb_template_includephp_test extends phpbb_template_template_test_case { $this->setup_engine(array('tpl_allow_php' => true)); - $cache_file = $this->template->cachepath . 'includephp_variables.html.php'; - - $this->run_template('includephp_variables.html', array('TEMPLATES' => 'templates'), array(), array(), "Path includes variables.\ntesting included php", $cache_file); + $this->run_template('includephp_variables.html', array('TEMPLATES' => 'templates'), array(), array(), "Path includes variables.\ntesting included php"); $this->template->set_filenames(array('test' => 'includephp_variables.html')); $this->assertEquals("Path includes variables.\ntesting included php", $this->display('test'), "Testing INCLUDEPHP"); @@ -37,7 +33,7 @@ class phpbb_template_includephp_test extends phpbb_template_template_test_case public function test_includephp_absolute() { - $path_to_php = dirname(__FILE__) . '/templates/_dummy_include.php.inc'; + $path_to_php = str_replace('\\', '/', dirname(__FILE__)) . '/templates/_dummy_include.php.inc'; $this->assertTrue(phpbb_is_absolute($path_to_php)); $template_text = "Path is absolute.\n"; @@ -49,9 +45,8 @@ class phpbb_template_includephp_test extends phpbb_template_template_test_case $this->setup_engine(array('tpl_allow_php' => true)); $this->style->set_custom_style('tests', $cache_dir, array(), ''); - $cache_file = $this->template->cachepath . 'includephp_absolute.html.php'; - $this->run_template('includephp_absolute.html', array(), array(), array(), "Path is absolute.\ntesting included php", $cache_file); + $this->run_template('includephp_absolute.html', array(), array(), array(), "Path is absolute.\ntesting included php"); $this->template->set_filenames(array('test' => 'includephp_absolute.html')); $this->assertEquals("Path is absolute.\ntesting included php", $this->display('test'), "Testing INCLUDEPHP"); From 3766b736da96cfbed3a234235f977f8f56c60632 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Tue, 25 Jun 2013 18:06:45 -0500 Subject: [PATCH 048/156] [feature/twig] Don't require phpbb_config, some tests pass null PHPBB3-11598 --- phpBB/includes/template/twig/environment.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/template/twig/environment.php b/phpBB/includes/template/twig/environment.php index 5032df9483..0947a902d0 100644 --- a/phpBB/includes/template/twig/environment.php +++ b/phpBB/includes/template/twig/environment.php @@ -29,7 +29,7 @@ class phpbb_template_twig_environment extends Twig_Environment /** @var array **/ protected $namespaceLookUpOrder = array('__main__'); - public function __construct(phpbb_config $phpbb_config, $phpbb_extensions, $phpbb_root_path, Twig_LoaderInterface $loader = null, $options = array()) + public function __construct($phpbb_config, $phpbb_extensions, $phpbb_root_path, Twig_LoaderInterface $loader = null, $options = array()) { $this->phpbb_config = $phpbb_config; $this->phpbb_extensions = $phpbb_extensions; From 25f0ee9fb61ad1d5c039e1732bec53decb28fe78 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Tue, 25 Jun 2013 19:22:23 -0500 Subject: [PATCH 049/156] [feature/twig] Fixing template events test (and behavior) According to the test, template event behavior was never correct. Only ONE template event file is supposed to be included from EACH extension. As it was before, EVERY matching template event file from each extension was included (this was how it was designed). E.g. Event call in prosilver "foo" Extension has template "foo" in prosilver AND all foo from all would be included, then foo from prosilver would be included This was clearly not designed correctly as only the most specific event file from each extension should be loaded, otherwise events could only ever be put in a single style tree (either only all, or only prosilver and subsilver2 and any style that inherits from neither of those). Otherwise the events would be duplicated on output (which is clearly not desirable). The Twig behavior already was correct as I designed it, so only the one most specific template event file found would be included from each extension. The tests had to be updated for the correct expected output. PHPBB3-11598 --- tests/template/template_events_test.php | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/tests/template/template_events_test.php b/tests/template/template_events_test.php index 571e55e04e..07181fcc4d 100644 --- a/tests/template/template_events_test.php +++ b/tests/template/template_events_test.php @@ -54,11 +54,9 @@ class phpbb_template_template_events_test extends phpbb_template_template_test_c array(), array(), array(), -'Kappa test event in all -Omega test event in all -Zeta test event in all -Kappa test event in silver -Omega test event in silver', +'Kappa test event in silver +Omega test event in silver +Zeta test event in all', ), array( 'Template event with inheritance - child', @@ -68,10 +66,9 @@ Omega test event in silver', array(), array(), array(), -'Kappa test event in all -Omega test event in all -Zeta test event in all -Kappa test event in silver_inherit', +'Kappa test event in silver_inherit +Omega test event in silver +Zeta test event in all', ), array( 'Definition in parent style', @@ -95,8 +92,7 @@ Kappa test event in silver_inherit', $this->setup_engine_for_events($dataset, $style_names); // Run test - $cache_file = $this->template->cachepath . str_replace('/', '.', $file) . '.php'; - $this->run_template($file, $vars, $block_vars, $destroy, $expected, $cache_file); + $this->run_template($file, $vars, $block_vars, $destroy, $expected); } protected function setup_engine_for_events($dataset, $style_names, array $new_config = array()) From 7a9aec5fda8b5be0aba1918b58b3972f7eed906f Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Tue, 25 Jun 2013 19:23:42 -0500 Subject: [PATCH 050/156] [feature/twig] No longer using the phpbb_template_locator This functionality is handled by the Twig Filesystem Loader PHPBB3-11598 --- phpBB/includes/template/twig/twig.php | 56 ++++++++++++++++----------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/phpBB/includes/template/twig/twig.php b/phpBB/includes/template/twig/twig.php index 97bba3f433..e80f42fede 100644 --- a/phpBB/includes/template/twig/twig.php +++ b/phpBB/includes/template/twig/twig.php @@ -58,12 +58,6 @@ class phpbb_template_twig implements phpbb_template */ protected $user; - /** - * Template locator - * @var phpbb_template_locator - */ - protected $locator; - /** * Extension manager. * @@ -88,6 +82,13 @@ class phpbb_template_twig implements phpbb_template */ protected $twig; + /** + * Array of filenames assigned to set_filenames + * + * @var array + */ + protected $filenames = array(); + /** * Constructor. * @@ -105,7 +106,6 @@ class phpbb_template_twig implements phpbb_template $this->php_ext = $php_ext; $this->config = $config; $this->user = $user; - $this->locator = $locator; $this->context = $context; $this->extension_manager = $extension_manager; @@ -161,7 +161,7 @@ class phpbb_template_twig implements phpbb_template */ public function set_filenames(array $filename_array) { - $this->locator->set_filenames($filename_array); + $this->filenames = array_merge($filename_array, $this->filenames); return $this; } @@ -181,30 +181,40 @@ class phpbb_template_twig implements phpbb_template $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']) + if ($this->user && ($style_names === array($this->user->style['style_path']) || $style_names[0] == $this->user->style['style_path'])) { $this->twig->getLoader()->setPaths($style_paths, 'core'); + } - // Add admin namespace - // @todo use phpbb_admin path - $this->twig->getLoader()->addPath($this->phpbb_root_path . 'adm/style/', 'admin'); + // Add admin namespace + // @todo use phpbb_admin path + if (is_dir($this->phpbb_root_path . 'adm/style/')) + { + $this->twig->getLoader()->setPaths($this->phpbb_root_path . 'adm/style/', 'admin'); + } - // Add all namespaces for all extensions - if ($this->extension_manager instanceof phpbb_extension_manager) + // 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) { - $style_names[] = 'all'; + // namespaces cannot contain / + $namespace = str_replace('/', '_', $ext_namespace); + $paths = array(); - foreach ($this->extension_manager->all_enabled() as $ext_namespace => $ext_path) + foreach ($style_names as $style_name) { - foreach ($style_names as $style_name) + $ext_style_path = $ext_path . 'styles/' . $style_name . '/template'; + + if (is_dir($ext_style_path)) { - 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)); - } + $paths[] = $ext_style_path; } } + + $this->twig->getLoader()->setPaths($paths, $namespace); } } @@ -253,7 +263,7 @@ class phpbb_template_twig implements phpbb_template try { - $this->twig->display($this->locator->get_filename_for_handle($handle), $this->get_template_vars()); + $this->twig->display($this->filenames[$handle], $this->get_template_vars()); } catch (Twig_Error $e) { From 6c771a38ded92135b9264e142cc27d7e5770eda1 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Tue, 25 Jun 2013 19:24:32 -0500 Subject: [PATCH 051/156] [feature/twig] Going back to Twig's handling of cache file names for now My method was not working correctly, will work on it more later. PHPBB3-11598 --- phpBB/includes/template/twig/environment.php | 18 +++++++++++++++--- tests/template/template_test_case.php | 2 +- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/phpBB/includes/template/twig/environment.php b/phpBB/includes/template/twig/environment.php index 0947a902d0..d20da965c3 100644 --- a/phpBB/includes/template/twig/environment.php +++ b/phpBB/includes/template/twig/environment.php @@ -45,15 +45,27 @@ class phpbb_template_twig_environment extends Twig_Environment * * @return string The cache file name */ - public function getCacheFilename($name) + public function ignoregetCacheFilename($name) { if (false === $this->cache) { return false; } +// @todo + $file_path = $this->getLoader()->getCacheKey($name); + foreach ($this->getLoader()->getNamespaces() as $namespace) + { + foreach ($this->getLoader()->getPaths($namespace) as $path) + { + if (strpos($file_path, $path) === 0) + { + //return $this->getCache() . '/' . preg_replace('#[^a-zA-Z0-9_/]#', '_', $namespace . '/' . $name) . '.php'; + } + } + } - // @todo correct cache file name handling - + // We probably should never get here under normal circumstances return $this->getCache() . '/' . preg_replace('#[^a-zA-Z0-9_/]#', '_', $name) . '.php'; + return $this->getCache() . '/' . preg_replace('#[^a-zA-Z0-9_/]#', '_', $name) . '_' . md5($this->getLoader()->getCacheKey($name)) . '.php'; } /** diff --git a/tests/template/template_test_case.php b/tests/template/template_test_case.php index 5ff15fff53..23ee8aae04 100644 --- a/tests/template/template_test_case.php +++ b/tests/template/template_test_case.php @@ -82,7 +82,7 @@ class phpbb_template_template_test_case extends phpbb_test_case protected function tearDown() { - $this->template->clear_cache(); + //$this->template->clear_cache(); } protected function run_template($file, array $vars, array $block_vars, array $destroy, $expected) From 040186418aa15d1de4a99b81cf05ee74ef94e042 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Tue, 25 Jun 2013 20:52:04 -0500 Subject: [PATCH 052/156] [feature/twig] Forgot to set up $config in node/php.php PHPBB3-11598 --- phpBB/includes/template/twig/node/php.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/phpBB/includes/template/twig/node/php.php b/phpBB/includes/template/twig/node/php.php index 83481b1d69..953cd184a7 100644 --- a/phpBB/includes/template/twig/node/php.php +++ b/phpBB/includes/template/twig/node/php.php @@ -28,6 +28,8 @@ class phpbb_template_twig_node_php extends Twig_Node { $compiler->addDebugInfo($this); + $config = $this->environment->get_phpbb_config(); + if (!$config['tpl_allow_php']) { $compiler From 15e4b334955cd841fe94cb0d4b6753cc8c9f6967 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Wed, 26 Jun 2013 09:09:11 -0500 Subject: [PATCH 053/156] [feature/twig] Fix alter_block_array to correctly set S_ROW_COUNT PHPBB3-11598 --- phpBB/includes/template/context.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/phpBB/includes/template/context.php b/phpBB/includes/template/context.php index 3abab4f31b..98b870adec 100644 --- a/phpBB/includes/template/context.php +++ b/phpBB/includes/template/context.php @@ -322,10 +322,13 @@ class phpbb_template_context for ($i = sizeof($block); $i > $key; $i--) { $block[$i] = $block[$i-1]; + + $block[$i]['S_ROW_COUNT'] = $i; } // Insert vararray at given position $block[$key] = $vararray; + $block[$key]['S_ROW_COUNT'] = $key; return true; } From 6d709525c318bcc6fa4a25aeb6a2a9d1256a9917 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Wed, 26 Jun 2013 12:27:32 -0500 Subject: [PATCH 054/156] [feature/twig] Set S_ROW_NUM in context also (previously was a hack in filter) PHPBB3-11598 --- phpBB/includes/template/context.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/phpBB/includes/template/context.php b/phpBB/includes/template/context.php index 98b870adec..9826f5e5f5 100644 --- a/phpBB/includes/template/context.php +++ b/phpBB/includes/template/context.php @@ -158,7 +158,7 @@ class phpbb_template_context } $s_row_count = isset($str[$blocks[$blockcount]]) ? sizeof($str[$blocks[$blockcount]]) : 0; - $vararray['S_ROW_COUNT'] = $s_row_count; + $vararray['S_ROW_COUNT'] = $vararray['S_ROW_NUM'] = $s_row_count; // Assign S_FIRST_ROW if (!$s_row_count) @@ -183,7 +183,7 @@ class phpbb_template_context { // Top-level block. $s_row_count = (isset($this->tpldata[$blockname])) ? sizeof($this->tpldata[$blockname]) : 0; - $vararray['S_ROW_COUNT'] = $s_row_count; + $vararray['S_ROW_COUNT'] = $vararray['S_ROW_NUM'] = $s_row_count; // Assign S_FIRST_ROW if (!$s_row_count) @@ -323,12 +323,12 @@ class phpbb_template_context { $block[$i] = $block[$i-1]; - $block[$i]['S_ROW_COUNT'] = $i; + $block[$i]['S_ROW_COUNT'] = $block[$i]['S_ROW_NUM'] = $i; } // Insert vararray at given position $block[$key] = $vararray; - $block[$key]['S_ROW_COUNT'] = $key; + $block[$key]['S_ROW_COUNT'] = $block[$key]['S_ROW_NUM'] = $key; return true; } From 09ed0dd7bccd1f2674525a7a2b7ec99b6c745832 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Wed, 26 Jun 2013 12:30:59 -0500 Subject: [PATCH 055/156] [feature/twig] Replace BEGIN with Twig for using Lexer No longer using the begin tokenparser/node as it did not allow proper handling of with {% include 'blah.html' %} $code = preg_replace('##', "{% INCLUDE$1 '$2' %}", $code); // This strips the $ inside of a tag directly after the token, which was used in #', '', $code); - // This strips the . or $ inside of a tag directly before a variable name, which was used in #', array($this, 'tag_if_cleanup'), $code); // Replace all of our starting tokens, with Twig style, {% TOKEN %} @@ -58,6 +62,74 @@ class phpbb_template_twig_lexer extends Twig_Lexer return parent::tokenize($code, $filename); } + /** + * Fix begin tokens (convert our BEGIN to Twig for) + * + * Not meant to be used outside of this context, public because the anonymous function calls this + * + * @param string $code + * @param array $parent_nodes + * @return string + */ + public function fix_begin_tokens($code, $parent_nodes = array()) + { + // PHP 5.3 cannot use $this in an anonymous function, so use this as a work-around + $parent_class = $this; + $callback = function ($matches) use ($parent_class, $parent_nodes) + { + $name = $matches[1]; + $slice = $matches[2]; + $body = $matches[3]; + + // Is the designer wanting to call another loop in a loop? + // + // + // + // + // 'loop2' is actually on the same nesting level as 'loop' you assign + // variables to it with template->assign_block_vars('loop2', array(...)) + if (strpos($name, '!') === 0) + { + // Count the number if ! occurrences + $count = substr_count($name, '!'); + for ($i = 0; $i < $count; $i++) + { + array_pop($parent_nodes); + $name = substr($name, 1); + } + } + + // Remove all parent nodes, e.g. foo, bar from foo.bar.foobar + foreach ($parent_nodes as $node) + { + $body = preg_replace('#([^a-zA-Z0-9])' . $node . '\.#', '$1', $body); + } + + // Add current node to list of parent nodes for child nodes + $parent_nodes[] = $name; + + // Recursive...fix any child nodes + $body = $parent_class->fix_begin_tokens($body, $parent_nodes); + + // Rename loopname vars (to prevent collisions, loop children are named (loop name)_loop_element) + $body = str_replace($name . '.', $name . '_loop_element.', $body); + + // Need the parent variable name + array_pop($parent_nodes); + $parent = (!empty($parent_nodes)) ? end($parent_nodes) . '_loop_element.' : ''; + + $slice = ($slice) ? '|slice(' . $slice . ')' : ''; + + // Turn into a Twig for loop, using (loop name)_loop_element for each child + return "{% for {$name}_loop_element in {$parent}{$name}{$slice} %}{$body}{% endfor %}"; + }; + + // Replace correctly, only needs to be done once + $code = str_replace('', '{% else %}', $code); + + return preg_replace_callback('#(.+?)#s', $callback, $code); + } + /** * preg_replace_callback to clean up IF statements * @@ -68,6 +140,10 @@ class phpbb_template_twig_lexer extends Twig_Lexer */ protected function tag_if_cleanup($matches) { - return ''; + // Replace $TEST with TEST + $matches[1] = preg_replace('#\s\$([a-zA-Z_0-9]+)#', ' $1', $matches[1]); + $matches[1] = preg_replace('#\s\.([a-zA-Z_0-9]+)#', ' $1|length', $matches[1]); + + return ''; } } diff --git a/phpBB/includes/template/twig/node/begin.php b/phpBB/includes/template/twig/node/begin.php deleted file mode 100644 index 3c1ce1b89b..0000000000 --- a/phpBB/includes/template/twig/node/begin.php +++ /dev/null @@ -1,139 +0,0 @@ - $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("if (!empty(\$parent['" . $this->getAttribute('beginName') . "'])) {\n") - ->indent() - ->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") - ; - - if (null !== $this->getNode('else')) { - $compiler - ->write("} else {\n") - ->indent() - ->subcompile($this->getNode('else')) - ->outdent() - ; - } - - $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/tokenparser/begin.php b/phpBB/includes/template/twig/tokenparser/begin.php deleted file mode 100644 index 0a2f2da40d..0000000000 --- a/phpBB/includes/template/twig/tokenparser/begin.php +++ /dev/null @@ -1,57 +0,0 @@ -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/twig.php b/phpBB/includes/template/twig/twig.php index e80f42fede..cb2899a2fd 100644 --- a/phpBB/includes/template/twig/twig.php +++ b/phpBB/includes/template/twig/twig.php @@ -432,7 +432,7 @@ class phpbb_template_twig implements phpbb_template * * @return array */ - protected function get_template_vars() + public function get_template_vars() { $vars = array(); @@ -454,20 +454,11 @@ class phpbb_template_twig implements phpbb_template $vars = array_merge( $vars, $this->context->get_rootref(), - array( - '_phpbb_blocks' => $this->context->get_tpldata(), - ) + $this->context->get_tpldata() ); - // Must do this so that 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']['.']); + unset($vars['.']); return $vars; } From abb7901edb61e551b5783254579fef737f6f5c37 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Fri, 28 Jun 2013 15:40:30 -0500 Subject: [PATCH 056/156] [feature/twig] New Twig filter, subset This filter grabs a subset of a loop for output (according to past functionality). PHPBB3-11598 --- phpBB/includes/template/twig/extension.php | 40 +++++++++++++++++++++- phpBB/includes/template/twig/lexer.php | 11 +++--- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/phpBB/includes/template/twig/extension.php b/phpBB/includes/template/twig/extension.php index 44d694ce1a..a952d70076 100644 --- a/phpBB/includes/template/twig/extension.php +++ b/phpBB/includes/template/twig/extension.php @@ -35,12 +35,19 @@ class phpbb_template_twig_extension extends Twig_Extension ); } + public function getFilters() + { + return array( + new Twig_SimpleFilter('subset', array($this, 'loop_subset'), array('needs_environment' => true)), + ); + } + public function getOperators() { return array( array(), array( - // @todo check if all these are needed (or others) + // @todo check if all these are needed (or others) and set precedence correctly '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), @@ -60,4 +67,35 @@ class phpbb_template_twig_extension extends Twig_Extension ), ); } + + /** + * Grabs a subset of a loop + * + * @param Twig_Environment $env A Twig_Environment instance + * @param mixed $item A variable + * @param integer $start Start of the subset + * @param integer $end End of the subset + * @param Boolean $preserveKeys Whether to preserve key or not (when the input is an array) + * + * @return mixed The sliced variable + */ + function loop_subset(Twig_Environment $env, $item, $start, $end = null, $preserveKeys = false) + { + // We do almost the same thing as array_slice, except when $end is positive + if ($end >= 1) + { + // When end is > 1, subset will end on the last item in an array with the specified $end + // This is different from slice in that it is the number we end on rather than the number + // of items to grab (length) + + // Start must always be the actual starting number for this calculation (not negative) + $start = ($start < 0) ? sizeof($item) + $start : $start; + $end = $end - $start; + } + + // We always include the last element (this was the past design) + $end = ($end == -1 || $end === null) ? null : $end + 1; + + return twig_slice($env, $item, $start, $end, $preserveKeys); + } } diff --git a/phpBB/includes/template/twig/lexer.php b/phpBB/includes/template/twig/lexer.php index 95b9bd4630..9d348535a5 100644 --- a/phpBB/includes/template/twig/lexer.php +++ b/phpBB/includes/template/twig/lexer.php @@ -78,7 +78,7 @@ class phpbb_template_twig_lexer extends Twig_Lexer $callback = function ($matches) use ($parent_class, $parent_nodes) { $name = $matches[1]; - $slice = $matches[2]; + $subset = trim(substr($matches[2], 1, -1)); // Remove parenthesis $body = $matches[3]; // Is the designer wanting to call another loop in a loop? @@ -118,16 +118,19 @@ class phpbb_template_twig_lexer extends Twig_Lexer array_pop($parent_nodes); $parent = (!empty($parent_nodes)) ? end($parent_nodes) . '_loop_element.' : ''; - $slice = ($slice) ? '|slice(' . $slice . ')' : ''; + if ($subset !== '') + { + $subset = '|subset(' . $subset . ')'; + } // Turn into a Twig for loop, using (loop name)_loop_element for each child - return "{% for {$name}_loop_element in {$parent}{$name}{$slice} %}{$body}{% endfor %}"; + return "{% for {$name}_loop_element in {$parent}{$name}{$subset} %}{$body}{% endfor %}"; }; // Replace correctly, only needs to be done once $code = str_replace('', '{% else %}', $code); - return preg_replace_callback('#(.+?)#s', $callback, $code); + return preg_replace_callback('#(.+?)#s', $callback, $code); } /** From 64963b5962d9a4bf1888dd1642a32ba3f6037258 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Sat, 29 Jun 2013 11:07:10 -0500 Subject: [PATCH 057/156] [feature/twig] Fixing DEFINE statements PHPBB3-11598 --- phpBB/includes/template/twig/definition.php | 50 +++++++++++ phpBB/includes/template/twig/lexer.php | 82 +++++++++++++------ phpBB/includes/template/twig/node/define.php | 49 +++++++++++ .../template/twig/tokenparser/define.php | 33 +++++++- phpBB/includes/template/twig/twig.php | 15 ++-- 5 files changed, 196 insertions(+), 33 deletions(-) create mode 100644 phpBB/includes/template/twig/definition.php create mode 100644 phpBB/includes/template/twig/node/define.php diff --git a/phpBB/includes/template/twig/definition.php b/phpBB/includes/template/twig/definition.php new file mode 100644 index 0000000000..110437eb32 --- /dev/null +++ b/phpBB/includes/template/twig/definition.php @@ -0,0 +1,50 @@ +definitions[$name])) ? $this->definitions[$name] : null; + } + + /** + * DEFINE a variable + * + * @param string $name + * @param mixed $value + * @return phpbb_template_twig_definition + */ + public function set($name, $value) + { + $this->definitions[$name] = $value; + + return $this; + } +} diff --git a/phpBB/includes/template/twig/lexer.php b/phpBB/includes/template/twig/lexer.php index 9d348535a5..e8ceef3d13 100644 --- a/phpBB/includes/template/twig/lexer.php +++ b/phpBB/includes/template/twig/lexer.php @@ -20,6 +20,7 @@ class phpbb_template_twig_lexer extends Twig_Lexer public function tokenize($code, $filename = null) { $valid_starting_tokens = array( + // Commented out tokens are handled separately from the main replace /*'BEGIN', 'BEGINELSE', 'END',*/ @@ -27,9 +28,8 @@ class phpbb_template_twig_lexer extends Twig_Lexer 'ELSE', 'ELSEIF', 'ENDIF', - 'DEFINE', - 'DEFINE', - 'UNDEFINE', + /*'DEFINE', + 'UNDEFINE',*/ 'ENDDEFINE', /*'INCLUDE', 'INCLUDEPHP',*/ @@ -42,22 +42,21 @@ class phpbb_template_twig_lexer extends Twig_Lexer // Fix our BEGIN statements $code = $this->fix_begin_tokens($code); + // Fix our IF tokens + $code = $this->fix_if_tokens($code); + + // Fix our DEFINE tokens + $code = $this->fix_define_tokens($code); + // Replace with {% include 'blah.html' %} $code = preg_replace('##', "{% INCLUDE$1 '$2' %}", $code); - // This strips the $ inside of a tag directly after the token, which was used in #', '', $code); - - // This strips the . or $ inside of a tag directly before a variable name, which was used in #', array($this, 'tag_if_cleanup'), $code); - // Replace all of our starting tokens, with Twig style, {% TOKEN %} // This also strips outer parenthesis, becomes $code = preg_replace('##', '{% $1 $2 %}', $code); - // Replace all of our variables, {VARNAME} or {$VARNAME}, with Twig style, {{ VARNAME }} - $code = preg_replace('#{\$?([a-zA-Z0-9_\.]+)}#', '{{ $1 }}', $code); + // Replace all of our variables, {VARNAME}, with Twig style, {{ VARNAME }} + $code = preg_replace('#{([a-zA-Z0-9_\.]+)}#', '{{ $1 }}', $code); return parent::tokenize($code, $filename); } @@ -68,7 +67,7 @@ class phpbb_template_twig_lexer extends Twig_Lexer * Not meant to be used outside of this context, public because the anonymous function calls this * * @param string $code - * @param array $parent_nodes + * @param array $parent_nodes (used in recursion) * @return string */ public function fix_begin_tokens($code, $parent_nodes = array()) @@ -134,19 +133,56 @@ class phpbb_template_twig_lexer extends Twig_Lexer } /** - * preg_replace_callback to clean up IF statements + * Fix IF statements * - * This strips the . or $ inside of a tag directly before a variable name. - * Was used in '; + // Replace .test with test|length + $matches[1] = preg_replace('#\s\.([a-zA-Z_0-9]+)#', ' $1|length', $matches[1]); + + return ''; + }; + + return preg_replace_callback('##', $callback, $code); + } + + /** + * Fix DEFINE statements and {$VARNAME} variables + * + * @param string $code + * @return string + */ + protected function fix_define_tokens($code) + { + /** + * Changing $VARNAME to definition.varname because set is only local + * context (e.g. DEFINE $TEST will only make $TEST available in current + * template and any child templates, but not any parent templates). + * + * DEFINE handles setting it properly to definition in its node, but the + * variables reading FROM it need to be altered to definition.VARNAME + * + * Setting up definition as a class in the array passed to Twig + * ($context) makes set definition.TEST available in the global context + */ + + // Replace #', '{% DEFINE $1 %}', $code); + + // Changing UNDEFINE NAME to DEFINE NAME = null to save from creating an extra token parser/node + $code = preg_replace('##', '{% DEFINE $1= null %}', $code); + + // Replace all of our variables, {$VARNAME}, with Twig style, {{ definition.VARNAME }} + $code = preg_replace('#{\$([a-zA-Z0-9_\.]+)}#', '{{ definition.$1 }}', $code); + + return $code; } } diff --git a/phpBB/includes/template/twig/node/define.php b/phpBB/includes/template/twig/node/define.php new file mode 100644 index 0000000000..ef7565d27d --- /dev/null +++ b/phpBB/includes/template/twig/node/define.php @@ -0,0 +1,49 @@ + $name, 'value' => $value), array('capture' => $capture, 'safe' => false), $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param Twig_Compiler A Twig_Compiler instance + */ + public function compile(Twig_Compiler $compiler) + { + $compiler->addDebugInfo($this); + + if ($this->getAttribute('capture')) { + $compiler + ->write("ob_start();\n") + ->subcompile($this->getNode('value')) + ; + + $compiler->raw(" = ('' === \$value = ob_get_clean()) ? '' : new Twig_Markup(\$value, \$this->env->getCharset())"); + } + else + { + $compiler + ->write("\$value = '") + ->raw($this->getNode('value')->getAttribute('value')) + ->raw("';\n") + ; + } + + $compiler + ->raw("\$context['definition']->set('") + ->raw($this->getNode('name')->getAttribute('name')) + ->raw("', \$value);\n") + ; + } +} diff --git a/phpBB/includes/template/twig/tokenparser/define.php b/phpBB/includes/template/twig/tokenparser/define.php index 83f537a1ea..ebf7cb4c4a 100644 --- a/phpBB/includes/template/twig/tokenparser/define.php +++ b/phpBB/includes/template/twig/tokenparser/define.php @@ -7,8 +7,39 @@ * */ -class phpbb_template_twig_tokenparser_define extends Twig_TokenParser_Set +class phpbb_template_twig_tokenparser_define 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) + { + $lineno = $token->getLine(); + $stream = $this->parser->getStream(); + $name = $this->parser->getExpressionParser()->parseExpression(); + + $capture = false; + if ($stream->test(Twig_Token::OPERATOR_TYPE, '=')) { + $stream->next(); + $value = $this->parser->getExpressionParser()->parseExpression(); + + $stream->expect(Twig_Token::BLOCK_END_TYPE); + } else { + $capture = true; + + $stream->expect(Twig_Token::BLOCK_END_TYPE); + + $value = $this->parser->subparse(array($this, 'decideBlockEnd'), true); + $stream->expect(Twig_Token::BLOCK_END_TYPE); + } + + return new phpbb_template_twig_node_define($capture, $name, $value, $lineno, $this->getTag()); + } + public function decideBlockEnd(Twig_Token $token) { return $token->test('ENDDEFINE'); diff --git a/phpBB/includes/template/twig/twig.php b/phpBB/includes/template/twig/twig.php index cb2899a2fd..65776b7b6e 100644 --- a/phpBB/includes/template/twig/twig.php +++ b/phpBB/includes/template/twig/twig.php @@ -261,14 +261,8 @@ class phpbb_template_twig implements phpbb_template return $result[0]; } - try - { - $this->twig->display($this->filenames[$handle], $this->get_template_vars()); - } - catch (Twig_Error $e) - { - throw $e; - } + $context = &$this->get_template_vars(); + $this->twig->display($this->filenames[$handle], $context); return true; } @@ -454,7 +448,10 @@ class phpbb_template_twig implements phpbb_template $vars = array_merge( $vars, $this->context->get_rootref(), - $this->context->get_tpldata() + $this->context->get_tpldata(), + array( + 'definition' => new phpbb_template_twig_definition(), + ) ); // cleanup From f18cbd50f0c54aa1a97d1b4ece69d5bf70b68734 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Sat, 29 Jun 2013 19:19:18 -0500 Subject: [PATCH 058/156] [feature/twig] Fixing more stuff for DEFINE/INCLUDE PHPBB3-11598 --- phpBB/includes/template/twig/lexer.php | 49 +++++++++++++++++--- phpBB/includes/template/twig/node/define.php | 4 +- 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/phpBB/includes/template/twig/lexer.php b/phpBB/includes/template/twig/lexer.php index e8ceef3d13..258b913a2c 100644 --- a/phpBB/includes/template/twig/lexer.php +++ b/phpBB/includes/template/twig/lexer.php @@ -31,14 +31,21 @@ class phpbb_template_twig_lexer extends Twig_Lexer /*'DEFINE', 'UNDEFINE',*/ 'ENDDEFINE', - /*'INCLUDE', - 'INCLUDEPHP',*/ + 'INCLUDE', + 'INCLUDEPHP', 'INCLUDEJS', 'PHP', 'ENDPHP', 'EVENT', ); + // Fix tokens that may have inline variables (e.g. with {% include 'blah.html' %} - $code = preg_replace('##', "{% INCLUDE$1 '$2' %}", $code); - // Replace all of our starting tokens, with Twig style, {% TOKEN %} // This also strips outer parenthesis, becomes $code = preg_replace('##', '{% $1 $2 %}', $code); @@ -61,6 +65,31 @@ class phpbb_template_twig_lexer extends Twig_Lexer return parent::tokenize($code, $filename); } + /** + * Fix tokens that may have inline variables + * + * E.g. "; + }; + + return preg_replace_callback('##', $callback, $code); + } + /** * Fix begin tokens (convert our BEGIN to Twig for) * @@ -148,10 +177,13 @@ class phpbb_template_twig_lexer extends Twig_Lexer // Replace .test with test|length $matches[1] = preg_replace('#\s\.([a-zA-Z_0-9]+)#', ' $1|length', $matches[1]); - return ''; + // Replace our "div by" with Twig's divisibleby (Twig does not like test names with spaces?) + $matches[1] = preg_replace('# div by ([0-9]+)#', ' divisibleby($1)', $matches[1]); + + return ''; }; - return preg_replace_callback('##', $callback, $code); + return preg_replace_callback('##', $callback, $code); } /** @@ -183,6 +215,9 @@ class phpbb_template_twig_lexer extends Twig_Lexer // Replace all of our variables, {$VARNAME}, with Twig style, {{ definition.VARNAME }} $code = preg_replace('#{\$([a-zA-Z0-9_\.]+)}#', '{{ definition.$1 }}', $code); + // Replace all of our variables, ~ $VARNAME ~, with Twig style, ~ definition.VARNAME ~ + $code = preg_replace('#~ \$([a-zA-Z0-9_\.]+) ~#', '~ definition.$1 ~', $code); + return $code; } } diff --git a/phpBB/includes/template/twig/node/define.php b/phpBB/includes/template/twig/node/define.php index ef7565d27d..87e93be7be 100644 --- a/phpBB/includes/template/twig/node/define.php +++ b/phpBB/includes/template/twig/node/define.php @@ -29,13 +29,13 @@ class phpbb_template_twig_node_define extends Twig_Node ->subcompile($this->getNode('value')) ; - $compiler->raw(" = ('' === \$value = ob_get_clean()) ? '' : new Twig_Markup(\$value, \$this->env->getCharset())"); + $compiler->write("\$value = ('' === \$value = ob_get_clean()) ? '' : new Twig_Markup(\$value, \$this->env->getCharset());\n"); } else { $compiler ->write("\$value = '") - ->raw($this->getNode('value')->getAttribute('value')) + ->subcompile($this->getNode('value')) ->raw("';\n") ; } From 82aa4edeabe1c0f3c01f6c4a23035470a89e3f1f Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Sat, 29 Jun 2013 19:22:01 -0500 Subject: [PATCH 059/156] [feature/twig] Adding some operators to the extension PHPBB3-11598 --- phpBB/includes/template/twig/extension.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/phpBB/includes/template/twig/extension.php b/phpBB/includes/template/twig/extension.php index a952d70076..fb9daab500 100644 --- a/phpBB/includes/template/twig/extension.php +++ b/phpBB/includes/template/twig/extension.php @@ -59,14 +59,18 @@ class phpbb_template_twig_extension extends Twig_Extension '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), + 'ge' => 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), + 'le' => 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), - ), - ); - } + + 'mod' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mod', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + ), + ); + } /** * Grabs a subset of a loop From c477f865fbab2ecc1cd13302f44d62b36af14c73 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Sat, 29 Jun 2013 19:22:58 -0500 Subject: [PATCH 060/156] [feature/twig] Add S_NUM_ROWS to loops in context PHPBB3-11598 --- phpBB/includes/template/context.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/phpBB/includes/template/context.php b/phpBB/includes/template/context.php index 9826f5e5f5..4689cf2d77 100644 --- a/phpBB/includes/template/context.php +++ b/phpBB/includes/template/context.php @@ -178,6 +178,11 @@ class phpbb_template_context // We're adding a new iteration to this block with the given // variable assignments. $str[$blocks[$blockcount]][] = $vararray; + + foreach ($str[$blocks[$blockcount]] as &$mod_block) + { + $mod_block['S_NUM_ROWS'] = $blockcount; + } } else { From c49d27329d5962f41ee850df2a0937528361151d Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 1 Jul 2013 09:18:58 -0500 Subject: [PATCH 061/156] [feature/twig] Adding ! operator PHPBB3-11598 --- phpBB/includes/template/twig/extension.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/phpBB/includes/template/twig/extension.php b/phpBB/includes/template/twig/extension.php index fb9daab500..d7400fde4b 100644 --- a/phpBB/includes/template/twig/extension.php +++ b/phpBB/includes/template/twig/extension.php @@ -45,9 +45,14 @@ class phpbb_template_twig_extension extends Twig_Extension public function getOperators() { return array( - array(), array( - // @todo check if all these are needed (or others) and set precedence correctly + '!' => array('precedence' => 50, 'class' => 'Twig_Node_Expression_Unary_Not'), + ), + array( + // precedence settings are copied from similar operators in Twig core extension + '||' => 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), + '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), @@ -64,9 +69,6 @@ class phpbb_template_twig_extension extends Twig_Extension 'lte' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_LessEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), 'le' => 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), - 'mod' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mod', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), ), ); From 2c55671767e194fb37cae674c0730e4bc50c0356 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 1 Jul 2013 09:19:30 -0500 Subject: [PATCH 062/156] [feature/twig] Fixing div by replacement PHPBB3-11598 --- phpBB/includes/template/twig/lexer.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/phpBB/includes/template/twig/lexer.php b/phpBB/includes/template/twig/lexer.php index 258b913a2c..a2afcf18be 100644 --- a/phpBB/includes/template/twig/lexer.php +++ b/phpBB/includes/template/twig/lexer.php @@ -177,12 +177,12 @@ class phpbb_template_twig_lexer extends Twig_Lexer // Replace .test with test|length $matches[1] = preg_replace('#\s\.([a-zA-Z_0-9]+)#', ' $1|length', $matches[1]); - // Replace our "div by" with Twig's divisibleby (Twig does not like test names with spaces?) - $matches[1] = preg_replace('# div by ([0-9]+)#', ' divisibleby($1)', $matches[1]); - return ''; }; + // Replace our "div by" with Twig's divisibleby (Twig does not like test names with spaces) + $code = preg_replace('# div by ([0-9]+)#', ' divisibleby($1)', $code); + return preg_replace_callback('##', $callback, $code); } From ecdc73a81a30e9d48c9e8eccfcdcb13fb52dbb81 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 1 Jul 2013 09:19:54 -0500 Subject: [PATCH 063/156] [feature/twig] Fixing define node PHPBB3-11598 --- phpBB/includes/template/twig/node/define.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/phpBB/includes/template/twig/node/define.php b/phpBB/includes/template/twig/node/define.php index 87e93be7be..0c4d400767 100644 --- a/phpBB/includes/template/twig/node/define.php +++ b/phpBB/includes/template/twig/node/define.php @@ -34,14 +34,14 @@ class phpbb_template_twig_node_define extends Twig_Node else { $compiler - ->write("\$value = '") + ->write("\$value = ") ->subcompile($this->getNode('value')) - ->raw("';\n") + ->raw(";\n") ; } $compiler - ->raw("\$context['definition']->set('") + ->write("\$context['definition']->set('") ->raw($this->getNode('name')->getAttribute('name')) ->raw("', \$value);\n") ; From 658d1b6afe7816ba92c30e227ebdef0db427ce53 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 1 Jul 2013 09:20:46 -0500 Subject: [PATCH 064/156] [feature/twig] Fixing include node PHPBB3-11598 --- phpBB/includes/template/twig/node/include.php | 36 ++++++++++--------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/phpBB/includes/template/twig/node/include.php b/phpBB/includes/template/twig/node/include.php index df7a95af44..2a90dc19e4 100644 --- a/phpBB/includes/template/twig/node/include.php +++ b/phpBB/includes/template/twig/node/include.php @@ -18,28 +18,30 @@ class phpbb_template_twig_node_include extends Twig_Node_Include { $compiler->addDebugInfo($this); - $location = $this->getNode('expr')->getAttribute('value'); - $namespace = false; - - if (strpos($location, '@') === 0) - { - $namespace = substr($location, 1, strpos($location, '/') - 1); - - $compiler + $compiler + ->write("\$location = ") + ->subcompile($this->getNode('expr')) + ->raw(";\n") + ->write("\$namespace = false;\n") + ->write("if (strpos(\$location, '@') === 0) {\n") + ->indent() + ->write("\$namespace = substr(\$location, 1, strpos(\$location, '/') - 1);\n") ->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") - ; - } + ->write("\$this->env->setNamespaceLookUpOrder(array(\$namespace, '__main__'));\n") + ->outdent() + ->write("}\n") + ; parent::compile($compiler); - if ($namespace) - { - $compiler - ->write("\$this->env->setNamespaceLookUpOrder(\$previous_look_up_order);\n") - ; - } + $compiler + ->write("if (\$namespace) {\n") + ->indent() + ->write("\$this->env->setNamespaceLookUpOrder(\$previous_look_up_order);\n") + ->outdent() + ->write("}\n") + ; } } From 97494051290f394f61767358a306c1896d0545f0 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 1 Jul 2013 09:32:21 -0500 Subject: [PATCH 065/156] [feature/twig] Transform {L_, {LA_ to use the lang() function PHPBB3-11598 --- phpBB/includes/template/twig/extension.php | 35 ++++++++++++++++++++++ phpBB/includes/template/twig/lexer.php | 6 ++++ phpBB/includes/template/twig/twig.php | 22 ++++---------- 3 files changed, 47 insertions(+), 16 deletions(-) diff --git a/phpBB/includes/template/twig/extension.php b/phpBB/includes/template/twig/extension.php index d7400fde4b..a3da61fcdb 100644 --- a/phpBB/includes/template/twig/extension.php +++ b/phpBB/includes/template/twig/extension.php @@ -17,11 +17,24 @@ if (!defined('IN_PHPBB')) class phpbb_template_twig_extension extends Twig_Extension { + /** @var phpbb_user */ + protected $user; + + public function __construct($user) + { + $this->user = $user; + } + public function getName() { return 'phpbb'; } + /** + * Returns the token parser instance to add to the existing list. + * + * @return array An array of Twig_TokenParser instances + */ public function getTokenParsers() { return array( @@ -35,6 +48,11 @@ class phpbb_template_twig_extension extends Twig_Extension ); } + /** + * Returns a list of filters to add to the existing list. + * + * @return array An array of filters + */ public function getFilters() { return array( @@ -42,6 +60,23 @@ class phpbb_template_twig_extension extends Twig_Extension ); } + /** + * Returns a list of global functions to add to the existing list. + * + * @return array An array of global functions + */ + public function getFunctions() + { + return array( + new Twig_SimpleFunction('lang', array($this->user, 'lang')), + ); + } + + /** + * Returns a list of operators to add to the existing list. + * + * @return array An array of operators + */ public function getOperators() { return array( diff --git a/phpBB/includes/template/twig/lexer.php b/phpBB/includes/template/twig/lexer.php index a2afcf18be..1daa6c30c9 100644 --- a/phpBB/includes/template/twig/lexer.php +++ b/phpBB/includes/template/twig/lexer.php @@ -59,6 +59,12 @@ class phpbb_template_twig_lexer extends Twig_Lexer // This also strips outer parenthesis, becomes $code = preg_replace('##', '{% $1 $2 %}', $code); + // Replace all of our language variables, {L_VARNAME}, with Twig style, {{ lang('NAME') }} + $code = preg_replace('#{L_([a-zA-Z0-9_\.]+)}#', '{{ lang(\'$1\') }}', $code); + + // Replace all of our JS escaped language variables, {LA_VARNAME}, with Twig style, {{ lang('NAME')|escape('js') }} + $code = preg_replace('#{LA_([a-zA-Z0-9_\.]+)}#', '{{ lang(\'$1\')|escape(\'js\') }}', $code); + // Replace all of our variables, {VARNAME}, with Twig style, {{ VARNAME }} $code = preg_replace('#{([a-zA-Z0-9_\.]+)}#', '{{ $1 }}', $code); diff --git a/phpBB/includes/template/twig/twig.php b/phpBB/includes/template/twig/twig.php index 65776b7b6e..f5879c6027 100644 --- a/phpBB/includes/template/twig/twig.php +++ b/phpBB/includes/template/twig/twig.php @@ -131,7 +131,11 @@ class phpbb_template_twig implements phpbb_template // @todo remove $this->clear_cache(); - $this->twig->addExtension(new phpbb_template_twig_extension); + $this->twig->addExtension( + new phpbb_template_twig_extension( + $this->user + ) + ); $lexer = new phpbb_template_twig_lexer($this->twig); @@ -430,27 +434,13 @@ class phpbb_template_twig implements phpbb_template { $vars = array(); - // Work-around for now - if (!empty($this->user->lang)) - { - 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(), $this->context->get_tpldata(), array( 'definition' => new phpbb_template_twig_definition(), + 'user' => $this->user, ) ); From 8d3fd1fcdd446bd3838d9d9ed68ce4b0c1f48ac3 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 1 Jul 2013 09:36:03 -0500 Subject: [PATCH 066/156] [feature/twig] Remove the get_rootref and get_tpldata functions prev added These are not really necessary PHPBB3-11598 --- phpBB/includes/template/context.php | 20 -------------------- phpBB/includes/template/twig/twig.php | 7 +++---- 2 files changed, 3 insertions(+), 24 deletions(-) diff --git a/phpBB/includes/template/context.php b/phpBB/includes/template/context.php index 4689cf2d77..498568e5f4 100644 --- a/phpBB/includes/template/context.php +++ b/phpBB/includes/template/context.php @@ -82,26 +82,6 @@ class phpbb_template_context return true; } - /** - * 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. * diff --git a/phpBB/includes/template/twig/twig.php b/phpBB/includes/template/twig/twig.php index f5879c6027..717213ea1f 100644 --- a/phpBB/includes/template/twig/twig.php +++ b/phpBB/includes/template/twig/twig.php @@ -432,12 +432,11 @@ class phpbb_template_twig implements phpbb_template */ public function get_template_vars() { - $vars = array(); + $context_vars = $this->context->get_data_ref(); $vars = array_merge( - $vars, - $this->context->get_rootref(), - $this->context->get_tpldata(), + $context_vars['.'][0], // To get normal vars + $context_vars, // To get loops array( 'definition' => new phpbb_template_twig_definition(), 'user' => $this->user, From 42e3a4bfb9653164db31637e36804945d854e9e7 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 1 Jul 2013 10:17:58 -0500 Subject: [PATCH 067/156] [feature/twig] Add addslashes filter (to use on LA_ instead of escape) To match previous parser behavior PHPBB3-11598 --- phpBB/includes/template/twig/extension.php | 1 + phpBB/includes/template/twig/lexer.php | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/template/twig/extension.php b/phpBB/includes/template/twig/extension.php index a3da61fcdb..1ea5f7b662 100644 --- a/phpBB/includes/template/twig/extension.php +++ b/phpBB/includes/template/twig/extension.php @@ -57,6 +57,7 @@ class phpbb_template_twig_extension extends Twig_Extension { return array( new Twig_SimpleFilter('subset', array($this, 'loop_subset'), array('needs_environment' => true)), + new Twig_SimpleFilter('addslashes', 'addslashes'), ); } diff --git a/phpBB/includes/template/twig/lexer.php b/phpBB/includes/template/twig/lexer.php index 1daa6c30c9..131cf654ef 100644 --- a/phpBB/includes/template/twig/lexer.php +++ b/phpBB/includes/template/twig/lexer.php @@ -62,8 +62,8 @@ class phpbb_template_twig_lexer extends Twig_Lexer // Replace all of our language variables, {L_VARNAME}, with Twig style, {{ lang('NAME') }} $code = preg_replace('#{L_([a-zA-Z0-9_\.]+)}#', '{{ lang(\'$1\') }}', $code); - // Replace all of our JS escaped language variables, {LA_VARNAME}, with Twig style, {{ lang('NAME')|escape('js') }} - $code = preg_replace('#{LA_([a-zA-Z0-9_\.]+)}#', '{{ lang(\'$1\')|escape(\'js\') }}', $code); + // Replace all of our escaped language variables, {LA_VARNAME}, with Twig style, {{ lang('NAME')|addslashes }} + $code = preg_replace('#{LA_([a-zA-Z0-9_\.]+)}#', '{{ lang(\'$1\')|addslashes }}', $code); // Replace all of our variables, {VARNAME}, with Twig style, {{ VARNAME }} $code = preg_replace('#{([a-zA-Z0-9_\.]+)}#', '{{ $1 }}', $code); From 4ee7fb1a9d549ce0b1c687eaddbe0bf3261ab3bf Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 1 Jul 2013 10:57:57 -0500 Subject: [PATCH 068/156] [feature/twig] Add S_BLOCK_NAME to context, set S_NUM_ROWS in alter_block PHPBB3-11598 --- phpBB/includes/template/context.php | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/phpBB/includes/template/context.php b/phpBB/includes/template/context.php index 498568e5f4..8585e7d794 100644 --- a/phpBB/includes/template/context.php +++ b/phpBB/includes/template/context.php @@ -146,6 +146,9 @@ class phpbb_template_context $vararray['S_FIRST_ROW'] = true; } + // Assign S_BLOCK_NAME + $vararray['S_BLOCK_NAME'] = $blocks[$blockcount]; + // Now the tricky part, we always assign S_LAST_ROW and remove the entry before // This is much more clever than going through the complete template data on display (phew) $vararray['S_LAST_ROW'] = true; @@ -159,6 +162,7 @@ class phpbb_template_context // variable assignments. $str[$blocks[$blockcount]][] = $vararray; + // Set S_NUM_ROWS foreach ($str[$blocks[$blockcount]] as &$mod_block) { $mod_block['S_NUM_ROWS'] = $blockcount; @@ -176,6 +180,9 @@ class phpbb_template_context $vararray['S_FIRST_ROW'] = true; } + // Assign S_BLOCK_NAME + $vararray['S_BLOCK_NAME'] = $blocks[$blockcount]; + // We always assign S_LAST_ROW and remove the entry before $vararray['S_LAST_ROW'] = true; if ($s_row_count > 0) @@ -185,6 +192,12 @@ class phpbb_template_context // Add a new iteration to this block with the variable assignments we were given. $this->tpldata[$blockname][] = $vararray; + + // Set S_NUM_ROWS + foreach ($this->tpldata[$blockname] as &$mod_block) + { + $mod_block['S_NUM_ROWS'] = $blockcount; + } } return true; @@ -303,6 +316,9 @@ class phpbb_template_context $vararray['S_FIRST_ROW'] = true; } + // Assign S_BLOCK_NAME + $vararray['S_BLOCK_NAME'] = $blockname; + // Re-position template blocks for ($i = sizeof($block); $i > $key; $i--) { @@ -315,6 +331,12 @@ class phpbb_template_context $block[$key] = $vararray; $block[$key]['S_ROW_COUNT'] = $block[$key]['S_ROW_NUM'] = $key; + // Set S_NUM_ROWS + foreach ($this->tpldata[$blockname] as &$mod_block) + { + $mod_block['S_NUM_ROWS'] = sizeof($this->tpldata[$blockname]); + } + return true; } From ddaccaf63e8ae7ff5bd13b187fa40f3d089f02f0 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 1 Jul 2013 11:52:03 -0500 Subject: [PATCH 069/156] [feature/twig] A bit of cleanup in twig.php PHPBB3-11598 --- phpBB/includes/template/twig/twig.php | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/phpBB/includes/template/twig/twig.php b/phpBB/includes/template/twig/twig.php index 717213ea1f..5fe8ba97f6 100644 --- a/phpBB/includes/template/twig/twig.php +++ b/phpBB/includes/template/twig/twig.php @@ -266,7 +266,7 @@ class phpbb_template_twig implements phpbb_template } $context = &$this->get_template_vars(); - $this->twig->display($this->filenames[$handle], $context); + $this->twig->display($this->get_filename_from_handle($handle), $context); return true; } @@ -324,20 +324,12 @@ class phpbb_template_twig implements phpbb_template */ 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; + return $this->twig->render($this->get_filename_from_handle($handle)); } - $this->assign_var($template_var, $contents); + $this->assign_var($template_var, $this->twig->render($this->get_filename_from_handle($handle))); return true; } @@ -448,4 +440,15 @@ class phpbb_template_twig implements phpbb_template return $vars; } + + /** + * Get a filename from the handle + * + * @param string $handle + * @return string + */ + protected function get_filename_from_handle($handle) + { + return (isset($this->filenames[$handle])) ? $this->filenames[$handle] : $handle; + } } From 8c75d1c1bc494220bed313e542902cdc22c5336f Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 1 Jul 2013 11:58:16 -0500 Subject: [PATCH 070/156] [feature/twig] Fix template_test.php Various tests were broken completely, and some things such as whitespace changed with Twig PHPBB3-11598 --- tests/template/template_test.php | 87 ++++--------------- tests/template/template_test_case.php | 24 ++--- tests/template/templates/define_unclosed.html | 2 - tests/template/templates/loop_nested.html | 8 +- tests/template/templates/loop_size.html | 2 +- tests/template/templates/loop_underscore.html | 2 +- tests/template/templates/loop_vars.html | 1 - 7 files changed, 38 insertions(+), 88 deletions(-) delete mode 100644 tests/template/templates/define_unclosed.html diff --git a/tests/template/template_test.php b/tests/template/template_test.php index a4748eb0b3..ad4c8fbd17 100644 --- a/tests/template/template_test.php +++ b/tests/template/template_test.php @@ -116,7 +116,7 @@ class phpbb_template_template_test extends phpbb_template_template_test_case array(), array('loop' => array(array('VARIABLE' => 'x'), array('VARIABLE' => 'y')), 'loop.inner' => array(array(), array())), array(), - "first\n0 - a\nx - b\nset\n1 - a\ny - b\nset\nlast\n0 - c\n1 - c\nlast inner\ninner loop", + "first\n0 - a\nx - b\nset\n1 - a\ny - b\nset\nlast\n0 - c\n1 - c\nlast inner", ), array( 'loop_advanced.html', @@ -139,13 +139,6 @@ class phpbb_template_template_test extends phpbb_template_template_test_case array(), "abc\nzxc\ncde\nbcd", ), - array( - 'define_unclosed.html', - array(), - array(), - array(), - "test", - ), array( 'expressions.html', array(), @@ -247,21 +240,15 @@ class phpbb_template_template_test extends phpbb_template_template_test_case array(), array(), array(), - "{ VARIABLE }\n{ 1_VARIABLE }\n{ VARIABLE }\n{ 1_VARIABLE }", + "VARIABLE\n1_VARIABLE\nVARIABLE\n1_VARIABLE", ), array( 'lang.html', - array('L_VARIABLE' => "Value'", 'L_1_VARIABLE' => "1 O'Clock"), + array(), array(), array(), "Value'\n1 O'Clock\nValue\'\n1 O\'Clock", - ), - array( - 'lang.html', - array('LA_VARIABLE' => "Value'", 'LA_1_VARIABLE' => "1 O'Clock"), - array(), - array(), - "{ VARIABLE }\n{ 1_VARIABLE }\nValue'\n1 O'Clock", + array('VARIABLE' => "Value'", '1_VARIABLE' => "1 O'Clock"), ), array( 'loop_nested_multilevel_ref.html', @@ -275,7 +262,6 @@ class phpbb_template_template_test extends phpbb_template_template_test_case array(), array('outer' => array(array('VARIABLE' => 'x'), array('VARIABLE' => 'y')), 'outer.inner' => array(array('VARIABLE' => 'z'), array('VARIABLE' => 'zz'))), array(), - // I don't completely understand this output, hopefully it's correct "top-level content\nouter x\nouter y\ninner z\nfirst row\n\ninner zz", ), array( @@ -283,7 +269,6 @@ class phpbb_template_template_test extends phpbb_template_template_test_case array(), array('outer' => array(array()), 'outer.middle' => array(array()), 'outer.middle.inner' => array(array('VARIABLE' => 'z'), array('VARIABLE' => 'zz'))), array(), - // I don't completely understand this output, hopefully it's correct "top-level content\nouter\nmiddle\ninner z\nfirst row of 2 in inner\n\ninner zz", ), array( @@ -313,24 +298,15 @@ class phpbb_template_template_test extends phpbb_template_template_test_case $this->template->set_filenames(array('test' => $filename)); $this->assertFileNotExists($this->template_path . '/' . $filename, 'Testing missing file, file cannot exist'); - $expecting = sprintf('style resource locator: File for handle test does not exist. Could not find: %s', $this->test_path . '/templates/' . $filename); - $this->setExpectedTriggerError(E_USER_ERROR, $expecting); + $this->setExpectedException('Twig_Error_Loader'); $this->display('test'); } - public function test_empty_file() - { - $expecting = 'style resource locator: set_filenames: Empty filename specified for test'; - - $this->setExpectedTriggerError(E_USER_ERROR, $expecting); - $this->template->set_filenames(array('test' => '')); - } public function test_invalid_handle() { - $expecting = 'No file specified for handle test'; - $this->setExpectedTriggerError(E_USER_ERROR, $expecting); + $this->setExpectedException('Twig_Error_Loader'); $this->display('test'); } @@ -338,40 +314,23 @@ class phpbb_template_template_test extends phpbb_template_template_test_case /** * @dataProvider template_data */ - public function test_template($file, array $vars, array $block_vars, array $destroy, $expected) + public function test_template($file, array $vars, array $block_vars, array $destroy, $expected, $lang_vars = array()) { - $this->run_template($file, $vars, $block_vars, $destroy, $expected); + $this->run_template($file, $vars, $block_vars, $destroy, $expected, $lang_vars); } - /** - * @dataProvider template_data - */ - public function test_assign_display($file, array $vars, array $block_vars, array $destroy, $expected) + public function test_assign_display() { + $this->run_template('basic.html', array(), array(), array(), "pass\npass\npass\n"); + $this->template->set_filenames(array( - 'test' => $file, - 'container' => 'variable.html', + 'test' => 'basic.html', + 'container' => 'variable.html', )); - $this->template->assign_vars($vars); - - foreach ($block_vars as $block => $loops) - { - foreach ($loops as $_vars) - { - $this->template->assign_block_vars($block, $_vars); - } - } - - foreach ($destroy as $block) - { - $this->template->destroy_block_vars($block); - } - - $this->assertEquals($expected, self::trim_template_result($this->template->assign_display('test')), "Testing assign_display($file)"); $this->template->assign_display('test', 'VARIABLE', false); - $this->assertEquals($expected, $this->display('container'), "Testing assign_display($file)"); + $this->assertEquals("pass\npass\npass\n", $this->display('container'), "Testing assign_display($file)"); } public function test_append_var_without_assign_var() @@ -382,7 +341,7 @@ class phpbb_template_template_test extends phpbb_template_template_test_case $items = array('This ', 'is ', 'a ', 'test'); $expecting = implode('', $items); - + foreach ($items as $word) { $this->template->append_var('VARIABLE', $word); @@ -400,7 +359,7 @@ class phpbb_template_template_test extends phpbb_template_template_test_case $start = 'This '; $items = array('is ', 'a ', 'test'); $expecting = $start . implode('', $items); - + $this->template->assign_var('VARIABLE', $start); foreach ($items as $word) { @@ -410,13 +369,6 @@ class phpbb_template_template_test extends phpbb_template_template_test_case $this->assertEquals($expecting, $this->display('append_var')); } - public function test_php() - { - $this->setup_engine(array('tpl_allow_php' => true)); - - $this->run_template('php.html', array(), array(), array(), 'test'); - } - public function alter_block_array_data() { return array( @@ -520,10 +472,9 @@ EOT $this->template->assign_block_vars('outer.middle', array()); $this->template->assign_block_vars('outer.middle', array()); - $this->assertEquals("outer - 0\nmiddle - 0\nmiddle - 1\nouter - 1\nmiddle - 0\nmiddle - 1\nouter - 2\nmiddle - 0\nmiddle - 1", $this->display('test'), 'Ensuring template is built correctly before modification'); + $this->assertEquals("outer - 0middle - 0middle - 1outer - 1middle - 0middle - 1outer - 2middle - 0middle - 1", $this->display('test'), 'Ensuring template is built correctly before modification'); $this->template->alter_block_array($alter_block, $vararray, $key, $mode); - $this->assertEquals($expect, $this->display('test'), $description); + $this->assertEquals(str_replace(array("\n", "\r", "\t"), '', $expect), str_replace(array("\n", "\r", "\t"), '', $this->display('test')), $description); } - -} +} \ No newline at end of file diff --git a/tests/template/template_test_case.php b/tests/template/template_test_case.php index 23ee8aae04..0a12dff9f4 100644 --- a/tests/template/template_test_case.php +++ b/tests/template/template_test_case.php @@ -16,6 +16,7 @@ class phpbb_template_template_test_case extends phpbb_test_case protected $template_path; protected $style_resource_locator; protected $style_provider; + protected $user; protected $test_path = 'tests/template'; @@ -59,16 +60,17 @@ class phpbb_template_template_test_case extends phpbb_test_case protected function setup_engine(array $new_config = array()) { - global $phpbb_root_path, $phpEx, $user; + global $phpbb_root_path, $phpEx; $defaults = $this->config_defaults(); $config = new phpbb_config(array_merge($defaults, $new_config)); + $this->user = new phpbb_user; $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_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->template = new phpbb_template_twig($phpbb_root_path, $phpEx, $config, $this->user, $this->style_resource_locator, new phpbb_template_context()); + $this->style = new phpbb_style($phpbb_root_path, $phpEx, $config, $this->user, $this->style_resource_locator, $this->style_provider, $this->template); $this->style->set_custom_style('tests', $this->template_path, array(), ''); } @@ -82,10 +84,10 @@ class phpbb_template_template_test_case extends phpbb_test_case protected function tearDown() { - //$this->template->clear_cache(); + $this->template->clear_cache(); } - protected function run_template($file, array $vars, array $block_vars, array $destroy, $expected) + protected function run_template($file, array $vars, array $block_vars, array $destroy, $expected, $lang_vars = array()) { $this->template->set_filenames(array('test' => $file)); $this->template->assign_vars($vars); @@ -103,13 +105,13 @@ class phpbb_template_template_test_case extends phpbb_test_case $this->template->destroy_block_vars($block); } - try + foreach ($lang_vars as $name => $value) { - $this->assertEquals($expected, $this->display('test'), "Testing $file"); - } - catch (ErrorException $e) - { - throw $e; + $this->user->lang[$name] = $value; } + + $expected = str_replace(array("\n", "\r", "\t"), '', $expected); + $output = str_replace(array("\n", "\r", "\t"), '', $this->display('test')); + $this->assertEquals($expected, $output, "Testing $file"); } } diff --git a/tests/template/templates/define_unclosed.html b/tests/template/templates/define_unclosed.html deleted file mode 100644 index 1c975eab2b..0000000000 --- a/tests/template/templates/define_unclosed.html +++ /dev/null @@ -1,2 +0,0 @@ - -test diff --git a/tests/template/templates/loop_nested.html b/tests/template/templates/loop_nested.html index 45b1ef85d4..3b5ffa5cac 100644 --- a/tests/template/templates/loop_nested.html +++ b/tests/template/templates/loop_nested.html @@ -1,6 +1,6 @@ - outer - {outer.S_ROW_COUNT} - {outer.VARIABLE} - - middle - {middle.S_ROW_COUNT} - {middle.VARIABLE} - +outer - {outer.S_ROW_COUNT} - {outer.VARIABLE} + +middle - {outer.middle.S_ROW_COUNT} - {outer.middle.VARIABLE} + diff --git a/tests/template/templates/loop_size.html b/tests/template/templates/loop_size.html index f1938441df..8f581cef10 100644 --- a/tests/template/templates/loop_size.html +++ b/tests/template/templates/loop_size.html @@ -36,4 +36,4 @@ in loop - + diff --git a/tests/template/templates/loop_underscore.html b/tests/template/templates/loop_underscore.html index dafce5dea6..4001007868 100644 --- a/tests/template/templates/loop_underscore.html +++ b/tests/template/templates/loop_underscore.html @@ -2,7 +2,7 @@ loop noloop - + loop diff --git a/tests/template/templates/loop_vars.html b/tests/template/templates/loop_vars.html index d94a0ae0f7..7d86d4b7b6 100644 --- a/tests/template/templates/loop_vars.html +++ b/tests/template/templates/loop_vars.html @@ -11,4 +11,3 @@ last last inner -inner loop From 1b2e5503ac770c1825664507cd4b9407d177a2d9 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 1 Jul 2013 12:07:29 -0500 Subject: [PATCH 071/156] [feature/twig] PHP test moved to a separate file This had to be done because cached template files are available in memory, so Twig doesn't ever reparse a template on the same page load PHPBB3-11598 --- tests/template/template_php_test.php | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 tests/template/template_php_test.php diff --git a/tests/template/template_php_test.php b/tests/template/template_php_test.php new file mode 100644 index 0000000000..9b5e855757 --- /dev/null +++ b/tests/template/template_php_test.php @@ -0,0 +1,21 @@ +setup_engine(array('tpl_allow_php' => true)); + + $this->run_template('php.html', array(), array(), array(), 'test'); + } +} \ No newline at end of file From e9bbeeb1a4c7d1c4b1d35848ff58f31af4483d07 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 1 Jul 2013 12:23:25 -0500 Subject: [PATCH 072/156] [feature/twig] Fix includephp node PHPBB3-11598 --- phpBB/includes/template/twig/node/includephp.php | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/phpBB/includes/template/twig/node/includephp.php b/phpBB/includes/template/twig/node/includephp.php index 5315d136d7..33142bf05a 100644 --- a/phpBB/includes/template/twig/node/includephp.php +++ b/phpBB/includes/template/twig/node/includephp.php @@ -46,19 +46,17 @@ class phpbb_template_twig_node_includephp extends Twig_Node ; } - // Replace variables in the expression - $expr = preg_replace('#{{ ([a-zA-Z0-9_]+) }}#', '\' . ((isset($context["$1"])) ? $context["$1"] : null) . \'', $this->getNode('expr')->getAttribute('value')); - $compiler - ->write("if (phpbb_is_absolute('$expr')) {\n") + ->write("\$location = ") + ->subcompile($this->getNode('expr')) + ->raw(";\n") + ->write("if (phpbb_is_absolute(\$location)) {\n") ->indent() - ->write("require('$expr');\n") + ->write("require(\$location);\n") ->outdent() ->write("} else {\n") ->indent() - ->write("require(\$this->getEnvironment()->get_phpbb_root_path() . '") - ->raw($expr) - ->raw("');\n") + ->write("require(\$this->getEnvironment()->get_phpbb_root_path() . \$location);\n") ->outdent() ->write("}\n") ; From 6c30441ad4a20fe4f154d5a859b9df0f28cbc8e0 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 1 Jul 2013 12:26:01 -0500 Subject: [PATCH 073/156] [feature/twig] Changing INCLUDEJS behavior slightly Automatically parsing inline variables the same way it is done for INCLUDE, INCLUDEPHP PHPBB3-11598 --- phpBB/includes/template/twig/lexer.php | 1 + .../styles/prosilver/template/memberlist_search.html | 2 +- phpBB/styles/prosilver/template/overall_footer.html | 2 +- phpBB/styles/prosilver/template/posting_buttons.html | 2 +- phpBB/styles/prosilver/template/timezone_option.html | 2 +- .../prosilver/template/ucp_avatar_options.html | 2 +- .../styles/subsilver2/template/timezone_option.html | 2 +- .../subsilver2/template/ucp_groups_manage.html | 2 +- .../subsilver2/template/ucp_profile_avatar.html | 2 +- tests/template/templates/includejs.html | 12 ++++++------ 10 files changed, 15 insertions(+), 14 deletions(-) diff --git a/phpBB/includes/template/twig/lexer.php b/phpBB/includes/template/twig/lexer.php index 131cf654ef..d9cc6f60ce 100644 --- a/phpBB/includes/template/twig/lexer.php +++ b/phpBB/includes/template/twig/lexer.php @@ -44,6 +44,7 @@ class phpbb_template_twig_lexer extends Twig_Lexer 'DEFINE.+=', 'INCLUDE', 'INCLUDEPHP', + 'INCLUDEJS', ), $code); // Fix our BEGIN statements diff --git a/phpBB/styles/prosilver/template/memberlist_search.html b/phpBB/styles/prosilver/template/memberlist_search.html index 97769b6155..6d2d87a278 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) // ]]> - +

{L_FIND_USERNAME}

diff --git a/phpBB/styles/prosilver/template/overall_footer.html b/phpBB/styles/prosilver/template/overall_footer.html index 01fc3f83da..5422cc7c10 100644 --- a/phpBB/styles/prosilver/template/overall_footer.html +++ b/phpBB/styles/prosilver/template/overall_footer.html @@ -55,7 +55,7 @@ - + {SCRIPTS} diff --git a/phpBB/styles/prosilver/template/posting_buttons.html b/phpBB/styles/prosilver/template/posting_buttons.html index b3e2b85492..164e887f75 100644 --- a/phpBB/styles/prosilver/template/posting_buttons.html +++ b/phpBB/styles/prosilver/template/posting_buttons.html @@ -52,7 +52,7 @@ // ]]> - + - + diff --git a/phpBB/styles/subsilver2/template/timezone_option.html b/phpBB/styles/subsilver2/template/timezone_option.html index d71166f517..9b68f81557 100644 --- a/phpBB/styles/subsilver2/template/timezone_option.html +++ b/phpBB/styles/subsilver2/template/timezone_option.html @@ -15,6 +15,6 @@ {S_TZ_OPTIONS} - + diff --git a/phpBB/styles/subsilver2/template/ucp_groups_manage.html b/phpBB/styles/subsilver2/template/ucp_groups_manage.html index 5595d19b9e..13b8b8c6b7 100644 --- a/phpBB/styles/subsilver2/template/ucp_groups_manage.html +++ b/phpBB/styles/subsilver2/template/ucp_groups_manage.html @@ -95,7 +95,7 @@ - + diff --git a/phpBB/styles/subsilver2/template/ucp_profile_avatar.html b/phpBB/styles/subsilver2/template/ucp_profile_avatar.html index 58ef499c41..885d46ef0b 100644 --- a/phpBB/styles/subsilver2/template/ucp_profile_avatar.html +++ b/phpBB/styles/subsilver2/template/ucp_profile_avatar.html @@ -48,6 +48,6 @@ - + diff --git a/tests/template/templates/includejs.html b/tests/template/templates/includejs.html index eca6e90637..ef73700eeb 100644 --- a/tests/template/templates/includejs.html +++ b/tests/template/templates/includejs.html @@ -1,8 +1,8 @@ - - + + - - - - + + + + {SCRIPTS} From 341bae40eb8e8238510a2cb1678f9594a3efd29e Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 1 Jul 2013 12:58:31 -0500 Subject: [PATCH 074/156] [feature/twig] Remove the twig loader class that I started (don't use it) PHPBB3-11598 --- phpBB/includes/template/twig/loader.php | 51 ------------------------- 1 file changed, 51 deletions(-) delete mode 100644 phpBB/includes/template/twig/loader.php diff --git a/phpBB/includes/template/twig/loader.php b/phpBB/includes/template/twig/loader.php deleted file mode 100644 index b153bd81ea..0000000000 --- a/phpBB/includes/template/twig/loader.php +++ /dev/null @@ -1,51 +0,0 @@ -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; - } -} From 6f925552a5a9101b3e8083a0bf27b64b3ffd382a Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 1 Jul 2013 13:06:37 -0500 Subject: [PATCH 075/156] [feature/twig] Fix includephp_from_subdir_test.php PHPBB3-11598 --- tests/template/subdir/includephp_from_subdir_test.php | 4 +--- tests/template/template_test_case.php | 8 ++++++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/template/subdir/includephp_from_subdir_test.php b/tests/template/subdir/includephp_from_subdir_test.php index 517cb85a30..6f9bc1efa6 100644 --- a/tests/template/subdir/includephp_from_subdir_test.php +++ b/tests/template/subdir/includephp_from_subdir_test.php @@ -19,9 +19,7 @@ class phpbb_template_subdir_includephp_from_subdir_test extends phpbb_template_t { $this->setup_engine(array('tpl_allow_php' => true)); - $cache_file = $this->template->cachepath . 'includephp_relative.html.php'; - - $this->run_template('includephp_relative.html', array(), array(), array(), "Path is relative to board root.\ntesting included php", $cache_file); + $this->run_template('includephp_relative.html', array(), array(), array(), "Path is relative to board root.\ntesting included php"); $this->template->set_filenames(array('test' => 'includephp_relative.html')); $this->assertEquals("Path is relative to board root.\ntesting included php", $this->display('test'), "Testing INCLUDEPHP"); diff --git a/tests/template/template_test_case.php b/tests/template/template_test_case.php index 0a12dff9f4..d3f1cc4646 100644 --- a/tests/template/template_test_case.php +++ b/tests/template/template_test_case.php @@ -105,9 +105,13 @@ class phpbb_template_template_test_case extends phpbb_test_case $this->template->destroy_block_vars($block); } - foreach ($lang_vars as $name => $value) + // Previous functionality was $cachefile (string), which was removed, check to prevent errors + if (is_array($lang_vars)) { - $this->user->lang[$name] = $value; + foreach ($lang_vars as $name => $value) + { + $this->user->lang[$name] = $value; + } } $expected = str_replace(array("\n", "\r", "\t"), '', $expected); From 3060cbe089fcb99ee3e7d66fe5b0e4bce171a88a Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 1 Jul 2013 13:17:59 -0500 Subject: [PATCH 076/156] [feature/twig] Fix template/template_php_test.php Must create a template file in the cache to load as this causes errors otherwise. The problem was that Twig builds template files into classes, which are always stored in PHP memory after being loaded. Because of this, Twig would never recompile a template that was already compiled on the same page load (so switching enable PHP on/off in two tests would not work). PHPBB3-11598 --- tests/template/template_php_test.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/template/template_php_test.php b/tests/template/template_php_test.php index 9b5e855757..fd4174953c 100644 --- a/tests/template/template_php_test.php +++ b/tests/template/template_php_test.php @@ -14,8 +14,17 @@ class phpbb_template_template_php_test extends phpbb_template_template_test_case { public function test_php() { + $template_text = 'echo "test";'; + + $cache_dir = dirname($this->template->cachepath) . '/'; + $fp = fopen($cache_dir . 'php.html', 'w'); + fputs($fp, $template_text); + fclose($fp); + $this->setup_engine(array('tpl_allow_php' => true)); + $this->style->set_custom_style('tests', $cache_dir, array(), ''); + $this->run_template('php.html', array(), array(), array(), 'test'); } -} \ No newline at end of file +} From 2d9bbe0ef218f56565d70a0e197ba91a80ea378b Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 1 Jul 2013 13:26:00 -0500 Subject: [PATCH 077/156] [feature/twig] Fix template/context.php PHPBB3-11598 --- phpBB/includes/template/context.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/template/context.php b/phpBB/includes/template/context.php index 8585e7d794..e3ad6be46c 100644 --- a/phpBB/includes/template/context.php +++ b/phpBB/includes/template/context.php @@ -181,7 +181,7 @@ class phpbb_template_context } // Assign S_BLOCK_NAME - $vararray['S_BLOCK_NAME'] = $blocks[$blockcount]; + $vararray['S_BLOCK_NAME'] = $blockname; // We always assign S_LAST_ROW and remove the entry before $vararray['S_LAST_ROW'] = true; @@ -196,7 +196,7 @@ class phpbb_template_context // Set S_NUM_ROWS foreach ($this->tpldata[$blockname] as &$mod_block) { - $mod_block['S_NUM_ROWS'] = $blockcount; + $mod_block['S_NUM_ROWS'] = sizeof($this->tpldata[$blockname]); } } From bdc05b7dc8ee2363dfe1a7fa70bc4118140ed351 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 1 Jul 2013 13:28:08 -0500 Subject: [PATCH 078/156] [feature/twig] Remove resource locator dependency from template PHPBB3-11598 --- phpBB/config/services.yml | 1 - phpBB/includes/bbcode.php | 2 +- phpBB/includes/functions_messenger.php | 2 +- phpBB/includes/template/twig/twig.php | 3 +-- phpBB/install/index.php | 2 +- tests/controller/helper_url_test.php | 3 +-- tests/extension/metadata_manager_test.php | 1 - tests/template/template_events_test.php | 2 +- tests/template/template_test_case.php | 2 +- tests/template/template_test_case_with_tree.php | 2 +- 10 files changed, 8 insertions(+), 12 deletions(-) diff --git a/phpBB/config/services.yml b/phpBB/config/services.yml index 4713cb21a6..32bd493743 100644 --- a/phpBB/config/services.yml +++ b/phpBB/config/services.yml @@ -260,7 +260,6 @@ services: - %core.php_ext% - @config - @user - - @style.resource_locator - @template_context - @ext.manager diff --git a/phpBB/includes/bbcode.php b/phpBB/includes/bbcode.php index 5a4161bb6c..ecbb056045 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_twig($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, 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 f0736fbb45..b117fda5b4 100644 --- a/phpBB/includes/functions_messenger.php +++ b/phpBB/includes/functions_messenger.php @@ -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_twig($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, 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/template/twig/twig.php b/phpBB/includes/template/twig/twig.php index 5fe8ba97f6..1d36ceadba 100644 --- a/phpBB/includes/template/twig/twig.php +++ b/phpBB/includes/template/twig/twig.php @@ -96,11 +96,10 @@ class phpbb_template_twig implements phpbb_template * * @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) + public function __construct($phpbb_root_path, $php_ext, $config, $user, phpbb_template_context $context, phpbb_extension_manager $extension_manager = null) { $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; diff --git a/phpBB/install/index.php b/phpBB/install/index.php index e16109086d..84a2a023f8 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_twig($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, 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/tests/controller/helper_url_test.php b/tests/controller/helper_url_test.php index 42c416b1d2..e376efde66 100644 --- a/tests/controller/helper_url_test.php +++ b/tests/controller/helper_url_test.php @@ -50,10 +50,9 @@ class phpbb_controller_helper_url_test extends phpbb_test_case $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_twig($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, 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 9dfb45b38e..bd88f396d9 100644 --- a/tests/extension/metadata_manager_test.php +++ b/tests/extension/metadata_manager_test.php @@ -47,7 +47,6 @@ class phpbb_extension_metadata_manager_test extends phpbb_database_test_case $this->phpEx, $this->config, $this->user, - new phpbb_style_resource_locator(), new phpbb_template_context() ); diff --git a/tests/template/template_events_test.php b/tests/template/template_events_test.php index 07181fcc4d..f7bcd2dcc6 100644 --- a/tests/template/template_events_test.php +++ b/tests/template/template_events_test.php @@ -107,7 +107,7 @@ Zeta test event in all', $this->extension_manager = new phpbb_mock_filesystem_extension_manager( dirname(__FILE__) . "/datasets/$dataset/" ); - $this->template = new phpbb_template_twig($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, 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 d3f1cc4646..63f0c873b0 100644 --- a/tests/template/template_test_case.php +++ b/tests/template/template_test_case.php @@ -69,7 +69,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_twig($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, new phpbb_template_context()); $this->style = new phpbb_style($phpbb_root_path, $phpEx, $config, $this->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 e9862bcecc..4b8cbada45 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_twig($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, 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(), ''); } From 793ee3f8d9d1ccc971d7b7118b981463b7de0938 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 1 Jul 2013 13:32:43 -0500 Subject: [PATCH 079/156] [feature/twig] Remove debug code, set debug/auto reload correctly PHPBB3-11598 --- phpBB/includes/template/twig/twig.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/phpBB/includes/template/twig/twig.php b/phpBB/includes/template/twig/twig.php index 1d36ceadba..377a0a47a8 100644 --- a/phpBB/includes/template/twig/twig.php +++ b/phpBB/includes/template/twig/twig.php @@ -120,16 +120,12 @@ class phpbb_template_twig implements phpbb_template $loader, array( 'cache' => $this->cachepath, - 'debug' => true, // @todo - 'auto_reload' => true, // @todo + 'debug' => defined('DEBUG'), + 'auto_reload' => (bool) $this->config['load_tplcompile'], 'autoescape' => false, ) ); - // Clear previous cache files (while WIP) - // @todo remove - $this->clear_cache(); - $this->twig->addExtension( new phpbb_template_twig_extension( $this->user From 9fbba760fbb79482976ec9107f70889be2a177fd Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 1 Jul 2013 13:34:28 -0500 Subject: [PATCH 080/156] [feature/twig] Remove classes related to old template engine PHPBB3-11598 --- phpBB/includes/template/compile.php | 166 --- phpBB/includes/template/filter.php | 1261 ------------------ phpBB/includes/template/phpbb.php | 515 ------- phpBB/includes/template/renderer_eval.php | 60 - phpBB/includes/template/renderer_include.php | 60 - 5 files changed, 2062 deletions(-) delete mode 100644 phpBB/includes/template/compile.php delete mode 100644 phpBB/includes/template/filter.php delete mode 100644 phpBB/includes/template/phpbb.php delete mode 100644 phpBB/includes/template/renderer_eval.php delete mode 100644 phpBB/includes/template/renderer_include.php diff --git a/phpBB/includes/template/compile.php b/phpBB/includes/template/compile.php deleted file mode 100644 index 76cb3011df..0000000000 --- a/phpBB/includes/template/compile.php +++ /dev/null @@ -1,166 +0,0 @@ -filter_params = $this->default_filter_params = array( - 'allow_php' => $allow_php, - 'style_names' => $style_names, - 'locator' => $locator, - 'phpbb_root_path' => $phpbb_root_path, - 'extension_manager' => $extension_manager, - 'user' => $user, - 'template_compile' => $this, - 'cleanup' => true, - ); - } - - /** - * Set filter parameters - * - * @param array $params Array of parameters (will be merged onto $this->filter_params) - */ - public function set_filter_params($params) - { - $this->filter_params = array_merge( - $this->filter_params, - $params - ); - } - - /** - * Reset filter parameters to their default settings - */ - public function reset_filter_params() - { - $this->filter_params = $this->default_filter_params; - } - - /** - * Compiles template in $source_file and writes compiled template to - * cache directory - * - * @param string $handle Template handle to compile - * @param string $source_file Source template file - * @return bool Return true on success otherwise false - */ - public function compile_file_to_file($source_file, $compiled_file) - { - $lock = new phpbb_lock_flock($compiled_file); - $lock->acquire(); - - $source_handle = @fopen($source_file, 'rb'); - $destination_handle = @fopen($compiled_file, 'wb'); - - if (!$source_handle || !$destination_handle) - { - return false; - } - - $this->compile_stream_to_stream($source_handle, $destination_handle); - - @fclose($source_handle); - @fclose($destination_handle); - - phpbb_chmod($compiled_file, CHMOD_READ | CHMOD_WRITE); - - $lock->release(); - - clearstatcache(); - - return true; - } - - /** - * Compiles a template located at $source_file. - * - * Returns PHP source suitable for eval(). - * - * @param string $source_file Source template file - * @return string|bool Return compiled code on successful compilation otherwise false - */ - public function compile_file($source_file) - { - $source_handle = @fopen($source_file, 'rb'); - $destination_handle = @fopen('php://temp' ,'r+b'); - - if (!$source_handle || !$destination_handle) - { - return false; - } - - $this->compile_stream_to_stream($source_handle, $destination_handle); - - @fclose($source_handle); - - rewind($destination_handle); - $contents = stream_get_contents($destination_handle); - @fclose($dest_handle); - - return $contents; - } - - /** - * Compiles contents of $source_stream into $dest_stream. - * - * A stream filter is appended to $source_stream as part of the - * process. - * - * @param resource $source_stream Source stream - * @param resource $dest_stream Destination stream - * @return null - */ - private function compile_stream_to_stream($source_stream, $dest_stream) - { - stream_filter_append($source_stream, 'phpbb_template', null, $this->filter_params); - stream_copy_to_stream($source_stream, $dest_stream); - } -} diff --git a/phpBB/includes/template/filter.php b/phpBB/includes/template/filter.php deleted file mode 100644 index 1c0a56c9f5..0000000000 --- a/phpBB/includes/template/filter.php +++ /dev/null @@ -1,1261 +0,0 @@ -'; - - const REGEX_TOKENS = '~|{((?:[a-z_][a-z_0-9]+\.)*\\$?[A-Z][A-Z_0-9]+)}~'; - - /** - * @var array - */ - private $block_names = array(); - - /** - * @var array - */ - private $block_else_level = array(); - - /** - * @var string - */ - private $chunk; - - /** - * @var bool - */ - private $in_php; - - /** - * Whether inline PHP code, and tags - * are allowed. If this is false all PHP code will be silently - * removed from the template during compilation. - * - * @var bool - */ - private $allow_php; - - /** - * Whether cleanup will be performed on resulting code, see compile() - * (Preserve whitespace) - * - * @var bool - */ - private $cleanup = true; - - /** - * Resource locator. - * - * @var phpbb_template_locator - */ - private $locator; - - /** - * @var string phpBB root path - */ - private $phpbb_root_path; - - /** - * 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; - - /** - * Extension manager. - * - * @var phpbb_extension_manager - */ - private $extension_manager; - - /** - * Current user - * - * @var phpbb_user - */ - private $user; - - /** - * Template compiler. - * - * @var phpbb_template_compile - */ - private $template_compile; - - /** - * Stream filter - * - * Is invoked for evey chunk of the stream, allowing us - * to work on a chunk at a time, which saves memory. - */ - public function filter($in, $out, &$consumed, $closing) - { - $written = false; - $first = false; - - while ($bucket = stream_bucket_make_writeable($in)) - { - $consumed += $bucket->datalen; - - $data = $this->chunk . $bucket->data; - $last_nl = strrpos($data, "\n"); - $this->chunk = substr($data, $last_nl); - $data = substr($data, 0, $last_nl); - - if (!strlen($data)) - { - continue; - } - - $written = true; - - $data = $this->compile($data); - if (!$first) - { - $data = $this->prepend_preamble($data); - $first = false; - } - $bucket->data = $data; - $bucket->datalen = strlen($bucket->data); - stream_bucket_append($out, $bucket); - } - - if ($closing && strlen($this->chunk)) - { - $written = true; - $bucket = stream_bucket_new($this->stream, $this->compile($this->chunk)); - stream_bucket_append($out, $bucket); - } - - return $written ? PSFS_PASS_ON : PSFS_FEED_ME; - } - - /** - * Initializer, called on creation. - * - * Get the allow_php option, style_names, root directory and locator from params, - * which are passed to stream_filter_append. - * - * @return boolean Returns true - */ - public function onCreate() - { - $this->chunk = ''; - $this->in_php = false; - $this->allow_php = $this->params['allow_php']; - $this->locator = $this->params['locator']; - $this->phpbb_root_path = $this->params['phpbb_root_path']; - $this->style_names = $this->params['style_names']; - $this->extension_manager = $this->params['extension_manager']; - $this->cleanup = $this->params['cleanup']; - if (isset($this->params['user'])) - { - $this->user = $this->params['user']; - } - $this->template_compile = $this->params['template_compile']; - return true; - } - - /** - * Compiles a chunk of template. - * - * The chunk must comprise of one or more complete lines from the source - * template. - * - * @param string $data Chunk of source template to compile - * @return string Compiled PHP/HTML code - */ - private function compile($data) - { - $block_start_in_php = $this->in_php; - - $data = preg_replace('#<(?:[\\?%]|script)#s', '', $data); - $data = preg_replace_callback(self::REGEX_TOKENS, array($this, 'replace'), $data); - - // Remove php - if (!$this->allow_php) - { - if ($block_start_in_php - && $this->in_php - && strpos($data, '') === false - && strpos($data, '') === false) - { - // This is just php code - return ''; - } - $data = preg_replace('~^.*?~', '', $data); - $data = preg_replace('~.*?~', '', $data); - $data = preg_replace('~.*?$~', '', $data); - } - - if ($this->cleanup) - { - /* - - Preserve whitespace. - PHP removes a newline after the closing tag (if it's there). - This is by design: - - http://www.php.net/manual/en/language.basic-syntax.phpmode.php - http://www.php.net/manual/en/language.basic-syntax.instruction-separation.php - - - Consider the following template: - - - some content - - - If we were to simply preserve all whitespace, we could simply - replace all "?>" tags with "?>\n". - Doing that, would add additional newlines to the compiled - template in place of the IF and ENDIF statements. These - newlines are unwanted (and one is conditional). The IF and - ENDIF are usually on their own line for ease of reading. - - This replacement preserves newlines only for statements that - are not the only statement on a line. It will NOT preserve - newlines at the end of statements in the above example. - It will preserve newlines in situations like: - - inline content - - */ - - $data = preg_replace('~(?)$~m', "$1\n", $data); - $data = str_replace('/**/?>', "?>\n", $data); - $data = str_replace('?>' . $data); - return $data; - } - - /** - * Callback for replacing matched tokens with compiled template code. - * - * Compiled template code is an HTML stream with embedded PHP. - * - * @param array $matches Regular expression matches - * @return string compiled template code - */ - private function replace($matches) - { - if ($this->in_php && $matches[1] != 'ENDPHP') - { - return ''; - } - - if (isset($matches[3])) - { - return $this->compile_var_tags($matches[0]); - } - - switch ($matches[1]) - { - case 'BEGIN': - $this->block_else_level[] = false; - return 'compile_tag_block($matches[2]) . ' ?>'; - break; - - case 'BEGINELSE': - $this->block_else_level[sizeof($this->block_else_level) - 1] = true; - return ''; - break; - - case 'END': - array_pop($this->block_names); - return 'block_else_level)) ? '}' : '}}') . ' ?>'; - break; - - case 'IF': - return 'compile_tag_if($matches[2], false) . ' ?>'; - break; - - case 'ELSE': - return ''; - break; - - case 'ELSEIF': - return 'compile_tag_if($matches[2], true) . ' ?>'; - break; - - case 'ENDIF': - return ''; - break; - - case 'DEFINE': - return 'compile_tag_define($matches[2], true) . ' ?>'; - break; - - case 'UNDEFINE': - return 'compile_tag_define($matches[2], false) . ' ?>'; - break; - - case 'ENDDEFINE': - return 'compile_tag_enddefine() . ' ?>'; - break; - - case 'INCLUDE': - return 'compile_tag_include($matches[2]) . ' ?>'; - break; - - case 'INCLUDEPHP': - return ($this->allow_php) ? 'compile_tag_include_php($matches[2]) . ' ?>' : ''; - break; - - case 'INCLUDEJS': - return 'compile_tag_include_js($matches[2]) . ' ?>'; - break; - - case 'PHP': - if ($this->allow_php) - { - $this->in_php = true; - return ''; - break; - - case 'ENDPHP': - if ($this->allow_php) - { - $this->in_php = false; - return ' ?>'; - } - return ''; - break; - - case 'EVENT': - return 'compile_tag_event($matches[2]) . '?>'; - break; - - default: - return $matches[0]; - break; - - } - return ''; - } - - /** - * Convert template variables into PHP varrefs - * - * @param string $text_blocks Variable reference in source template - * @param bool $is_expr Returns whether the source was an expression type variable (i.e. S_FIRST_ROW) - * @return string PHP variable name - */ - private function get_varref($text_blocks, &$is_expr) - { - // change template varrefs into PHP varrefs - $varrefs = array(); - - // This one will handle varrefs WITH namespaces - preg_match_all('#\{((?:' . self::REGEX_NS . '\.)+)(\$)?(' . self::REGEX_VAR . ')\}#', $text_blocks, $varrefs, PREG_SET_ORDER); - - foreach ($varrefs as $var_val) - { - $namespace = $var_val[1]; - $varname = $var_val[3]; - $new = $this->generate_block_varref($namespace, $varname, $is_expr, $var_val[2]); - - $text_blocks = str_replace($var_val[0], $new, $text_blocks); - } - - // Language variables cannot be reduced to a single varref, so they must be skipped - // These two replacements would break language variables, so we can only run them on non-language types - if (strpos($text_blocks, '{L_') === false && strpos($text_blocks, '{LA_') === false) - { - // This will handle the remaining root-level varrefs - $text_blocks = preg_replace('#\{(' . self::REGEX_VAR . ')\}#', "\$_rootref['\\1']", $text_blocks); - $text_blocks = preg_replace('#\{\$(' . self::REGEX_VAR . ')\}#', "\$_tpldata['DEFINE']['.']['\\1']", $text_blocks); - } - - return $text_blocks; - } - - /** - * Parse paths of the form {FOO}/a/{BAR}/b - * - * Note: this method assumes at least one variable in the path, this should - * be checked before this method is called. - * - * @param string $path The path to parse - * @param string $include_type The type of template function to call - * @return string An appropriately formatted string to include in the - * template or an empty string if an expression like S_FIRST_ROW was - * incorrectly used - */ - private function parse_dynamic_path($path, $include_type) - { - $matches = array(); - $replace = array(); - $is_expr = true; - - preg_match_all('#\{((?:' . self::REGEX_NS . '\.)*)(\$)?(' . self::REGEX_VAR . ')\}#', $path, $matches); - foreach ($matches[0] as $var_str) - { - $tmp_is_expr = false; - $var = $this->get_varref($var_str, $tmp_is_expr); - $is_expr = $is_expr && $tmp_is_expr; - $replace[] = "' . $var . '"; - } - - if (!$is_expr) - { - return " \$_template->$include_type('" . str_replace($matches[0], $replace, $path) . "', true);"; - } - else - { - return ''; - } - } - - /** - * Compile variables - * - * @param string $text_blocks Variable reference in source template - * @return string compiled template code - */ - private function compile_var_tags(&$text_blocks) - { - $is_expr = null; - $text_blocks = $this->get_varref($text_blocks, $is_expr); - $lang_replaced = $this->compile_language_tags($text_blocks); - - if(!$lang_replaced) - { - $text_blocks = ''; - } - - return $text_blocks; - } - - /** - * Handles special language tags L_ and LA_ - * - * @param string $text_blocks Variable reference in source template - * @return bool Whether a replacement occurred or not - */ - private function compile_language_tags(&$text_blocks) - { - $replacements = 0; - - // transform vars prefixed by L_ into their language variable pendant if nothing is set within the tpldata array - if (strpos($text_blocks, '{L_') !== false) - { - $text_blocks = preg_replace('#\{L_(' . self::REGEX_VAR_SUFFIX . ')\}#', "", $text_blocks, -1, $replacements); - return (bool) $replacements; - } - - // Handle addslashed language variables prefixed with LA_ - // If a template variable already exist, it will be used in favor of it... - if (strpos($text_blocks, '{LA_') !== false) - { - $text_blocks = preg_replace('#\{LA_(' . self::REGEX_VAR_SUFFIX . '+)\}#', "", $text_blocks, -1, $replacements); - return (bool) $replacements; - } - - return false; - } - - /** - * Compile blocks - * - * @param string $tag_args Block contents in source template - * @return string compiled template code - */ - private function compile_tag_block($tag_args) - { - $no_nesting = false; - - // Is the designer wanting to call another loop in a loop? - // - // - // - // - // 'loop2' is actually on the same nesting level as 'loop' you assign - // variables to it with template->assign_block_vars('loop2', array(...)) - if (strpos($tag_args, '!') === 0) - { - // Count the number if ! occurrences (not allowed in vars) - $no_nesting = substr_count($tag_args, '!'); - $tag_args = substr($tag_args, $no_nesting); - } - - // Allow for control of looping (indexes start from zero): - // foo(2) : Will start the loop on the 3rd entry - // foo(-2) : Will start the loop two entries from the end - // foo(3,4) : Will start the loop on the fourth entry and end it on the fifth - // foo(3,-4) : Will start the loop on the fourth entry and end it four from last - $match = array(); - - if (preg_match('#^([^()]*)\(([\-\d]+)(?:,([\-\d]+))?\)$#', $tag_args, $match)) - { - $tag_args = $match[1]; - - if ($match[2] < 0) - { - $loop_start = '($_' . $tag_args . '_count ' . $match[2] . ' < 0 ? 0 : $_' . $tag_args . '_count ' . $match[2] . ')'; - } - else - { - $loop_start = '($_' . $tag_args . '_count < ' . $match[2] . ' ? $_' . $tag_args . '_count : ' . $match[2] . ')'; - } - - if (!isset($match[3]) || strlen($match[3]) < 1 || $match[3] == -1) - { - $loop_end = '$_' . $tag_args . '_count'; - } - else if ($match[3] >= 0) - { - $loop_end = '(' . ($match[3] + 1) . ' > $_' . $tag_args . '_count ? $_' . $tag_args . '_count : ' . ($match[3] + 1) . ')'; - } - else //if ($match[3] < -1) - { - $loop_end = '$_' . $tag_args . '_count' . ($match[3] + 1); - } - } - else - { - $loop_start = 0; - $loop_end = '$_' . $tag_args . '_count'; - } - - $tag_template_php = ''; - array_push($this->block_names, $tag_args); - - if ($no_nesting !== false) - { - // We need to implode $no_nesting times from the end... - $block = array_slice($this->block_names, -$no_nesting); - } - else - { - $block = $this->block_names; - } - - if (sizeof($block) < 2) - { - // Block is not nested. - $tag_template_php = '$_' . $tag_args . "_count = (isset(\$_tpldata['$tag_args'])) ? sizeof(\$_tpldata['$tag_args']) : 0;"; - $varref = "\$_tpldata['$tag_args']"; - } - else - { - // This block is nested. - // Generate a namespace string for this block. - $namespace = implode('.', $block); - - // Get a reference to the data array for this block that depends on the - // current indices of all parent blocks. - $varref = $this->generate_block_data_ref($namespace, false); - - // Create the for loop code to iterate over this block. - $tag_template_php = '$_' . $tag_args . '_count = (isset(' . $varref . ')) ? sizeof(' . $varref . ') : 0;'; - } - - $tag_template_php .= 'if ($_' . $tag_args . '_count) {'; - - /** - * The following uses foreach for iteration instead of a for loop, foreach is faster but requires PHP to make a copy of the contents of the array which uses more memory - * - * if (!$offset) - * { - * $tag_template_php .= 'foreach (' . $varref . ' as $_' . $tag_args . '_i => $_' . $tag_args . '_val){'; - * } - * - */ - - $tag_template_php .= 'for ($_' . $tag_args . '_i = ' . $loop_start . '; $_' . $tag_args . '_i < ' . $loop_end . '; ++$_' . $tag_args . '_i){'; - $tag_template_php .= '$_' . $tag_args . '_val = &' . $varref . '[$_' . $tag_args . '_i];'; - - return $tag_template_php; - } - - /** - * Compile a general expression - much of this is from Smarty with - * some adaptions for our block level methods - * - * @param string $tag_args Expression (tag arguments) in source template - * @return string compiled template code - */ - private function compile_expression($tag_args) - { - $match = array(); - preg_match_all('/(?: - "[^"\\\\]*(?:\\\\.[^"\\\\]*)*" | - \'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\' | - [(),] | - [^\s(),]+)/x', $tag_args, $match); - - $tokens = $match[0]; - $is_arg_stack = array(); - - for ($i = 0, $size = sizeof($tokens); $i < $size; $i++) - { - $token = &$tokens[$i]; - - switch ($token) - { - case '!==': - case '===': - case '<<': - case '>>': - case '|': - case '^': - case '&': - case '~': - case ')': - case ',': - case '+': - case '-': - case '*': - case '/': - case '@': - break; - - case '==': - case 'eq': - $token = '=='; - break; - - case '!=': - case '<>': - case 'ne': - case 'neq': - $token = '!='; - break; - - case '<': - case 'lt': - $token = '<'; - break; - - case '<=': - case 'le': - case 'lte': - $token = '<='; - break; - - case '>': - case 'gt': - $token = '>'; - break; - - case '>=': - case 'ge': - case 'gte': - $token = '>='; - break; - - case '&&': - case 'and': - $token = '&&'; - break; - - case '||': - case 'or': - $token = '||'; - break; - - case '!': - case 'not': - $token = '!'; - break; - - case '%': - case 'mod': - $token = '%'; - break; - - case '(': - array_push($is_arg_stack, $i); - break; - - case 'is': - $is_arg_start = ($tokens[$i-1] == ')') ? array_pop($is_arg_stack) : $i-1; - $is_arg = implode(' ', array_slice($tokens, $is_arg_start, $i - $is_arg_start)); - - $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i+1)); - - array_splice($tokens, $is_arg_start, sizeof($tokens), $new_tokens); - - $i = $is_arg_start; - - // no break - - default: - $varrefs = array(); - if (preg_match('#^((?:' . self::REGEX_NS . '\.)+)?(\$)?(?=[A-Z])([A-Z0-9\-_]+)#s', $token, $varrefs)) - { - if (!empty($varrefs[1])) - { - $namespace = substr($varrefs[1], 0, -1); - $dot_pos = strrchr($namespace, '.'); - if ($dot_pos !== false) - { - $namespace = substr($dot_pos, 1); - } - - // S_ROW_COUNT is deceptive, it returns the current row number not the number of rows - // hence S_ROW_COUNT is deprecated in favour of S_ROW_NUM - switch ($varrefs[3]) - { - case 'S_ROW_NUM': - case 'S_ROW_COUNT': - $token = "\$_${namespace}_i"; - break; - - case 'S_NUM_ROWS': - $token = "\$_${namespace}_count"; - break; - - case 'S_FIRST_ROW': - $token = "(\$_${namespace}_i == 0)"; - break; - - case 'S_LAST_ROW': - $token = "(\$_${namespace}_i == \$_${namespace}_count - 1)"; - break; - - case 'S_BLOCK_NAME': - $token = "'$namespace'"; - break; - - default: - $token = $this->generate_block_data_ref(substr($varrefs[1], 0, -1), true, $varrefs[2]) . '[\'' . $varrefs[3] . '\']'; - $token = '(isset(' . $token . ') ? ' . $token . ' : null)'; - break; - } - } - else - { - $token = ($varrefs[2]) ? '$_tpldata[\'DEFINE\'][\'.\'][\'' . $varrefs[3] . '\']' : '$_rootref[\'' . $varrefs[3] . '\']'; - $token = '(isset(' . $token . ') ? ' . $token . ' : null)'; - } - - } - else if (preg_match('#^\.((?:' . self::REGEX_NS . '\.?)+)$#s', $token, $varrefs)) - { - // Allow checking if loops are set with .loopname - // It is also possible to check the loop count by doing for example - $blocks = explode('.', $varrefs[1]); - - // If the block is nested, we have a reference that we can grab. - // If the block is not nested, we just go and grab the block from _tpldata - if (sizeof($blocks) > 1) - { - $block = array_pop($blocks); - $namespace = implode('.', $blocks); - $varref = $this->generate_block_data_ref($namespace, true); - - // Add the block reference for the last child. - $varref .= "['" . $block . "']"; - } - else - { - $varref = '$_tpldata'; - - // Add the block reference for the last child. - $varref .= "['" . $blocks[0] . "']"; - } - $token = "(isset($varref) ? sizeof($varref) : 0)"; - } - - break; - } - } - - return $tokens; - } - - /** - * Compile IF tags - * - * @param string $tag_args Expression given with IF in source template - * @param bool $elseif True if compiling an IF tag, false if compiling an ELSEIF tag - * @return string compiled template code - */ - private function compile_tag_if($tag_args, $elseif) - { - $tokens = $this->compile_expression($tag_args); - - $tpl = ($elseif) ? '} else if (' : 'if ('; - - $tpl .= implode(' ', $tokens); - $tpl .= ') { '; - - return $tpl; - } - - /** - * Compile DEFINE tags - * - * @param string $tag_args Expression given with DEFINE in source template - * @param bool $op True if compiling a DEFINE tag, false if compiling an UNDEFINE tag - * @return string compiled template code - */ - private function compile_tag_define($tag_args, $op) - { - $match = array(); - preg_match('#^((?:' . self::REGEX_NS . '\.)+)?\$(?=[A-Z])([A-Z0-9_\-]*)(?: = (.*?))?$#', $tag_args, $match); - - if (!empty($match[2]) && !isset($match[3]) && $op) - { - // DEFINE tag with ENDDEFINE - $array = "\$_tpldata['DEFINE']['.vars']"; - $code = 'ob_start(); '; - $code .= "if (!isset($array)) { $array = array(); } "; - $code .= "{$array}[] = '{$match[2]}'"; - return $code; - } - - if (empty($match[2]) || (!isset($match[3]) && $op)) - { - return ''; - } - - if (!$op) - { - return 'unset(' . (($match[1]) ? $this->generate_block_data_ref(substr($match[1], 0, -1), true, true) . '[\'' . $match[2] . '\']' : '$_tpldata[\'DEFINE\'][\'.\'][\'' . $match[2] . '\']') . ');'; - } - - /* - * Define tags that contain template variables (enclosed in curly brackets) - * need to be treated differently. - */ - if (substr($match[3], 1, 1) == '{' && substr($match[3], -2, 1) == '}') - { - $parsed_statement = implode(' ', $this->compile_expression(substr($match[3], 2, -2))); - } - else - { - $parsed_statement = implode(' ', $this->compile_expression($match[3])); - } - - return (($match[1]) ? $this->generate_block_data_ref(substr($match[1], 0, -1), true, true) . '[\'' . $match[2] . '\']' : '$_tpldata[\'DEFINE\'][\'.\'][\'' . $match[2] . '\']') . ' = ' . $parsed_statement . ';'; - } - - /** - * Compile ENDDEFINE tag - * - * @return string compiled template code - */ - private function compile_tag_enddefine() - { - $array = "\$_tpldata['DEFINE']['.vars']"; - $code = "if (!isset($array) || !sizeof($array)) { trigger_error('ENDDEFINE tag without DEFINE in ' . basename(__FILE__), E_USER_ERROR); }"; - $code .= "\$define_var = array_pop($array); "; - $code .= "\$_tpldata['DEFINE']['.'][\$define_var] = ob_get_clean();"; - return $code; - } - - /** - * Compile INCLUDE tag - * - * @param string $tag_args Expression given with INCLUDE in source template - * @return string compiled template code - */ - private function compile_tag_include($tag_args) - { - // Process dynamic includes - if (strpos($tag_args, '{') !== false) - { - return $this->parse_dynamic_path($tag_args, '_tpl_include'); - } - - return "\$_template->_tpl_include('$tag_args');"; - } - - /** - * Compile INCLUDE_PHP tag - * - * @param string $tag_args Expression given with INCLUDEPHP in source template - * @return string compiled template code - */ - private function compile_tag_include_php($tag_args) - { - if (strpos($tag_args, '{') !== false) - { - return $this->parse_dynamic_path($tag_args, '_php_include'); - } - - return "\$_template->_php_include('$tag_args');"; - } - - /** - * Compile EVENT tag. - * - * $tag_args should be a single string identifying the event. - * The event name can contain letters, numbers and underscores only. - * If an invalid event name is specified, an E_USER_ERROR will be - * triggered. - * - * Event tags are only functional when the template engine has - * an instance of the extension manager. Extension manager would - * be called upon to find all extensions listening for the specified - * event, and to obtain additional template fragments. All such - * template fragments will be compiled and included in the generated - * compiled template code for the current template being compiled. - * - * The above means that whenever an extension is enabled or disabled, - * template cache should be cleared in order to update the compiled - * template code for the active set of template event listeners. - * - * This also means that extensions cannot return different template - * fragments at different times. Once templates are compiled, changing - * such template fragments would have no effect. - * - * @param string $tag_args EVENT tag arguments, as a string - for EVENT this is the event name - * @return string compiled template code - */ - private function compile_tag_event($tag_args) - { - if (!preg_match('/^\w+$/', $tag_args)) - { - // The event location is improperly formatted, - if ($this->user) - { - trigger_error($this->user->lang('ERR_TEMPLATE_EVENT_LOCATION', $tag_args), E_USER_ERROR); - } - else - { - trigger_error(sprintf('The specified template event location [%s] is improperly formatted.', $tag_args), E_USER_ERROR); - } - } - $location = $tag_args; - - if ($this->extension_manager) - { - $finder = $this->extension_manager->get_finder(); - - $files = $finder - ->extension_prefix($location) - ->extension_suffix('.html') - ->extension_directory("/styles/all/template") - ->get_files(); - - foreach ($this->style_names as $style_name) - { - $more_files = $finder - ->extension_prefix($location) - ->extension_suffix('.html') - ->extension_directory("/styles/" . $style_name . "/template") - ->get_files(); - if (!empty($more_files)) - { - $files = array_merge($files, $more_files); - break; - } - } - - $all_compiled = ''; - foreach ($files as $file) - { - $this->template_compile->set_filter_params(array( - 'cleanup' => false, - )); - - $compiled = $this->template_compile->compile_file($file); - - $this->template_compile->reset_filter_params(); - - if ($compiled === false) - { - if ($this->user) - { - trigger_error($this->user->lang('ERR_TEMPLATE_COMPILATION', phpbb_filter_root_path($file)), E_USER_ERROR); - } - else - { - trigger_error(sprintf('The file could not be compiled: %s', phpbb_filter_root_path($file)), E_USER_ERROR); - } - } - - $all_compiled .= $compiled; - } - // Need spaces inside php tags as php cannot grok - // < ?php? > sans the spaces - return ' ?' . '>' . $all_compiled . 'parse_dynamic_path($tag_args, '_js_include'); - } - - // Locate file - $filename = $this->locator->get_first_file_location(array($tag_args), false, true); - - if ($filename === false) - { - // File does not exist, find it during run time - return ' $_template->_js_include(\'' . addslashes($tag_args) . '\', true); '; - } - - if (substr($filename, 0, strlen($this->phpbb_root_path)) != $this->phpbb_root_path) - { - // Absolute path, include as is - return ' $_template->_js_include(\'' . addslashes($filename) . '\', false, false); '; - } - - // Relative path, remove root path from it - $filename = substr($filename, strlen($this->phpbb_root_path)); - return ' $_template->_js_include(\'' . addslashes($filename) . '\', false, true); '; - } - - /** - * Generates a reference to the given variable inside the given (possibly nested) - * block namespace. This is a string of the form: - * ' . $_tpldata['parent'][$_parent_i]['$child1'][$_child1_i]['$child2'][$_child2_i]...['varname'] . ' - * It's ready to be inserted into an "echo" line in one of the templates. - * - * @param string $namespace Namespace to access (expects a trailing "." on the namespace) - * @param string $varname Variable name to use - * @param bool $expr Returns whether the source was an expression type - * @param bool $defop If true this is a variable created with the DEFINE construct, otherwise template variable - * @return string Code to access variable or echo it if $echo is true - */ - private function generate_block_varref($namespace, $varname, &$expr, $defop = false) - { - // Strip the trailing period. - $namespace = substr($namespace, 0, -1); - - if (($pos = strrpos($namespace, '.')) !== false) - { - $local_namespace = substr($namespace, $pos + 1); - } - else - { - $local_namespace = $namespace; - } - - $expr = true; - - // S_ROW_COUNT is deceptive, it returns the current row number now the number of rows - // hence S_ROW_COUNT is deprecated in favour of S_ROW_NUM - switch ($varname) - { - case 'S_ROW_NUM': - case 'S_ROW_COUNT': - $varref = "\$_${local_namespace}_i"; - break; - - case 'S_NUM_ROWS': - $varref = "\$_${local_namespace}_count"; - break; - - case 'S_FIRST_ROW': - $varref = "(\$_${local_namespace}_i == 0)"; - break; - - case 'S_LAST_ROW': - $varref = "(\$_${local_namespace}_i == \$_${local_namespace}_count - 1)"; - break; - - case 'S_BLOCK_NAME': - $varref = "'$local_namespace'"; - break; - - default: - // Get a reference to the data block for this namespace. - $varref = $this->generate_block_data_ref($namespace, true, $defop); - // Prepend the necessary code to stick this in an echo line. - - // Append the variable reference. - $varref .= "['$varname']"; - - $expr = false; - break; - } - // @todo Test the !$expr more - - return $varref; - } - - /** - * Generates a reference to the array of data values for the given - * (possibly nested) block namespace. This is a string of the form: - * $_tpldata['parent'][$_parent_i]['$child1'][$_child1_i]['$child2'][$_child2_i]...['$childN'] - * - * @param string $blockname Block to access (does not expect a trailing "." on the blockname) - * @param bool $include_last_iterator If $include_last_iterator is true, then [$_childN_i] will be appended to the form shown above. - * @param bool $defop If true this is a variable created with the DEFINE construct, otherwise template variable - * @return string Code to access variable - */ - private function generate_block_data_ref($blockname, $include_last_iterator, $defop = false) - { - // Get an array of the blocks involved. - $blocks = explode('.', $blockname); - $blockcount = sizeof($blocks) - 1; - - // DEFINE is not an element of any referenced variable, we must use _tpldata to access it - if ($defop) - { - $varref = '$_tpldata[\'DEFINE\']'; - // Build up the string with everything but the last child. - for ($i = 0; $i < $blockcount; $i++) - { - $varref .= "['" . $blocks[$i] . "'][\$_" . $blocks[$i] . '_i]'; - } - // Add the block reference for the last child. - $varref .= "['" . $blocks[$blockcount] . "']"; - // Add the iterator for the last child if requried. - if ($include_last_iterator) - { - $varref .= '[$_' . $blocks[$blockcount] . '_i]'; - } - return $varref; - } - else if ($include_last_iterator) - { - return '$_'. $blocks[$blockcount] . '_val'; - } - else - { - return '$_'. $blocks[$blockcount - 1] . '_val[\''. $blocks[$blockcount]. '\']'; - } - } -} diff --git a/phpBB/includes/template/phpbb.php b/phpBB/includes/template/phpbb.php deleted file mode 100644 index 8f4d163f8c..0000000000 --- a/phpBB/includes/template/phpbb.php +++ /dev/null @@ -1,515 +0,0 @@ - $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 = ''; - $this->context->append_var('SCRIPTS', $code); - } -} diff --git a/phpBB/includes/template/renderer_eval.php b/phpBB/includes/template/renderer_eval.php deleted file mode 100644 index f8e4cb7b10..0000000000 --- a/phpBB/includes/template/renderer_eval.php +++ /dev/null @@ -1,60 +0,0 @@ -code = $code; - $this->template = $template; - } - - /** - * Displays the template managed by this renderer by eval'ing php code - * of the template. - * - * @param phpbb_template_context $context Template context to use - * @param array $lang Language entries to use - */ - public function render($context, $lang) - { - $_template = $this->template; - $_tpldata = &$context->get_data_ref(); - $_rootref = &$context->get_root_ref(); - $_lang = $lang; - - eval(' ?>' . $this->code . 'path = $path; - $this->template = $template; - } - - /** - * Displays the template managed by this renderer by including - * the php file containing the template. - * - * @param phpbb_template_context $context Template context to use - * @param array $lang Language entries to use - */ - public function render($context, $lang) - { - $_template = $this->template; - $_tpldata = &$context->get_data_ref(); - $_rootref = &$context->get_root_ref(); - $_lang = $lang; - - include($this->path); - } -} From d7cff78443465a06d6aab519c3285a9b20b6cd50 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 1 Jul 2013 13:39:51 -0500 Subject: [PATCH 081/156] [feature/twig] Use adm_relative_path to build admin namespace PHPBB3-11598 --- phpBB/config/services.yml | 1 + phpBB/includes/template/twig/twig.php | 17 +++++++++++------ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/phpBB/config/services.yml b/phpBB/config/services.yml index 32bd493743..23205169b9 100644 --- a/phpBB/config/services.yml +++ b/phpBB/config/services.yml @@ -262,6 +262,7 @@ services: - @user - @template_context - @ext.manager + - %core.adm_relative_path% template_context: class: phpbb_template_context diff --git a/phpBB/includes/template/twig/twig.php b/phpBB/includes/template/twig/twig.php index 377a0a47a8..b5fb8eb860 100644 --- a/phpBB/includes/template/twig/twig.php +++ b/phpBB/includes/template/twig/twig.php @@ -40,6 +40,12 @@ class phpbb_template_twig implements phpbb_template */ protected $phpbb_root_path; + /** + * adm relative path + * @var string + */ + protected $adm_relative_path; + /** * PHP file extension * @var string @@ -92,16 +98,16 @@ class phpbb_template_twig implements phpbb_template /** * Constructor. * - * @todo remove unnecessary dependencies - * * @param string $phpbb_root_path phpBB root path * @param user $user current user * @param phpbb_template_context $context template context * @param phpbb_extension_manager $extension_manager extension manager, if null then template events will not be invoked + * @param string $adm_relative_path relative path to adm directory */ - public function __construct($phpbb_root_path, $php_ext, $config, $user, phpbb_template_context $context, phpbb_extension_manager $extension_manager = null) + public function __construct($phpbb_root_path, $php_ext, $config, $user, phpbb_template_context $context, phpbb_extension_manager $extension_manager = null, $adm_relative_path = null) { $this->phpbb_root_path = $phpbb_root_path; + $this->adm_relative_path = $adm_relative_path; $this->php_ext = $php_ext; $this->config = $config; $this->user = $user; @@ -186,10 +192,9 @@ class phpbb_template_twig implements phpbb_template } // Add admin namespace - // @todo use phpbb_admin path - if (is_dir($this->phpbb_root_path . 'adm/style/')) + if (is_dir($this->phpbb_root_path . $this->adm_relative_path . 'style/')) { - $this->twig->getLoader()->setPaths($this->phpbb_root_path . 'adm/style/', 'admin'); + $this->twig->getLoader()->setPaths($this->phpbb_root_path . $this->adm_relative_path . 'style/', 'admin'); } // Add all namespaces for all extensions From 1a58d188aab0c22965732621c8d93a00ea7a747e Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 1 Jul 2013 14:42:05 -0500 Subject: [PATCH 082/156] [feature/twig] Prevent errors from empty user->style PHPBB3-11598 --- phpBB/includes/template/twig/twig.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/template/twig/twig.php b/phpBB/includes/template/twig/twig.php index b5fb8eb860..3cd37e04e9 100644 --- a/phpBB/includes/template/twig/twig.php +++ b/phpBB/includes/template/twig/twig.php @@ -186,7 +186,7 @@ class phpbb_template_twig implements phpbb_template $this->twig->getLoader()->setPaths($style_paths); // Core style namespace from phpbb_style::set_style() - if ($this->user && ($style_names === array($this->user->style['style_path']) || $style_names[0] == $this->user->style['style_path'])) + if (isset($this->user->style['style_path']) && ($style_names === array($this->user->style['style_path']) || $style_names[0] == $this->user->style['style_path'])) { $this->twig->getLoader()->setPaths($style_paths, 'core'); } From 943728d3eff5b14b8936ccacf00dd729c9ac1d40 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 1 Jul 2013 14:58:20 -0500 Subject: [PATCH 083/156] [feature/twig] Fix length replace in lexer PHPBB3-11598 --- phpBB/includes/template/twig/lexer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/template/twig/lexer.php b/phpBB/includes/template/twig/lexer.php index d9cc6f60ce..b32a9e4ffa 100644 --- a/phpBB/includes/template/twig/lexer.php +++ b/phpBB/includes/template/twig/lexer.php @@ -182,7 +182,7 @@ class phpbb_template_twig_lexer extends Twig_Lexer $matches[1] = preg_replace('#\s\$([a-zA-Z_0-9]+)#', ' definition.$1', $matches[1]); // Replace .test with test|length - $matches[1] = preg_replace('#\s\.([a-zA-Z_0-9]+)#', ' $1|length', $matches[1]); + $matches[1] = preg_replace('#\s\.([a-zA-Z_0-9\.]+)#', ' $1|length', $matches[1]); return ''; }; From 46d6899b466ce57e605ee6cf708204a1dd92004f Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 1 Jul 2013 20:41:36 -0500 Subject: [PATCH 084/156] [feature/twig] Do not assign var by reference PHPBB3-11598 --- phpBB/includes/template/twig/twig.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/phpBB/includes/template/twig/twig.php b/phpBB/includes/template/twig/twig.php index 3cd37e04e9..89f6189f41 100644 --- a/phpBB/includes/template/twig/twig.php +++ b/phpBB/includes/template/twig/twig.php @@ -265,8 +265,7 @@ class phpbb_template_twig implements phpbb_template return $result[0]; } - $context = &$this->get_template_vars(); - $this->twig->display($this->get_filename_from_handle($handle), $context); + $this->twig->display($this->get_filename_from_handle($handle), $this->get_template_vars()); return true; } @@ -329,7 +328,7 @@ class phpbb_template_twig implements phpbb_template return $this->twig->render($this->get_filename_from_handle($handle)); } - $this->assign_var($template_var, $this->twig->render($this->get_filename_from_handle($handle))); + $this->assign_var($template_var, $this->twig->render($this->get_filename_from_handle($handle, $this->get_template_vars()))); return true; } From 1c7e077fea245448315068bc724d852d2c9b087e Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 1 Jul 2013 21:11:24 -0500 Subject: [PATCH 085/156] [feature/twig] Remove get_lang function (it's not used anywhere) PHPBB3-11598 --- phpBB/includes/template/twig/twig.php | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/phpBB/includes/template/twig/twig.php b/phpBB/includes/template/twig/twig.php index 89f6189f41..496c0b21a8 100644 --- a/phpBB/includes/template/twig/twig.php +++ b/phpBB/includes/template/twig/twig.php @@ -178,7 +178,7 @@ class phpbb_template_twig implements phpbb_template * @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()) + public function set_style_names(array $style_names, array $style_paths = array()) { $this->style_names = $style_names; @@ -292,26 +292,6 @@ class phpbb_template_twig implements phpbb_template 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. From 8f303b376b5677bb0203c6ffae9c8c456cf1e075 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 1 Jul 2013 21:16:36 -0500 Subject: [PATCH 086/156] [feature/twig] Don't forget to set the context when rendering! PHPBB3-11598 --- phpBB/includes/template/twig/twig.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/template/twig/twig.php b/phpBB/includes/template/twig/twig.php index 496c0b21a8..6b0771f77b 100644 --- a/phpBB/includes/template/twig/twig.php +++ b/phpBB/includes/template/twig/twig.php @@ -305,7 +305,7 @@ class phpbb_template_twig implements phpbb_template { if ($return_content) { - return $this->twig->render($this->get_filename_from_handle($handle)); + return $this->twig->render($this->get_filename_from_handle($handle), $this->get_template_vars()); } $this->assign_var($template_var, $this->twig->render($this->get_filename_from_handle($handle, $this->get_template_vars()))); From 16ebf14653c98cd842ee94a66d69b871a3ec0d25 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 1 Jul 2013 21:18:09 -0500 Subject: [PATCH 087/156] [feature/twig] Clean up the messenger a little bit This should fix at least one bug, noticed we were using: $this->vars = &$this->tpl_obj->_rootref; Which hasn't been valid for a long+ time PHPBB3-11598 --- phpBB/includes/functions_messenger.php | 103 +++++++++++++++---------- 1 file changed, 61 insertions(+), 42 deletions(-) diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php index b117fda5b4..5f1251c34e 100644 --- a/phpBB/includes/functions_messenger.php +++ b/phpBB/includes/functions_messenger.php @@ -27,8 +27,9 @@ class messenger var $mail_priority = MAIL_NORMAL_PRIORITY; var $use_queue = true; - var $tpl_obj = NULL; - var $tpl_msg = array(); + /** @var phpbb_template */ + protected $template; + var $eol = "\n"; /** @@ -210,6 +211,8 @@ class messenger { global $config, $phpbb_root_path, $phpEx, $user, $phpbb_extension_manager; + $this->setup_template(); + if (!trim($template_file)) { trigger_error('No template file for emailing set.', E_USER_ERROR); @@ -219,46 +222,43 @@ class messenger { // fall back to board default language if the user's language is // missing $template_file. If this does not exist either, - // $tpl->set_filenames will do a trigger_error + // $this->template->set_filenames will do a trigger_error $template_lang = basename($config['default_lang']); } - // tpl_msg now holds a template object we can use to parse the template file - if (!isset($this->tpl_msg[$template_lang . $template_file])) + if ($template_path) { - $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_twig($phpbb_root_path, $phpEx, $config, $user, new phpbb_template_context(), $phpbb_extension_manager); - $style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator, $style_path_provider, $tpl); + $template_paths = array( + $template_path, + ); + } + if (!$template_path) + { + $template_path = (!empty($user->lang_path)) ? $user->lang_path : $phpbb_root_path . 'language/'; + $template_path .= $template_lang . '/email'; - $this->tpl_msg[$template_lang . $template_file] = $tpl; + $template_paths = array( + $template_path, + ); - $fallback_template_path = false; - - if (!$template_path) + // we can only specify default language fallback when the path is not a custom one for which we + // do not know the default language alternative + if ($template_lang !== basename($config['default_lang'])) { - $template_path = (!empty($user->lang_path)) ? $user->lang_path : $phpbb_root_path . 'language/'; - $template_path .= $template_lang . '/email'; + $fallback_template_path = (!empty($user->lang_path)) ? $user->lang_path : $phpbb_root_path . 'language/'; + $fallback_template_path .= basename($config['default_lang']) . '/email'; - // we can only specify default language fallback when the path is not a custom one for which we - // do not know the default language alternative - if ($template_lang !== basename($config['default_lang'])) - { - $fallback_template_path = (!empty($user->lang_path)) ? $user->lang_path : $phpbb_root_path . 'language/'; - $fallback_template_path .= basename($config['default_lang']) . '/email'; - } + $template_paths[] = $fallback_template_path; } - - $style->set_custom_style($template_lang . '_email', array($template_path, $fallback_template_path), array(), ''); - - $tpl->set_filenames(array( - 'body' => $template_file . '.txt', - )); } - $this->tpl_obj = &$this->tpl_msg[$template_lang . $template_file]; - $this->vars = &$this->tpl_obj->_rootref; - $this->tpl_msg = ''; + $this->set_template_paths($template_lang . '_email', $template_paths); + + $this->template->set_filenames(array( + 'body' => $template_file . '.txt', + )); + + $this->vars = $this->template->get_template_vars(); return true; } @@ -268,22 +268,16 @@ class messenger */ function assign_vars($vars) { - if (!is_object($this->tpl_obj)) - { - return; - } + $this->setup_template(); - $this->tpl_obj->assign_vars($vars); + $this->template->assign_vars($vars); } function assign_block_vars($blockname, $vars) { - if (!is_object($this->tpl_obj)) - { - return; - } + $this->setup_template(); - $this->tpl_obj->assign_block_vars($blockname, $vars); + $this->template->assign_block_vars($blockname, $vars); } /** @@ -316,7 +310,7 @@ class messenger } // Parse message through template - $this->msg = trim($this->tpl_obj->assign_display('body')); + $this->msg = trim($this->template->assign_display('body')); // Because we use \n for newlines in the body message we need to fix line encoding errors for those admins who uploaded email template files in the wrong encoding $this->msg = str_replace("\r\n", "\n", $this->msg); @@ -643,6 +637,31 @@ class messenger unset($addresses); return true; } + + /** + * Setup template engine + */ + protected function setup_template() + { + global $config, $phpbb_root_path, $phpEx, $user, $phpbb_extension_manager; + + if ($this->template instanceof phpbb_template) + { + return; + } + + $this->template = new phpbb_template_twig($phpbb_root_path, $phpEx, $config, $user, new phpbb_template_context(), $phpbb_extension_manager); + } + + /** + * Set template paths to load + */ + protected function set_template_paths($path_name, $paths) + { + $this->setup_template(); + + $this->template->set_style_names(array($path_name), $paths); + } } /** From e0f5e23032ce080c163439c1089a7b4994276da6 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 1 Jul 2013 21:21:37 -0500 Subject: [PATCH 088/156] [feature/twig] Fixed tabs in environment.php PHPBB3-11598 --- phpBB/includes/template/twig/environment.php | 81 ++++++++++---------- 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/phpBB/includes/template/twig/environment.php b/phpBB/includes/template/twig/environment.php index d20da965c3..34e6f09981 100644 --- a/phpBB/includes/template/twig/environment.php +++ b/phpBB/includes/template/twig/environment.php @@ -29,7 +29,7 @@ class phpbb_template_twig_environment extends Twig_Environment /** @var array **/ protected $namespaceLookUpOrder = array('__main__'); - public function __construct($phpbb_config, $phpbb_extensions, $phpbb_root_path, Twig_LoaderInterface $loader = null, $options = array()) + public function __construct($phpbb_config, $phpbb_extensions, $phpbb_root_path, Twig_LoaderInterface $loader = null, $options = array()) { $this->phpbb_config = $phpbb_config; $this->phpbb_extensions = $phpbb_extensions; @@ -38,19 +38,20 @@ class phpbb_template_twig_environment extends Twig_Environment return parent::__construct($loader, $options); } - /** - * Gets the cache filename for a given template. - * - * @param string $name The template name - * - * @return string The cache file name - */ - public function ignoregetCacheFilename($name) - { - if (false === $this->cache) { - return false; - } -// @todo + /** + * Gets the cache filename for a given template. + * + * @param string $name The template name + * + * @return string The cache file name + */ + public function ignoregetCacheFilename($name) + { + if (false === $this->cache) + { + return false; + } + // @todo $file_path = $this->getLoader()->getCacheKey($name); foreach ($this->getLoader()->getNamespaces() as $namespace) { @@ -64,9 +65,9 @@ class phpbb_template_twig_environment extends Twig_Environment } // We probably should never get here under normal circumstances - return $this->getCache() . '/' . preg_replace('#[^a-zA-Z0-9_/]#', '_', $name) . '.php'; - return $this->getCache() . '/' . preg_replace('#[^a-zA-Z0-9_/]#', '_', $name) . '_' . md5($this->getLoader()->getCacheKey($name)) . '.php'; - } + return $this->getCache() . '/' . preg_replace('#[^a-zA-Z0-9_/]#', '_', $name) . '.php'; + return $this->getCache() . '/' . preg_replace('#[^a-zA-Z0-9_/]#', '_', $name) . '_' . md5($this->getLoader()->getCacheKey($name)) . '.php'; + } /** * Get the list of enabled phpBB extensions @@ -112,7 +113,7 @@ class phpbb_template_twig_environment extends Twig_Environment * Set the namespace look up order to load templates from * * @param array $namespace - * @return Twig_Environment + * @return Twig_Environment */ public function setNamespaceLookUpOrder($namespace) { @@ -121,28 +122,28 @@ class phpbb_template_twig_environment extends Twig_Environment 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); + /** + * 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); + return parent::loadTemplate('@' . $namespace . '/' . $name, $index); } catch (Twig_Error_Loader $e) { @@ -154,9 +155,9 @@ class phpbb_template_twig_environment extends Twig_Environment } else { - return parent::loadTemplate($name, $index); + return parent::loadTemplate($name, $index); } - } + } /** * recursive helper to set variables into $context so that Twig can properly fetch them for display From 3dc40ad8443671081adc6f975a155f6f30cf3159 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 1 Jul 2013 21:22:50 -0500 Subject: [PATCH 089/156] [feature/twig] Use correct case for variable name PHPBB3-11598 --- phpBB/includes/template/twig/environment.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/phpBB/includes/template/twig/environment.php b/phpBB/includes/template/twig/environment.php index 34e6f09981..a71958998a 100644 --- a/phpBB/includes/template/twig/environment.php +++ b/phpBB/includes/template/twig/environment.php @@ -27,7 +27,7 @@ class phpbb_template_twig_environment extends Twig_Environment protected $phpbb_root_path; /** @var array **/ - protected $namespaceLookUpOrder = array('__main__'); + protected $namespace_look_up_order = array('__main__'); public function __construct($phpbb_config, $phpbb_extensions, $phpbb_root_path, Twig_LoaderInterface $loader = null, $options = array()) { @@ -106,7 +106,7 @@ class phpbb_template_twig_environment extends Twig_Environment */ public function getNamespaceLookUpOrder() { - return $this->namespaceLookUpOrder; + return $this->namespace_look_up_order; } /** @@ -117,7 +117,7 @@ class phpbb_template_twig_environment extends Twig_Environment */ public function setNamespaceLookUpOrder($namespace) { - $this->namespaceLookUpOrder = $namespace; + $this->namespace_look_up_order = $namespace; return $this; } From f90252395697aa4f1d0e606e4d92665b2293eb8d Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 1 Jul 2013 21:24:27 -0500 Subject: [PATCH 090/156] [feature/twig] Comments PHPBB3-11598 --- phpBB/includes/template/twig/environment.php | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/phpBB/includes/template/twig/environment.php b/phpBB/includes/template/twig/environment.php index a71958998a..f1ce6da38b 100644 --- a/phpBB/includes/template/twig/environment.php +++ b/phpBB/includes/template/twig/environment.php @@ -39,12 +39,11 @@ class phpbb_template_twig_environment extends Twig_Environment } /** - * Gets the cache filename for a given template. - * - * @param string $name The template name - * - * @return string The cache file name - */ + * Gets the cache filename for a given template. + * + * @param string $name The template name + * @return string The cache file name + */ public function ignoregetCacheFilename($name) { if (false === $this->cache) @@ -127,7 +126,6 @@ class phpbb_template_twig_environment extends Twig_Environment * * @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) @@ -160,11 +158,12 @@ class phpbb_template_twig_environment extends Twig_Environment } /** - * recursive helper to set variables into $context so that Twig can properly fetch them for display + * 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!) + * @return null */ public function context_recursive_loop_builder($data, $blocks, &$current_location) { From 3b9cb7faa7390ce244a69841de3618f4273cf3e0 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 1 Jul 2013 21:29:15 -0500 Subject: [PATCH 091/156] [feature/twig] Fix call for previous change to var name case PHPBB3-11598 --- phpBB/includes/template/twig/environment.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/template/twig/environment.php b/phpBB/includes/template/twig/environment.php index f1ce6da38b..73375444da 100644 --- a/phpBB/includes/template/twig/environment.php +++ b/phpBB/includes/template/twig/environment.php @@ -132,7 +132,7 @@ class phpbb_template_twig_environment extends Twig_Environment { if (strpos($name, '@') === false) { - foreach ($this->namespaceLookUpOrder as $namespace) + foreach ($this->getNamespaceLookUpOrder() as $namespace) { try { From f249a527e5b3b07063e2203928677f40d6ba8646 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 1 Jul 2013 21:32:10 -0500 Subject: [PATCH 092/156] [feature/twig] Should have been else PHPBB3-11598 --- phpBB/includes/functions_messenger.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php index 5f1251c34e..0222a57bcc 100644 --- a/phpBB/includes/functions_messenger.php +++ b/phpBB/includes/functions_messenger.php @@ -232,7 +232,7 @@ class messenger $template_path, ); } - if (!$template_path) + else { $template_path = (!empty($user->lang_path)) ? $user->lang_path : $phpbb_root_path . 'language/'; $template_path .= $template_lang . '/email'; From 883b0a9f8c3e102db8965069899dc2b97d1eb1ff Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 1 Jul 2013 21:44:00 -0500 Subject: [PATCH 093/156] [feature/twig] Update phpbb_template interface Return $this wherever possible PHPBB3-11598 --- phpBB/includes/template/template.php | 34 ++++++++++++++++--------- phpBB/includes/template/twig/twig.php | 36 +++++++++++++++++++-------- 2 files changed, 47 insertions(+), 23 deletions(-) diff --git a/phpBB/includes/template/template.php b/phpBB/includes/template/template.php index 15f0b6ee60..e506c2c278 100644 --- a/phpBB/includes/template/template.php +++ b/phpBB/includes/template/template.php @@ -17,24 +17,36 @@ if (!defined('IN_PHPBB')) interface phpbb_template { + + /** + * Clear the cache + * + * @return phpbb_template + */ + public function clear_cache(); + /** * 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); /** - * Sets the style names corresponding to style hierarchy being compiled + * Sets the style names/paths corresponding to style hierarchy being compiled * and/or rendered. * * @param array $style_names List of style names in inheritance tree order - * @return null + * @param array $style_paths List of style paths in inheritance tree order + * @return phpbb_template $this */ - public function set_style_names(array $style_names); + public function set_style_names(array $style_names, array $style_paths = array()); /** * Clears all variables and blocks assigned to this template. + * + * @return phpbb_template $this */ public function destroy(); @@ -42,6 +54,7 @@ interface phpbb_template * Reset/empty complete block * * @param string $blockname Name of block to destroy + * @return phpbb_template $this */ public function destroy_block_vars($blockname); @@ -53,7 +66,7 @@ interface phpbb_template * This function calls hooks. * * @param string $handle Handle to display - * @return bool True on success, false on failure + * @return phpbb_template $this */ public function display($handle); @@ -64,7 +77,7 @@ interface phpbb_template * @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 + * @return phpbb_template|string if $return_content is true return string of the compiled handle, otherwise return $this */ public function assign_display($handle, $template_var = '', $return_content = true); @@ -72,6 +85,7 @@ interface phpbb_template * Assign key variable pairs from an array * * @param array $vararray A hash of variable name => value pairs + * @return phpbb_template $this */ public function assign_vars(array $vararray); @@ -82,6 +96,7 @@ interface phpbb_template * * @param string $varname Variable name * @param string $varval Value to assign to variable + * @return phpbb_template $this */ public function assign_var($varname, $varval); @@ -92,6 +107,7 @@ interface phpbb_template * * @param string $varname Variable name * @param string $varval Value to append to variable + * @return phpbb_template $this */ public function append_var($varname, $varval); @@ -99,6 +115,7 @@ interface phpbb_template * 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 + * @return phpbb_template $this */ public function assign_block_vars($blockname, array $vararray); @@ -130,11 +147,4 @@ interface phpbb_template * @return bool false on error, true on success */ public function alter_block_array($blockname, array $vararray, $key = false, $mode = 'insert'); - - /** - * Clear the cache - * - * @return phpbb_template - */ - public function clear_cache(); } diff --git a/phpBB/includes/template/twig/twig.php b/phpBB/includes/template/twig/twig.php index 6b0771f77b..dbc36ecddf 100644 --- a/phpBB/includes/template/twig/twig.php +++ b/phpBB/includes/template/twig/twig.php @@ -172,10 +172,11 @@ class phpbb_template_twig implements phpbb_template } /** - * Sets the style names corresponding to style hierarchy being compiled + * Sets the style names/paths corresponding to style hierarchy being compiled * and/or rendered. * * @param array $style_names List of style names in inheritance tree order + * @param array $style_paths List of style paths in inheritance tree order * @return phpbb_template $this */ public function set_style_names(array $style_names, array $style_paths = array()) @@ -241,10 +242,13 @@ class phpbb_template_twig implements phpbb_template * Reset/empty complete block * * @param string $blockname Name of block to destroy + * @return phpbb_template $this */ public function destroy_block_vars($blockname) { - return $this->context->destroy_block_vars($blockname); + $this->context->destroy_block_vars($blockname); + + return $this; } /** @@ -255,7 +259,7 @@ class phpbb_template_twig implements phpbb_template * This function calls hooks. * * @param string $handle Handle to display - * @return bool True on success, false on failure + * @return phpbb_template $this */ public function display($handle) { @@ -267,7 +271,7 @@ class phpbb_template_twig implements phpbb_template $this->twig->display($this->get_filename_from_handle($handle), $this->get_template_vars()); - return true; + return $this; } /** @@ -299,7 +303,7 @@ class phpbb_template_twig implements phpbb_template * @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 + * @return phpbb_template|string if $return_content is true return string of the compiled handle, otherwise return $this */ public function assign_display($handle, $template_var = '', $return_content = true) { @@ -310,13 +314,14 @@ class phpbb_template_twig implements phpbb_template $this->assign_var($template_var, $this->twig->render($this->get_filename_from_handle($handle, $this->get_template_vars()))); - return true; + return $this; } /** * Assign key variable pairs from an array * * @param array $vararray A hash of variable name => value pairs + * @return phpbb_template $this */ public function assign_vars(array $vararray) { @@ -324,6 +329,8 @@ class phpbb_template_twig implements phpbb_template { $this->assign_var($key, $val); } + + return $this; } /** @@ -333,10 +340,13 @@ class phpbb_template_twig implements phpbb_template * * @param string $varname Variable name * @param string $varval Value to assign to variable + * @return phpbb_template $this */ public function assign_var($varname, $varval) { - return $this->context->assign_var($varname, $varval); + $this->context->assign_var($varname, $varval); + + return $this; } /** @@ -346,24 +356,28 @@ class phpbb_template_twig implements phpbb_template * * @param string $varname Variable name * @param string $varval Value to append to variable + * @return phpbb_template $this */ public function append_var($varname, $varval) { - return $this->context->append_var($varname, $varval); + $this->context->append_var($varname, $varval); + + return $this; } - // 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 + * @return phpbb_template $this */ public function assign_block_vars($blockname, array $vararray) { - return $this->context->assign_block_vars($blockname, $vararray); + $this->context->assign_block_vars($blockname, $vararray); + + return $this; } - // Docstring is copied from phpbb_template_context method with the same name. /** * Change already assigned key variable pair (one-dimensional - single loop entry) * From 156d5c671fb9db28fbbdcacb974093c2c52b0f5b Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Tue, 2 Jul 2013 10:13:16 -0500 Subject: [PATCH 094/156] [feature/twig] INCLUDEJS now uses the definition class This had to be done because, like DEFINE, setting variables to $context only affected the local file and any children, not parent templates. PHPBB3-11598 --- phpBB/includes/template/twig/definition.php | 19 +++++++++++++++++++ .../includes/template/twig/node/includejs.php | 4 ++-- .../prosilver/template/overall_footer.html | 2 +- .../subsilver2/template/overall_footer.html | 2 +- 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/phpBB/includes/template/twig/definition.php b/phpBB/includes/template/twig/definition.php index 110437eb32..6557b209eb 100644 --- a/phpBB/includes/template/twig/definition.php +++ b/phpBB/includes/template/twig/definition.php @@ -47,4 +47,23 @@ class phpbb_template_twig_definition return $this; } + + /** + * Append to a variable + * + * @param string $name + * @param string $value + * @return phpbb_template_twig_definition + */ + public function append($name, $value) + { + if (!isset($this->definitions[$name])) + { + $this->definitions[$name] = ''; + } + + $this->definitions[$name] .= $value; + + return $this; + } } diff --git a/phpBB/includes/template/twig/node/includejs.php b/phpBB/includes/template/twig/node/includejs.php index f4c26affa4..bba5d4ef91 100644 --- a/phpBB/includes/template/twig/node/includejs.php +++ b/phpBB/includes/template/twig/node/includejs.php @@ -31,9 +31,9 @@ class phpbb_template_twig_node_includejs extends Twig_Node $config = $this->environment->get_phpbb_config(); $compiler - ->write("\$context['SCRIPTS'] .= '';\n\n") + ->raw(" . '?assets_version=" . $config['assets_version'] . "\">');\n") ; } } diff --git a/phpBB/styles/prosilver/template/overall_footer.html b/phpBB/styles/prosilver/template/overall_footer.html index 5422cc7c10..dcb8058ee1 100644 --- a/phpBB/styles/prosilver/template/overall_footer.html +++ b/phpBB/styles/prosilver/template/overall_footer.html @@ -56,7 +56,7 @@ -{SCRIPTS} +{$SCRIPTS} diff --git a/phpBB/styles/subsilver2/template/overall_footer.html b/phpBB/styles/subsilver2/template/overall_footer.html index 3a29a0d752..2d794d9f71 100644 --- a/phpBB/styles/subsilver2/template/overall_footer.html +++ b/phpBB/styles/subsilver2/template/overall_footer.html @@ -14,7 +14,7 @@ -{SCRIPTS} +{$SCRIPTS} From 59d13d0535ab3687725d36f2dbe2ee64de294df8 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Tue, 2 Jul 2013 11:02:55 -0500 Subject: [PATCH 095/156] [feature/twig] INCLUDEJS behavior now supports local relative paths This was done because T_TEMPLATE_PATH is not always correct for js files (e.g. the inheriting style does not include these). Now we use the Twig Loader to find the correct file to link to (most specific file first, then parent styles). Also allows using @namespace convention PHPBB3-11598 --- phpBB/includes/template/twig/node/includejs.php | 12 ++++++++++-- .../styles/prosilver/template/memberlist_search.html | 2 +- phpBB/styles/prosilver/template/overall_footer.html | 6 +++--- phpBB/styles/prosilver/template/posting_buttons.html | 2 +- phpBB/styles/prosilver/template/timezone_option.html | 2 +- .../prosilver/template/ucp_avatar_options.html | 2 +- .../styles/subsilver2/template/timezone_option.html | 2 +- .../subsilver2/template/ucp_groups_manage.html | 2 +- .../subsilver2/template/ucp_profile_avatar.html | 2 +- 9 files changed, 20 insertions(+), 12 deletions(-) diff --git a/phpBB/includes/template/twig/node/includejs.php b/phpBB/includes/template/twig/node/includejs.php index bba5d4ef91..91b24e8068 100644 --- a/phpBB/includes/template/twig/node/includejs.php +++ b/phpBB/includes/template/twig/node/includejs.php @@ -31,9 +31,17 @@ class phpbb_template_twig_node_includejs extends Twig_Node $config = $this->environment->get_phpbb_config(); $compiler - ->write("\$context['definition']->append('SCRIPTS', '');\n") + ->raw(";\n") + ->write("if (!file_exists(\$js_file)) {\n") + ->indent() + ->write("\$js_file = \$this->getEnvironment()->getLoader()->getCacheKey(\$js_file);\n") + ->outdent() + ->write("}\n") + ->write("\$context['definition']->append('SCRIPTS', '\n');\n") ; } } diff --git a/phpBB/styles/prosilver/template/memberlist_search.html b/phpBB/styles/prosilver/template/memberlist_search.html index 6d2d87a278..4f029627fc 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) // ]]> - +

{L_FIND_USERNAME}

diff --git a/phpBB/styles/prosilver/template/overall_footer.html b/phpBB/styles/prosilver/template/overall_footer.html index dcb8058ee1..5c88209ad8 100644 --- a/phpBB/styles/prosilver/template/overall_footer.html +++ b/phpBB/styles/prosilver/template/overall_footer.html @@ -53,9 +53,9 @@ - - - + + + {$SCRIPTS} diff --git a/phpBB/styles/prosilver/template/posting_buttons.html b/phpBB/styles/prosilver/template/posting_buttons.html index 164e887f75..8a153a5ee8 100644 --- a/phpBB/styles/prosilver/template/posting_buttons.html +++ b/phpBB/styles/prosilver/template/posting_buttons.html @@ -52,7 +52,7 @@ // ]]> - + - + diff --git a/phpBB/styles/subsilver2/template/timezone_option.html b/phpBB/styles/subsilver2/template/timezone_option.html index 9b68f81557..0f27719f86 100644 --- a/phpBB/styles/subsilver2/template/timezone_option.html +++ b/phpBB/styles/subsilver2/template/timezone_option.html @@ -15,6 +15,6 @@ {S_TZ_OPTIONS} - + diff --git a/phpBB/styles/subsilver2/template/ucp_groups_manage.html b/phpBB/styles/subsilver2/template/ucp_groups_manage.html index 13b8b8c6b7..b8e7e29481 100644 --- a/phpBB/styles/subsilver2/template/ucp_groups_manage.html +++ b/phpBB/styles/subsilver2/template/ucp_groups_manage.html @@ -95,7 +95,7 @@ - + diff --git a/phpBB/styles/subsilver2/template/ucp_profile_avatar.html b/phpBB/styles/subsilver2/template/ucp_profile_avatar.html index 885d46ef0b..60a816d00a 100644 --- a/phpBB/styles/subsilver2/template/ucp_profile_avatar.html +++ b/phpBB/styles/subsilver2/template/ucp_profile_avatar.html @@ -48,6 +48,6 @@ - + From 02a8150bb615b6319bcdfd170e3febe34117f16c Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Tue, 2 Jul 2013 11:08:52 -0500 Subject: [PATCH 096/156] [feature/twig] INCLUDEPHP behavior now supports local relative paths As a last resort, now we use the Twig Loader to find the correct file to include to (most specific file first, then parent styles). Also allows using @namespace convention. This is ONLY done if the specified path is not an absolute path AND the file does not exist relative to the phpBB root path. PHPBB3-11598 --- phpBB/includes/template/twig/node/includephp.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/phpBB/includes/template/twig/node/includephp.php b/phpBB/includes/template/twig/node/includephp.php index 33142bf05a..a19ce43653 100644 --- a/phpBB/includes/template/twig/node/includephp.php +++ b/phpBB/includes/template/twig/node/includephp.php @@ -52,11 +52,18 @@ class phpbb_template_twig_node_includephp extends Twig_Node ->raw(";\n") ->write("if (phpbb_is_absolute(\$location)) {\n") ->indent() + // Absolute path specified ->write("require(\$location);\n") ->outdent() + ->write("} else if (file_exists(\$this->getEnvironment()->get_phpbb_root_path() . \$location)) {\n") + ->indent() + // PHP file relative to phpbb_root_path + ->write("require(\$this->getEnvironment()->get_phpbb_root_path() . \$location);\n") + ->outdent() ->write("} else {\n") ->indent() - ->write("require(\$this->getEnvironment()->get_phpbb_root_path() . \$location);\n") + // Local path (behaves like INCLUDE) + ->write("require(\$this->getEnvironment()->getLoader()->getCacheKey(\$location));\n") ->outdent() ->write("}\n") ; From 9dce2b28af639d74a0e7eb15b7e1d4c29a5396a3 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Tue, 2 Jul 2013 11:21:05 -0500 Subject: [PATCH 097/156] [feature/twig] Fix template test case PHPBB3-11598 --- tests/template/template_test_case.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/template/template_test_case.php b/tests/template/template_test_case.php index 63f0c873b0..3e2cd5a387 100644 --- a/tests/template/template_test_case.php +++ b/tests/template/template_test_case.php @@ -29,7 +29,7 @@ class phpbb_template_template_test_case extends phpbb_test_case try { - $this->assertTrue($this->template->display($handle, false)); + $this->template->display($handle, false); } catch (Exception $exception) { From c6c064a1360cf6ef488adbe516cea5c4d7138f0c Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Tue, 2 Jul 2013 11:21:31 -0500 Subject: [PATCH 098/156] [feature/twig] Fix includejs test PHPBB3-11598 --- tests/template/template_includejs_test.php | 12 ++++++------ tests/template/templates/includejs.html | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/template/template_includejs_test.php b/tests/template/template_includejs_test.php index c0169bd385..67381b1fd4 100644 --- a/tests/template/template_includejs_test.php +++ b/tests/template/template_includejs_test.php @@ -18,12 +18,12 @@ class phpbb_template_template_includejs_test extends phpbb_template_template_tes // Prepare correct result $scripts = array( - '', - '', - '', - '', - '', - '', + '', + '', + '', + '', + '', + '', ); // Run test diff --git a/tests/template/templates/includejs.html b/tests/template/templates/includejs.html index ef73700eeb..229f1ccc19 100644 --- a/tests/template/templates/includejs.html +++ b/tests/template/templates/includejs.html @@ -5,4 +5,4 @@ -{SCRIPTS} +{$SCRIPTS} From 709b3e98034e537fb3cbe5cbcb1511002c2d372d Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Tue, 2 Jul 2013 11:29:32 -0500 Subject: [PATCH 099/156] [feature/twig] Fix BBCode parser PHPBB3-11598 --- phpBB/includes/bbcode.php | 2 +- phpBB/includes/template/template.php | 7 +++++++ phpBB/includes/template/twig/twig.php | 10 ++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/phpBB/includes/bbcode.php b/phpBB/includes/bbcode.php index ecbb056045..fd00728510 100644 --- a/phpBB/includes/bbcode.php +++ b/phpBB/includes/bbcode.php @@ -138,7 +138,7 @@ class bbcode $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')); - $this->template_filename = $style_resource_locator->get_source_file_for_handle('bbcode.html'); + $this->template_filename = $template->get_source_file_for_handle('bbcode.html'); } $bbcode_ids = $rowset = $sql = array(); diff --git a/phpBB/includes/template/template.php b/phpBB/includes/template/template.php index e506c2c278..2b7c36ea7d 100644 --- a/phpBB/includes/template/template.php +++ b/phpBB/includes/template/template.php @@ -147,4 +147,11 @@ interface phpbb_template * @return bool false on error, true on success */ public function alter_block_array($blockname, array $vararray, $key = false, $mode = 'insert'); + + /** + * Get path to template for handle (required for BBCode parser) + * + * @return string + */ + public function get_source_file_for_handle($handle); } diff --git a/phpBB/includes/template/twig/twig.php b/phpBB/includes/template/twig/twig.php index dbc36ecddf..9d69136e0c 100644 --- a/phpBB/includes/template/twig/twig.php +++ b/phpBB/includes/template/twig/twig.php @@ -444,4 +444,14 @@ class phpbb_template_twig implements phpbb_template { return (isset($this->filenames[$handle])) ? $this->filenames[$handle] : $handle; } + + /** + * Get path to template for handle (required for BBCode parser) + * + * @return string + */ + public function get_source_file_for_handle($handle) + { + return $this->twig->getLoader()->getCacheKey($this->get_filename_from_handle($handle)); + } } From f39edcea3fb12c4f3ce9606772887c93d629f2d4 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Tue, 2 Jul 2013 12:17:56 -0500 Subject: [PATCH 100/156] [feature/twig] Check the template context for language vars We output some language vars to the context (e.g. L_TITLE in the ACP). These do not exist in user->lang, so we must check the context vars first, if not in context, we output the result of user->lang. PHPBB3-11598 --- phpBB/includes/template/twig/extension.php | 37 ++++++++++++++++++++-- phpBB/includes/template/twig/twig.php | 1 + 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/template/twig/extension.php b/phpBB/includes/template/twig/extension.php index 1ea5f7b662..a54c2b2509 100644 --- a/phpBB/includes/template/twig/extension.php +++ b/phpBB/includes/template/twig/extension.php @@ -17,11 +17,15 @@ if (!defined('IN_PHPBB')) class phpbb_template_twig_extension extends Twig_Extension { + /** @var phpbb_template_context */ + protected $context; + /** @var phpbb_user */ protected $user; - public function __construct($user) + public function __construct(phpbb_template_context $context, $user) { + $this->context = $context; $this->user = $user; } @@ -69,7 +73,7 @@ class phpbb_template_twig_extension extends Twig_Extension public function getFunctions() { return array( - new Twig_SimpleFunction('lang', array($this->user, 'lang')), + new Twig_SimpleFunction('lang', array($this, 'lang')), ); } @@ -140,4 +144,33 @@ class phpbb_template_twig_extension extends Twig_Extension return twig_slice($env, $item, $start, $end, $preserveKeys); } + + /** + * Get output for a language variable (L_FOO, LA_FOO) + * + * This function checks to see if the language var was outputted to $context + * (e.g. in the ACP, L_TITLE) + * If not, we return the result of $user->lang() + * + * @param string $lang name + * @return string + */ + function lang() + { + $args = func_get_args(); + $key = $args[0]; + + $context = $this->context->get_data_ref(); + $context_vars = $context['.'][0]; + + if (isset($context_vars['L_' . $key])) + { + return $context_vars['L_' . $key]; + } + + // LA_ is transformed into lang(\'$1\')|addslashes, so we should not + // need to check for it + + return call_user_func_array(array($this->user, 'lang'), $args); + } } diff --git a/phpBB/includes/template/twig/twig.php b/phpBB/includes/template/twig/twig.php index 9d69136e0c..347db0b94c 100644 --- a/phpBB/includes/template/twig/twig.php +++ b/phpBB/includes/template/twig/twig.php @@ -134,6 +134,7 @@ class phpbb_template_twig implements phpbb_template $this->twig->addExtension( new phpbb_template_twig_extension( + $this->context, $this->user ) ); From 985a233a78af7350387dfb9b8a924d09df767f05 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Tue, 2 Jul 2013 12:22:42 -0500 Subject: [PATCH 101/156] [feature/twig] Remove reference to cachepath, it is not used publicly anymore PHPBB3-11598 --- phpBB/includes/style/style.php | 2 -- phpBB/includes/template/twig/twig.php | 5 ++++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/phpBB/includes/style/style.php b/phpBB/includes/style/style.php index 493c4512a6..29cdcf0f7f 100644 --- a/phpBB/includes/style/style.php +++ b/phpBB/includes/style/style.php @@ -160,8 +160,6 @@ class phpbb_style $this->template->set_style_names($names, $appended_paths); } - //$this->template->cachepath = $this->phpbb_root_path . 'cache/tpl_' . str_replace('_', '-', $name) . '_'; - return true; } diff --git a/phpBB/includes/template/twig/twig.php b/phpBB/includes/template/twig/twig.php index 347db0b94c..98bd1ab89c 100644 --- a/phpBB/includes/template/twig/twig.php +++ b/phpBB/includes/template/twig/twig.php @@ -30,9 +30,12 @@ class phpbb_template_twig implements phpbb_template /** * Path of the cache directory for the template + * + * Cannot be changed during runtime. + * * @var string */ - public $cachepath = ''; + private $cachepath = ''; /** * phpBB root path From f102f609f5f0e424374aab55b8141c4e4a48b0fc Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Tue, 2 Jul 2013 12:23:42 -0500 Subject: [PATCH 102/156] [feature/twig] Remove getCacheFilename function I was working on This can be addressed later if we decide we want to have more nicely named cache files. It does not need to be addressed now PHPBB3-11598 --- phpBB/includes/template/twig/environment.php | 30 -------------------- 1 file changed, 30 deletions(-) diff --git a/phpBB/includes/template/twig/environment.php b/phpBB/includes/template/twig/environment.php index 73375444da..190d43f513 100644 --- a/phpBB/includes/template/twig/environment.php +++ b/phpBB/includes/template/twig/environment.php @@ -38,36 +38,6 @@ class phpbb_template_twig_environment extends Twig_Environment return parent::__construct($loader, $options); } - /** - * Gets the cache filename for a given template. - * - * @param string $name The template name - * @return string The cache file name - */ - public function ignoregetCacheFilename($name) - { - if (false === $this->cache) - { - return false; - } - // @todo - $file_path = $this->getLoader()->getCacheKey($name); - foreach ($this->getLoader()->getNamespaces() as $namespace) - { - foreach ($this->getLoader()->getPaths($namespace) as $path) - { - if (strpos($file_path, $path) === 0) - { - //return $this->getCache() . '/' . preg_replace('#[^a-zA-Z0-9_/]#', '_', $namespace . '/' . $name) . '.php'; - } - } - } - - // We probably should never get here under normal circumstances - return $this->getCache() . '/' . preg_replace('#[^a-zA-Z0-9_/]#', '_', $name) . '.php'; - return $this->getCache() . '/' . preg_replace('#[^a-zA-Z0-9_/]#', '_', $name) . '_' . md5($this->getLoader()->getCacheKey($name)) . '.php'; - } - /** * Get the list of enabled phpBB extensions * From 57c2d99e65ce107208db10721cff5b815ee3403c Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Tue, 2 Jul 2013 12:34:16 -0500 Subject: [PATCH 103/156] [feature/twig] Fix indentation PHPBB3-11598 --- phpBB/includes/template/twig/environment.php | 11 ++ phpBB/includes/template/twig/node/define.php | 26 ++-- phpBB/includes/template/twig/node/event.php | 54 ++++----- .../node/expression/binary/equalequal.php | 8 +- .../node/expression/binary/notequalequal.php | 8 +- phpBB/includes/template/twig/node/include.php | 28 ++--- .../includes/template/twig/node/includejs.php | 36 +++--- .../template/twig/node/includephp.php | 60 ++++----- phpBB/includes/template/twig/node/php.php | 28 ++--- .../template/twig/tokenparser/define.php | 76 ++++++------ .../template/twig/tokenparser/event.php | 46 +++---- .../includes/template/twig/tokenparser/if.php | 114 +++++++++--------- .../template/twig/tokenparser/include.php | 44 +++---- .../template/twig/tokenparser/includejs.php | 46 +++---- .../template/twig/tokenparser/includephp.php | 58 ++++----- .../template/twig/tokenparser/php.php | 52 ++++---- 16 files changed, 353 insertions(+), 342 deletions(-) diff --git a/phpBB/includes/template/twig/environment.php b/phpBB/includes/template/twig/environment.php index 190d43f513..acb97cfad2 100644 --- a/phpBB/includes/template/twig/environment.php +++ b/phpBB/includes/template/twig/environment.php @@ -29,6 +29,15 @@ class phpbb_template_twig_environment extends Twig_Environment /** @var array **/ protected $namespace_look_up_order = array('__main__'); + /** + * Constructor + * + * @param phpbb_config $phpbb_config + * @param array $phpbb_extensions Array of enabled extensions (name => path) + * @param string $phpbb_root_path + * @param Twig_LoaderInterface $loader + * @param array $options Array of options to pass to Twig + */ public function __construct($phpbb_config, $phpbb_extensions, $phpbb_root_path, Twig_LoaderInterface $loader = null, $options = array()) { $this->phpbb_config = $phpbb_config; @@ -41,6 +50,8 @@ class phpbb_template_twig_environment extends Twig_Environment /** * Get the list of enabled phpBB extensions * + * Used in EVENT node + * * @return array */ public function get_phpbb_extensions() diff --git a/phpBB/includes/template/twig/node/define.php b/phpBB/includes/template/twig/node/define.php index 0c4d400767..499bbdc518 100644 --- a/phpBB/includes/template/twig/node/define.php +++ b/phpBB/includes/template/twig/node/define.php @@ -9,19 +9,19 @@ class phpbb_template_twig_node_define extends Twig_Node { - public function __construct($capture, Twig_NodeInterface $name, Twig_NodeInterface $value, $lineno, $tag = null) - { - parent::__construct(array('name' => $name, 'value' => $value), array('capture' => $capture, 'safe' => false), $lineno, $tag); - } + public function __construct($capture, Twig_NodeInterface $name, Twig_NodeInterface $value, $lineno, $tag = null) + { + parent::__construct(array('name' => $name, 'value' => $value), array('capture' => $capture, 'safe' => false), $lineno, $tag); + } - /** - * Compiles the node to PHP. - * - * @param Twig_Compiler A Twig_Compiler instance - */ - public function compile(Twig_Compiler $compiler) - { - $compiler->addDebugInfo($this); + /** + * Compiles the node to PHP. + * + * @param Twig_Compiler A Twig_Compiler instance + */ + public function compile(Twig_Compiler $compiler) + { + $compiler->addDebugInfo($this); if ($this->getAttribute('capture')) { $compiler @@ -45,5 +45,5 @@ class phpbb_template_twig_node_define extends Twig_Node ->raw($this->getNode('name')->getAttribute('name')) ->raw("', \$value);\n") ; - } + } } diff --git a/phpBB/includes/template/twig/node/event.php b/phpBB/includes/template/twig/node/event.php index 358c68dae5..6de270e19c 100644 --- a/phpBB/includes/template/twig/node/event.php +++ b/phpBB/includes/template/twig/node/event.php @@ -12,39 +12,39 @@ class phpbb_template_twig_node_event extends Twig_Node /** @var Twig_Environment */ protected $environment; - public function __construct(Twig_Node_Expression $expr, phpbb_template_twig_environment $environment, $lineno, $tag = null) - { - $this->environment = $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); - } + 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); + /** + * 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'); + $location = $this->getNode('expr')->getAttribute('name'); - foreach ($this->environment->get_phpbb_extensions() as $ext_namespace => $ext_path) - { - $ext_namespace = str_replace('/', '_', $ext_namespace); + 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") + 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") - ; + // 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 index 3a0c79c839..054f63ecf9 100644 --- a/phpBB/includes/template/twig/node/expression/binary/equalequal.php +++ b/phpBB/includes/template/twig/node/expression/binary/equalequal.php @@ -9,8 +9,8 @@ class phpbb_template_twig_node_expression_binary_equalequal extends Twig_Node_Expression_Binary { - public function operator(Twig_Compiler $compiler) - { - return $compiler->raw('==='); - } + 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 index b53bc56b2d..d8a1c411cf 100644 --- a/phpBB/includes/template/twig/node/expression/binary/notequalequal.php +++ b/phpBB/includes/template/twig/node/expression/binary/notequalequal.php @@ -9,8 +9,8 @@ class phpbb_template_twig_node_expression_binary_notequalequal extends Twig_Node_Expression_Binary { - public function operator(Twig_Compiler $compiler) - { - return $compiler->raw('!=='); - } + 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 index 2a90dc19e4..a614cbe20f 100644 --- a/phpBB/includes/template/twig/node/include.php +++ b/phpBB/includes/template/twig/node/include.php @@ -9,14 +9,14 @@ 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); + /** + * Compiles the node to PHP. + * + * @param Twig_Compiler A Twig_Compiler instance + */ + public function compile(Twig_Compiler $compiler) + { + $compiler->addDebugInfo($this); $compiler ->write("\$location = ") @@ -26,15 +26,15 @@ class phpbb_template_twig_node_include extends Twig_Node_Include ->write("if (strpos(\$location, '@') === 0) {\n") ->indent() ->write("\$namespace = substr(\$location, 1, strpos(\$location, '/') - 1);\n") - ->write("\$previous_look_up_order = \$this->env->getNamespaceLookUpOrder();\n") + ->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") + // We set the namespace lookup order to be this namespace first, then the main path + ->write("\$this->env->setNamespaceLookUpOrder(array(\$namespace, '__main__'));\n") ->outdent() ->write("}\n") ; - parent::compile($compiler); + parent::compile($compiler); $compiler ->write("if (\$namespace) {\n") @@ -42,6 +42,6 @@ class phpbb_template_twig_node_include extends Twig_Node_Include ->write("\$this->env->setNamespaceLookUpOrder(\$previous_look_up_order);\n") ->outdent() ->write("}\n") - ; - } + ; + } } diff --git a/phpBB/includes/template/twig/node/includejs.php b/phpBB/includes/template/twig/node/includejs.php index 91b24e8068..6d0d67c6c9 100644 --- a/phpBB/includes/template/twig/node/includejs.php +++ b/phpBB/includes/template/twig/node/includejs.php @@ -12,27 +12,27 @@ class phpbb_template_twig_node_includejs extends Twig_Node /** @var Twig_Environment */ protected $environment; - public function __construct(Twig_Node_Expression $expr, phpbb_template_twig_environment $environment, $lineno, $tag = null) - { - $this->environment = $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); - } + 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); + /** + * Compiles the node to PHP. + * + * @param Twig_Compiler A Twig_Compiler instance + */ + public function compile(Twig_Compiler $compiler) + { + $compiler->addDebugInfo($this); $config = $this->environment->get_phpbb_config(); - $compiler + $compiler ->write("\$js_file = ") - ->subcompile($this->getNode('expr')) + ->subcompile($this->getNode('expr')) ->raw(";\n") ->write("if (!file_exists(\$js_file)) {\n") ->indent() @@ -41,7 +41,7 @@ class phpbb_template_twig_node_includejs extends Twig_Node ->write("}\n") ->write("\$context['definition']->append('SCRIPTS', '\n');\n") - ; - } + ->raw(" . '?assets_version=" . $config['assets_version'] . "\">\n');\n") + ; + } } diff --git a/phpBB/includes/template/twig/node/includephp.php b/phpBB/includes/template/twig/node/includephp.php index a19ce43653..b5bb2ee9c9 100644 --- a/phpBB/includes/template/twig/node/includephp.php +++ b/phpBB/includes/template/twig/node/includephp.php @@ -12,21 +12,21 @@ class phpbb_template_twig_node_includephp extends Twig_Node /** @var Twig_Environment */ protected $environment; - public function __construct(Twig_Node_Expression $expr, phpbb_template_twig_environment $environment, $ignoreMissing = false, $lineno, $tag = null) - { - $this->environment = $environment; + public function __construct(Twig_Node_Expression $expr, phpbb_template_twig_environment $environment, $ignoreMissing = false, $lineno, $tag = null) + { + $this->environment = $environment; - parent::__construct(array('expr' => $expr), array('ignore_missing' => (Boolean) $ignoreMissing), $lineno, $tag); - } + parent::__construct(array('expr' => $expr), array('ignore_missing' => (Boolean) $ignoreMissing), $lineno, $tag); + } - /** - * Compiles the node to PHP. - * - * @param Twig_Compiler A Twig_Compiler instance - */ - public function compile(Twig_Compiler $compiler) - { - $compiler->addDebugInfo($this); + /** + * Compiles the node to PHP. + * + * @param Twig_Compiler A Twig_Compiler instance + */ + public function compile(Twig_Compiler $compiler) + { + $compiler->addDebugInfo($this); $config = $this->environment->get_phpbb_config(); @@ -39,12 +39,12 @@ class phpbb_template_twig_node_includephp extends Twig_Node return; } - if ($this->getAttribute('ignore_missing')) { - $compiler - ->write("try {\n") - ->indent() - ; - } + if ($this->getAttribute('ignore_missing')) { + $compiler + ->write("try {\n") + ->indent() + ; + } $compiler ->write("\$location = ") @@ -68,15 +68,15 @@ class phpbb_template_twig_node_includephp extends Twig_Node ->write("}\n") ; - if ($this->getAttribute('ignore_missing')) { - $compiler - ->outdent() - ->write("} catch (Twig_Error_Loader \$e) {\n") - ->indent() - ->write("// ignore missing template\n") - ->outdent() - ->write("}\n\n") - ; - } - } + if ($this->getAttribute('ignore_missing')) { + $compiler + ->outdent() + ->write("} catch (Twig_Error_Loader \$e) {\n") + ->indent() + ->write("// ignore missing template\n") + ->outdent() + ->write("}\n\n") + ; + } + } } diff --git a/phpBB/includes/template/twig/node/php.php b/phpBB/includes/template/twig/node/php.php index 953cd184a7..ebf4947e48 100644 --- a/phpBB/includes/template/twig/node/php.php +++ b/phpBB/includes/template/twig/node/php.php @@ -12,21 +12,21 @@ class phpbb_template_twig_node_php extends Twig_Node /** @var Twig_Environment */ protected $environment; - public function __construct(Twig_Node_Text $text, phpbb_template_twig_environment $environment, $lineno, $tag = null) - { - $this->environment = $environment; + public function __construct(Twig_Node_Text $text, phpbb_template_twig_environment $environment, $lineno, $tag = null) + { + $this->environment = $environment; - parent::__construct(array('text' => $text), array(), $lineno, $tag); - } + parent::__construct(array('text' => $text), array(), $lineno, $tag); + } - /** - * Compiles the node to PHP. - * - * @param Twig_Compiler A Twig_Compiler instance - */ - public function compile(Twig_Compiler $compiler) - { - $compiler->addDebugInfo($this); + /** + * Compiles the node to PHP. + * + * @param Twig_Compiler A Twig_Compiler instance + */ + public function compile(Twig_Compiler $compiler) + { + $compiler->addDebugInfo($this); $config = $this->environment->get_phpbb_config(); @@ -42,5 +42,5 @@ class phpbb_template_twig_node_php extends Twig_Node $compiler ->raw($this->getNode('text')->getAttribute('data')) ; - } + } } diff --git a/phpBB/includes/template/twig/tokenparser/define.php b/phpBB/includes/template/twig/tokenparser/define.php index ebf7cb4c4a..ed77699b77 100644 --- a/phpBB/includes/template/twig/tokenparser/define.php +++ b/phpBB/includes/template/twig/tokenparser/define.php @@ -9,49 +9,49 @@ class phpbb_template_twig_tokenparser_define 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) - { - $lineno = $token->getLine(); - $stream = $this->parser->getStream(); - $name = $this->parser->getExpressionParser()->parseExpression(); + /** + * 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(); + $stream = $this->parser->getStream(); + $name = $this->parser->getExpressionParser()->parseExpression(); - $capture = false; - if ($stream->test(Twig_Token::OPERATOR_TYPE, '=')) { - $stream->next(); - $value = $this->parser->getExpressionParser()->parseExpression(); + $capture = false; + if ($stream->test(Twig_Token::OPERATOR_TYPE, '=')) { + $stream->next(); + $value = $this->parser->getExpressionParser()->parseExpression(); - $stream->expect(Twig_Token::BLOCK_END_TYPE); - } else { - $capture = true; + $stream->expect(Twig_Token::BLOCK_END_TYPE); + } else { + $capture = true; - $stream->expect(Twig_Token::BLOCK_END_TYPE); + $stream->expect(Twig_Token::BLOCK_END_TYPE); - $value = $this->parser->subparse(array($this, 'decideBlockEnd'), true); - $stream->expect(Twig_Token::BLOCK_END_TYPE); - } + $value = $this->parser->subparse(array($this, 'decideBlockEnd'), true); + $stream->expect(Twig_Token::BLOCK_END_TYPE); + } - return new phpbb_template_twig_node_define($capture, $name, $value, $lineno, $this->getTag()); - } + return new phpbb_template_twig_node_define($capture, $name, $value, $lineno, $this->getTag()); + } - public function decideBlockEnd(Twig_Token $token) - { - return $token->test('ENDDEFINE'); - } + 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'; - } + /** + * 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 index 03810454ed..2a6d6b6457 100644 --- a/phpBB/includes/template/twig/tokenparser/event.php +++ b/phpBB/includes/template/twig/tokenparser/event.php @@ -9,30 +9,30 @@ 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(); + /** + * 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); + $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()); - } + 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'; - } + /** + * 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 index 04ee048f94..939d679030 100644 --- a/phpBB/includes/template/twig/tokenparser/if.php +++ b/phpBB/includes/template/twig/tokenparser/if.php @@ -9,70 +9,70 @@ 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; + /** + * 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; + $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 '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; + 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()); - } - } + 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); + $stream->expect(Twig_Token::BLOCK_END_TYPE); - return new Twig_Node_If(new Twig_Node($tests), $else, $lineno, $this->getTag()); - } + 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 decideIfFork(Twig_Token $token) + { + return $token->test(array('ELSEIF', 'ELSE', 'ENDIF')); + } - public function decideIfEnd(Twig_Token $token) - { - return $token->test(array('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'; - } + /** + * 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 index 0f7e4faf8f..5b5105d23e 100644 --- a/phpBB/includes/template/twig/tokenparser/include.php +++ b/phpBB/includes/template/twig/tokenparser/include.php @@ -9,29 +9,29 @@ 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(); + /** + * 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(); + list($variables, $only, $ignoreMissing) = $this->parseArguments(); - return new phpbb_template_twig_node_include($expr, $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag()); - } + 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'; - } + /** + * 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 index 0b46f315d2..962d01ac45 100644 --- a/phpBB/includes/template/twig/tokenparser/includejs.php +++ b/phpBB/includes/template/twig/tokenparser/includejs.php @@ -9,30 +9,30 @@ 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(); + /** + * 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); + $stream = $this->parser->getStream(); + $stream->expect(Twig_Token::BLOCK_END_TYPE); - return new phpbb_template_twig_node_includejs($expr, $this->parser->getEnvironment(), $token->getLine(), $this->getTag()); - } + return new phpbb_template_twig_node_includejs($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 'INCLUDEJS'; - } + /** + * 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/tokenparser/includephp.php b/phpBB/includes/template/twig/tokenparser/includephp.php index a81d663c09..57d804183b 100644 --- a/phpBB/includes/template/twig/tokenparser/includephp.php +++ b/phpBB/includes/template/twig/tokenparser/includephp.php @@ -9,39 +9,39 @@ class phpbb_template_twig_tokenparser_includephp 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(); + /** + * 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 = $this->parser->getStream(); - $ignoreMissing = false; - if ($stream->test(Twig_Token::NAME_TYPE, 'ignore')) { - $stream->next(); - $stream->expect(Twig_Token::NAME_TYPE, 'missing'); + $ignoreMissing = false; + if ($stream->test(Twig_Token::NAME_TYPE, 'ignore')) { + $stream->next(); + $stream->expect(Twig_Token::NAME_TYPE, 'missing'); - $ignoreMissing = true; - } + $ignoreMissing = true; + } - $stream->expect(Twig_Token::BLOCK_END_TYPE); + $stream->expect(Twig_Token::BLOCK_END_TYPE); - return new phpbb_template_twig_node_includephp($expr, $this->parser->getEnvironment(), $ignoreMissing, $token->getLine(), $this->getTag()); - } + return new phpbb_template_twig_node_includephp($expr, $this->parser->getEnvironment(), $ignoreMissing, $token->getLine(), $this->getTag()); + } - /** - * Gets the tag name associated with this token parser. - * - * @return string The tag name - */ - public function getTag() - { - return 'INCLUDEPHP'; - } + /** + * Gets the tag name associated with this token parser. + * + * @return string The tag name + */ + public function getTag() + { + return 'INCLUDEPHP'; + } } diff --git a/phpBB/includes/template/twig/tokenparser/php.php b/phpBB/includes/template/twig/tokenparser/php.php index 7db57081e2..62e1c4fdcd 100644 --- a/phpBB/includes/template/twig/tokenparser/php.php +++ b/phpBB/includes/template/twig/tokenparser/php.php @@ -9,38 +9,38 @@ class phpbb_template_twig_tokenparser_php 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) - { - $stream = $this->parser->getStream(); + /** + * 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) + { + $stream = $this->parser->getStream(); - $stream->expect(Twig_Token::BLOCK_END_TYPE); + $stream->expect(Twig_Token::BLOCK_END_TYPE); $body = $this->parser->subparse(array($this, 'decideEnd'), true); - $stream->expect(Twig_Token::BLOCK_END_TYPE); + $stream->expect(Twig_Token::BLOCK_END_TYPE); - return new phpbb_template_twig_node_php($body, $this->parser->getEnvironment(), $token->getLine(), $this->getTag()); - } + return new phpbb_template_twig_node_php($body, $this->parser->getEnvironment(), $token->getLine(), $this->getTag()); + } - public function decideEnd(Twig_Token $token) - { - return $token->test('ENDPHP'); - } + public function decideEnd(Twig_Token $token) + { + return $token->test('ENDPHP'); + } - /** - * Gets the tag name associated with this token parser. - * - * @return string The tag name - */ - public function getTag() - { - return 'PHP'; + /** + * Gets the tag name associated with this token parser. + * + * @return string The tag name + */ + public function getTag() + { + return 'PHP'; } } From b4947f94ed23270d4dbb498afb31555da2c8af0d Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Tue, 2 Jul 2013 12:43:26 -0500 Subject: [PATCH 104/156] [feature/twig] Should compare to $this->test_path rather than hardcoded path PHPBB3-11598 --- tests/template/template_includejs_test.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/template/template_includejs_test.php b/tests/template/template_includejs_test.php index 67381b1fd4..a57b219150 100644 --- a/tests/template/template_includejs_test.php +++ b/tests/template/template_includejs_test.php @@ -18,12 +18,12 @@ class phpbb_template_template_includejs_test extends phpbb_template_template_tes // Prepare correct result $scripts = array( - '', - '', - '', - '', - '', - '', + '', + '', + '', + '', + '', + '', ); // Run test From 6bbe92a8d020f1fcfa8de0da50714acf88837295 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Tue, 2 Jul 2013 12:50:55 -0500 Subject: [PATCH 105/156] [feature/twig] Move test_php back to template_test Was originally moved because I thought that a new test file might mean a new instance and the memory would be cleared, fixing the original problem, but that isn't true and it was fixed another way. PHPBB3-11598 --- tests/template/template_php_test.php | 30 ---------------------------- tests/template/template_test.php | 16 +++++++++++++++ 2 files changed, 16 insertions(+), 30 deletions(-) delete mode 100644 tests/template/template_php_test.php diff --git a/tests/template/template_php_test.php b/tests/template/template_php_test.php deleted file mode 100644 index fd4174953c..0000000000 --- a/tests/template/template_php_test.php +++ /dev/null @@ -1,30 +0,0 @@ -echo "test";'; - - $cache_dir = dirname($this->template->cachepath) . '/'; - $fp = fopen($cache_dir . 'php.html', 'w'); - fputs($fp, $template_text); - fclose($fp); - - $this->setup_engine(array('tpl_allow_php' => true)); - - $this->style->set_custom_style('tests', $cache_dir, array(), ''); - - $this->run_template('php.html', array(), array(), array(), 'test'); - } -} diff --git a/tests/template/template_test.php b/tests/template/template_test.php index ad4c8fbd17..26cfb3a8e4 100644 --- a/tests/template/template_test.php +++ b/tests/template/template_test.php @@ -369,6 +369,22 @@ class phpbb_template_template_test extends phpbb_template_template_test_case $this->assertEquals($expecting, $this->display('append_var')); } + public function test_php() + { + $template_text = 'echo "test";'; + + $cache_dir = dirname($this->template->cachepath) . '/'; + $fp = fopen($cache_dir . 'php.html', 'w'); + fputs($fp, $template_text); + fclose($fp); + + $this->setup_engine(array('tpl_allow_php' => true)); + + $this->style->set_custom_style('tests', $cache_dir, array(), ''); + + $this->run_template('php.html', array(), array(), array(), 'test'); + } + public function alter_block_array_data() { return array( From 2507c648fe92de5363bd443839d1bb52f55795b4 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Tue, 2 Jul 2013 12:59:23 -0500 Subject: [PATCH 106/156] [feature/twig] template->cachepath is now private, missed checking tests PHPBB3-11598 --- tests/template/includephp_test.php | 4 +++- tests/template/template_test.php | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/template/includephp_test.php b/tests/template/includephp_test.php index edf1e40bb8..a3dc9bd5c5 100644 --- a/tests/template/includephp_test.php +++ b/tests/template/includephp_test.php @@ -33,11 +33,13 @@ class phpbb_template_includephp_test extends phpbb_template_template_test_case public function test_includephp_absolute() { + global $phpbb_root_path; + $path_to_php = str_replace('\\', '/', dirname(__FILE__)) . '/templates/_dummy_include.php.inc'; $this->assertTrue(phpbb_is_absolute($path_to_php)); $template_text = "Path is absolute.\n"; - $cache_dir = dirname($this->template->cachepath) . '/'; + $cache_dir = dirname($phpbb_root_path . 'cache') . '/'; $fp = fopen($cache_dir . 'includephp_absolute.html', 'w'); fputs($fp, $template_text); fclose($fp); diff --git a/tests/template/template_test.php b/tests/template/template_test.php index 26cfb3a8e4..1b3dda9b2a 100644 --- a/tests/template/template_test.php +++ b/tests/template/template_test.php @@ -371,9 +371,11 @@ class phpbb_template_template_test extends phpbb_template_template_test_case public function test_php() { + global $phpbb_root_path; + $template_text = 'echo "test";'; - $cache_dir = dirname($this->template->cachepath) . '/'; + $cache_dir = dirname($phpbb_root_path . 'cache') . '/'; $fp = fopen($cache_dir . 'php.html', 'w'); fputs($fp, $template_text); fclose($fp); From 52bce2ce11013477f763d0e9fe4f6f724a970f29 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Tue, 2 Jul 2013 13:43:02 -0500 Subject: [PATCH 107/156] [feature/twig] Prevent errors from mkdir if the dir already exists PHPBB3-11598 --- tests/test_framework/phpbb_test_case_helpers.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/test_framework/phpbb_test_case_helpers.php b/tests/test_framework/phpbb_test_case_helpers.php index 50b2bf03ec..c4907d5ecf 100644 --- a/tests/test_framework/phpbb_test_case_helpers.php +++ b/tests/test_framework/phpbb_test_case_helpers.php @@ -94,7 +94,10 @@ class phpbb_test_case_helpers public function makedirs($path) { - mkdir($path, 0777, true); + if (!is_dir($path)) + { + mkdir($path, 0777, true); + } } static public function get_test_config() From 9652483ef49295379b28bdd842c846c0160fa1a1 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Tue, 2 Jul 2013 14:24:48 -0500 Subject: [PATCH 108/156] [feature/twig] Fix begin loop var regex PHPBB3-11598 --- phpBB/includes/template/twig/lexer.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/template/twig/lexer.php b/phpBB/includes/template/twig/lexer.php index b32a9e4ffa..c7ab1590f5 100644 --- a/phpBB/includes/template/twig/lexer.php +++ b/phpBB/includes/template/twig/lexer.php @@ -134,10 +134,10 @@ class phpbb_template_twig_lexer extends Twig_Lexer } } - // Remove all parent nodes, e.g. foo, bar from foo.bar.foobar + // Remove all parent nodes, e.g. foo, bar from foo.bar.foobar.VAR foreach ($parent_nodes as $node) { - $body = preg_replace('#([^a-zA-Z0-9])' . $node . '\.#', '$1', $body); + $body = preg_replace('#([^a-zA-Z0-9_])' . $node . '\.([a-zA-Z0-9_]+)\.#', '$1$2.', $body); } // Add current node to list of parent nodes for child nodes From f1717412f3c222af5c3cfc0b248842ea9ec88c9f Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Wed, 3 Jul 2013 09:31:35 -0500 Subject: [PATCH 109/156] [feature/twig] Debugging test failures PHPBB3-11598 --- tests/test_framework/phpbb_test_case_helpers.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/test_framework/phpbb_test_case_helpers.php b/tests/test_framework/phpbb_test_case_helpers.php index c4907d5ecf..b83b1ca5ca 100644 --- a/tests/test_framework/phpbb_test_case_helpers.php +++ b/tests/test_framework/phpbb_test_case_helpers.php @@ -96,6 +96,12 @@ class phpbb_test_case_helpers { if (!is_dir($path)) { + // Testing + if (file_exists($path)) + { + echo $path; + } + mkdir($path, 0777, true); } } From 36f25ea09bd42de7bc705332edc5ce3c402bd844 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 4 Jul 2013 10:12:09 -0500 Subject: [PATCH 110/156] [feature/twig] Change style->set_style to accept a list of base directories set_style now accepts an array containing a list of paths, e.g. array( 'ext/foo/bar/styles', 'styles'). Default: array('styles') Using this option allows us to set the style based on the user's preferred style (including the full tree), but use one or more base directories to add the paths from. The main use for this ability is so that extensions can call set_style, including their path and the phpBB styles path (or any others) and have their template files loaded from those directories (in the order given). PHPBB3-11598 --- phpBB/includes/style/style.php | 87 ++++++++++++++++----------- phpBB/includes/template/template.php | 2 +- phpBB/includes/template/twig/twig.php | 6 +- 3 files changed, 58 insertions(+), 37 deletions(-) diff --git a/phpBB/includes/style/style.php b/phpBB/includes/style/style.php index 29cdcf0f7f..b0bf3c1019 100644 --- a/phpBB/includes/style/style.php +++ b/phpBB/includes/style/style.php @@ -85,28 +85,56 @@ class phpbb_style } /** - * Set style location based on (current) user's chosen style. + * Get the style tree of the style preferred by the current user + * + * @return array Style tree, most specific first */ - public function set_style() + public function get_user_style() { - $style_path = $this->user->style['style_path']; - $style_dirs = ($this->user->style['style_parent_id']) ? array_reverse(explode('/', $this->user->style['style_parent_tree'])) : array(); + return array_merge(array( + $this->user->style['style_path'], + ), + ($this->user->style['style_parent_id']) ? array_reverse(explode('/', $this->user->style['style_parent_tree'])) : array() + ); + } - $names = array($style_path); - foreach ($style_dirs as $dir) - { - $names[] = $dir; - } - // Add 'all' path, used as last fallback path by events and extensions - //$names[] = 'all'; + /** + * Set style location based on (current) user's chosen style. + * + * @param array $style_directories The directories to add style paths for + * E.g. array('ext/foo/bar/styles', 'styles') + * Default: array('styles') (phpBB's style directory) + * @return bool true + */ + public function set_style($style_directories = array('styles')) + { + $this->names = $this->get_user_style(); $paths = array(); - foreach ($names as $name) + foreach ($style_directories as $directory) { - $paths[] = $this->get_style_path($name); + foreach ($this->names as $name) + { + $path = $this->get_style_path($name, $directory); + + if (is_dir($path)) + { + $paths[] = $path; + } + } } - return $this->set_custom_style($style_path, $paths, $names); + $this->provider->set_styles($paths); + $this->locator->set_paths($this->provider); + + foreach ($paths as &$path) + { + $path .= '/template/'; + } + + $this->template->set_style_names($this->names, $paths, ($style_directories === array('styles'))); + + return true; } /** @@ -118,6 +146,7 @@ class phpbb_style * @param array or string $paths Array of style paths, relative to current root directory * @param array $names Array of names of templates in inheritance tree order, used by extensions. If empty, $name will be used. * @param string $template_path Path to templates, relative to style directory. False if path should be set to default (templates/). + * @return bool true */ public function set_custom_style($name, $paths, $names = array(), $template_path = false) { @@ -138,28 +167,15 @@ class phpbb_style 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 + + foreach ($paths as &$path) { - $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); + $path .= '/' . (($template_path !== false) ? $template_path : 'template/'); } + $this->template->set_style_names($names, $paths); + return true; } @@ -167,11 +183,14 @@ class phpbb_style * Get location of style directory for specific style_path * * @param string $path Style path, such as "prosilver" + * @param string $style_base_directory The base directory the style is in + * E.g. 'styles', 'ext/foo/bar/styles' + * Default: 'styles' * @return string Path to style directory, relative to current path */ - public function get_style_path($path) + public function get_style_path($path, $style_base_directory = 'styles') { - return $this->phpbb_root_path . 'styles/' . $path; + return $this->phpbb_root_path . trim($style_base_directory, '/') . '/' . $path; } /** diff --git a/phpBB/includes/template/template.php b/phpBB/includes/template/template.php index 2b7c36ea7d..89a01e924d 100644 --- a/phpBB/includes/template/template.php +++ b/phpBB/includes/template/template.php @@ -41,7 +41,7 @@ interface phpbb_template * @param array $style_paths List of style paths in inheritance tree order * @return phpbb_template $this */ - public function set_style_names(array $style_names, array $style_paths = array()); + public function set_style_names(array $style_names, array $style_paths); /** * Clears all variables and blocks assigned to this template. diff --git a/phpBB/includes/template/twig/twig.php b/phpBB/includes/template/twig/twig.php index 98bd1ab89c..dd2c1a4023 100644 --- a/phpBB/includes/template/twig/twig.php +++ b/phpBB/includes/template/twig/twig.php @@ -181,9 +181,11 @@ class phpbb_template_twig implements phpbb_template * * @param array $style_names List of style names in inheritance tree order * @param array $style_paths List of style paths in inheritance tree order + * @param bool $is_core True if the style names are the "core" styles for this page load + * Core means the main phpBB template files * @return phpbb_template $this */ - public function set_style_names(array $style_names, array $style_paths = array()) + public function set_style_names(array $style_names, array $style_paths, $is_core = false) { $this->style_names = $style_names; @@ -191,7 +193,7 @@ class phpbb_template_twig implements phpbb_template $this->twig->getLoader()->setPaths($style_paths); // Core style namespace from phpbb_style::set_style() - if (isset($this->user->style['style_path']) && ($style_names === array($this->user->style['style_path']) || $style_names[0] == $this->user->style['style_path'])) + if ($is_core) { $this->twig->getLoader()->setPaths($style_paths, 'core'); } From 884a5b06fa2e300285a67885d0652d201c7a330a Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 4 Jul 2013 10:13:05 -0500 Subject: [PATCH 111/156] [feature/twig] Add set_style function to controller helper PHPBB3-11598 --- phpBB/config/services.yml | 1 + phpBB/includes/controller/helper.php | 25 ++++++++++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/phpBB/config/services.yml b/phpBB/config/services.yml index 23205169b9..f364bf5574 100644 --- a/phpBB/config/services.yml +++ b/phpBB/config/services.yml @@ -68,6 +68,7 @@ services: controller.helper: class: phpbb_controller_helper arguments: + - @style - @template - @user - %core.root_path% diff --git a/phpBB/includes/controller/helper.php b/phpBB/includes/controller/helper.php index 74410ddfd1..ec09757a5d 100644 --- a/phpBB/includes/controller/helper.php +++ b/phpBB/includes/controller/helper.php @@ -23,6 +23,12 @@ use Symfony\Component\HttpFoundation\Response; */ class phpbb_controller_helper { + /** + * Style object + * @var phpbb_style + */ + protected $style; + /** * Template object * @var phpbb_template @@ -50,19 +56,36 @@ class phpbb_controller_helper /** * Constructor * + * @param phpbb_style $style Style object * @param phpbb_template $template Template object * @param phpbb_user $user User object * @param string $phpbb_root_path phpBB root path * @param string $php_ext PHP extension */ - public function __construct(phpbb_template $template, phpbb_user $user, $phpbb_root_path, $php_ext) + public function __construct(phpbb_style $style, phpbb_template $template, phpbb_user $user, $phpbb_root_path, $php_ext) { + $this->style = $style; $this->template = $template; $this->user = $user; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; } + /** + * Set style location based on (current) user's chosen style. + * + * @param array $style_directories The directories to add style paths for + * E.g. array('ext/foo/bar/styles', 'styles') + * Default: array('styles') (phpBB's style directory) + * @return phpbb_controller_helper $this + */ + public function set_style($style_base_directory = array('styles')) + { + $this->style->set_style($style_base_directory); + + return $this; + } + /** * Automate setting up the page and creating the response object. * From 5c39f26cd27d5e4a1debfa24407825906f42d346 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 4 Jul 2013 10:13:46 -0500 Subject: [PATCH 112/156] [feature/twig] Call set_style in the foo/bar controller for functional tests PHPBB3-11598 --- tests/functional/fixtures/ext/foo/bar/controller/controller.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/functional/fixtures/ext/foo/bar/controller/controller.php b/tests/functional/fixtures/ext/foo/bar/controller/controller.php index 5a91b5f681..331f6addfb 100644 --- a/tests/functional/fixtures/ext/foo/bar/controller/controller.php +++ b/tests/functional/fixtures/ext/foo/bar/controller/controller.php @@ -9,6 +9,8 @@ class phpbb_ext_foo_bar_controller { $this->template = $template; $this->helper = $helper; + + $this->helper->set_style(array('ext/foo/bar/styles', 'styles')); } public function handle() From 84e0943c7bee5061bc53aed2a14f82751d238bf8 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 4 Jul 2013 10:22:12 -0500 Subject: [PATCH 113/156] [feature/twig] Indentation and comments PHPBB3-11598 --- phpBB/includes/template/twig/extension.php | 18 +++++++++--------- phpBB/includes/template/twig/twig.php | 4 +++- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/phpBB/includes/template/twig/extension.php b/phpBB/includes/template/twig/extension.php index a54c2b2509..f73b99a4c1 100644 --- a/phpBB/includes/template/twig/extension.php +++ b/phpBB/includes/template/twig/extension.php @@ -59,9 +59,9 @@ class phpbb_template_twig_extension extends Twig_Extension */ public function getFilters() { - return array( - new Twig_SimpleFilter('subset', array($this, 'loop_subset'), array('needs_environment' => true)), - new Twig_SimpleFilter('addslashes', 'addslashes'), + return array( + new Twig_SimpleFilter('subset', array($this, 'loop_subset'), array('needs_environment' => true)), + new Twig_SimpleFilter('addslashes', 'addslashes'), ); } @@ -72,8 +72,8 @@ class phpbb_template_twig_extension extends Twig_Extension */ public function getFunctions() { - return array( - new Twig_SimpleFunction('lang', array($this, 'lang')), + return array( + new Twig_SimpleFunction('lang', array($this, 'lang')), ); } @@ -86,7 +86,7 @@ class phpbb_template_twig_extension extends Twig_Extension { return array( array( - '!' => array('precedence' => 50, 'class' => 'Twig_Node_Expression_Unary_Not'), + '!' => array('precedence' => 50, 'class' => 'Twig_Node_Expression_Unary_Not'), ), array( // precedence settings are copied from similar operators in Twig core extension @@ -109,9 +109,9 @@ class phpbb_template_twig_extension extends Twig_Extension 'lte' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_LessEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), 'le' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_LessEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - 'mod' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mod', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - ), - ); + 'mod' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mod', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + ), + ); } /** diff --git a/phpBB/includes/template/twig/twig.php b/phpBB/includes/template/twig/twig.php index dd2c1a4023..621bfe0f4f 100644 --- a/phpBB/includes/template/twig/twig.php +++ b/phpBB/includes/template/twig/twig.php @@ -102,7 +102,9 @@ class phpbb_template_twig implements phpbb_template * Constructor. * * @param string $phpbb_root_path phpBB root path - * @param user $user current user + * @param string $php_ext php extension (typically 'php') + * @param phpbb_config $config + * @param phpbb_user $user * @param phpbb_template_context $context template context * @param phpbb_extension_manager $extension_manager extension manager, if null then template events will not be invoked * @param string $adm_relative_path relative path to adm directory From 81f27fd87ee2e8ffc1ad1ad06c5b255c5436e86c Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 4 Jul 2013 10:40:14 -0500 Subject: [PATCH 114/156] [feature/twig] Add test to make sure nested loops get the correct S_ROW_COUNT PHPBB3-11598 --- tests/template/template_test.php | 7 +++++++ tests/template/templates/loop_nested2.html | 6 ++++++ 2 files changed, 13 insertions(+) create mode 100644 tests/template/templates/loop_nested2.html diff --git a/tests/template/template_test.php b/tests/template/template_test.php index 1b3dda9b2a..4970ce0363 100644 --- a/tests/template/template_test.php +++ b/tests/template/template_test.php @@ -125,6 +125,13 @@ class phpbb_template_template_test extends phpbb_template_template_test_case array(), "101234561\nx\n101234561\nx\n101234561\nx\n1234561\nx\n1\nx\n101\nx\n234\nx\n10\nx\n561\nx\n561", ), + array( + 'loop_nested2.html', + array(), + array('outer' => array(array(), array()), 'outer.middle' => array(array(), array())), + array(), + "o0o1m01m11", + ), array( 'define.html', array(), diff --git a/tests/template/templates/loop_nested2.html b/tests/template/templates/loop_nested2.html new file mode 100644 index 0000000000..3eeeb5e36a --- /dev/null +++ b/tests/template/templates/loop_nested2.html @@ -0,0 +1,6 @@ + +o{outer.S_ROW_COUNT} + +m{outer.middle.S_ROW_COUNT}{outer.S_ROW_COUNT} + + From 2fb48d60f1b8ea111c766d6d9e7a3dde2b8a4e74 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 4 Jul 2013 11:08:36 -0500 Subject: [PATCH 115/156] [feature/twig] Attempt to automatically set style dir for ext controllers Extension authors can change it themselves if necessary PHPBB3-11598 --- phpBB/config/services.yml | 2 +- phpBB/includes/controller/resolver.php | 28 +++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/phpBB/config/services.yml b/phpBB/config/services.yml index f364bf5574..bb9879601c 100644 --- a/phpBB/config/services.yml +++ b/phpBB/config/services.yml @@ -79,7 +79,7 @@ services: arguments: - @user - @service_container - - @ext.finder + - @style cron.task_collection: class: phpbb_di_service_collection diff --git a/phpBB/includes/controller/resolver.php b/phpBB/includes/controller/resolver.php index ee469aa9c8..2c7d112748 100644 --- a/phpBB/includes/controller/resolver.php +++ b/phpBB/includes/controller/resolver.php @@ -37,16 +37,24 @@ class phpbb_controller_resolver implements ControllerResolverInterface */ protected $container; + /** + * phpbb_style object + * @var phpbb_style + */ + protected $style; + /** * Construct method * * @param phpbb_user $user User Object * @param ContainerInterface $container ContainerInterface object + * @param phpbb_style $style */ - public function __construct(phpbb_user $user, ContainerInterface $container) + public function __construct(phpbb_user $user, ContainerInterface $container, phpbb_style $style) { $this->user = $user; $this->container = $container; + $this->style = $style; } /** @@ -80,6 +88,24 @@ class phpbb_controller_resolver implements ControllerResolverInterface $controller_object = $this->container->get($service); + /* + * If this is an extension controller, we'll try to automatically set + * the style paths for the extension (the ext author can change them + * if necessary). + */ + $controller_dir = explode('_', get_class($controller_object)); + + // 0 phpbb, 1 ext, 2 vendor, 3 extension name, ... + if ($controller_dir[1] === 'ext') + { + $controller_style_dir = 'ext/' . $controller_dir[2] . '/' . $controller_dir[3] . '/styles'; + + if (is_dir($controller_style_dir)) + { + $this->style->set_style(array($controller_style_dir, 'styles')); + } + } + return array($controller_object, $method); } From bb56c1a391feff9c54d05f64e49c6d1f93ac2bce Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 4 Jul 2013 11:09:33 -0500 Subject: [PATCH 116/156] Revert "[feature/twig] Call set_style in the foo/bar controller for functional tests" This reverts commit 5c39f26cd27d5e4a1debfa24407825906f42d346. --- tests/functional/fixtures/ext/foo/bar/controller/controller.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/functional/fixtures/ext/foo/bar/controller/controller.php b/tests/functional/fixtures/ext/foo/bar/controller/controller.php index 331f6addfb..5a91b5f681 100644 --- a/tests/functional/fixtures/ext/foo/bar/controller/controller.php +++ b/tests/functional/fixtures/ext/foo/bar/controller/controller.php @@ -9,8 +9,6 @@ class phpbb_ext_foo_bar_controller { $this->template = $template; $this->helper = $helper; - - $this->helper->set_style(array('ext/foo/bar/styles', 'styles')); } public function handle() From 1ce33c1ff62426d030731cca100c4119bcd5265d Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 4 Jul 2013 11:12:26 -0500 Subject: [PATCH 117/156] [feature/twig] Safety check for 2fb48d6 PHPBB3-11598 --- phpBB/includes/controller/resolver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/controller/resolver.php b/phpBB/includes/controller/resolver.php index 2c7d112748..e44aa14b55 100644 --- a/phpBB/includes/controller/resolver.php +++ b/phpBB/includes/controller/resolver.php @@ -96,7 +96,7 @@ class phpbb_controller_resolver implements ControllerResolverInterface $controller_dir = explode('_', get_class($controller_object)); // 0 phpbb, 1 ext, 2 vendor, 3 extension name, ... - if ($controller_dir[1] === 'ext') + if (isset($controller_dir[3]) && $controller_dir[1] === 'ext') { $controller_style_dir = 'ext/' . $controller_dir[2] . '/' . $controller_dir[3] . '/styles'; From b7ede06835ba784b81365946f057adf75ae7592b Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 4 Jul 2013 11:16:44 -0500 Subject: [PATCH 118/156] [feature/twig] Make style dependency optional for resolver PHPBB3-11598 --- phpBB/includes/controller/resolver.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/controller/resolver.php b/phpBB/includes/controller/resolver.php index e44aa14b55..95dfc8da8e 100644 --- a/phpBB/includes/controller/resolver.php +++ b/phpBB/includes/controller/resolver.php @@ -50,7 +50,7 @@ class phpbb_controller_resolver implements ControllerResolverInterface * @param ContainerInterface $container ContainerInterface object * @param phpbb_style $style */ - public function __construct(phpbb_user $user, ContainerInterface $container, phpbb_style $style) + public function __construct(phpbb_user $user, ContainerInterface $container, phpbb_style $style = null) { $this->user = $user; $this->container = $container; @@ -96,7 +96,7 @@ class phpbb_controller_resolver implements ControllerResolverInterface $controller_dir = explode('_', get_class($controller_object)); // 0 phpbb, 1 ext, 2 vendor, 3 extension name, ... - if (isset($controller_dir[3]) && $controller_dir[1] === 'ext') + if (!is_null($this->style) && isset($controller_dir[3]) && $controller_dir[1] === 'ext') { $controller_style_dir = 'ext/' . $controller_dir[2] . '/' . $controller_dir[3] . '/styles'; From 5f03321fac6ce888cb870e158c685bf839c25f07 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 4 Jul 2013 12:44:12 -0500 Subject: [PATCH 119/156] [feature/twig] Support using Twig filters on {VAR}, add masks for Twig tags Now we can do {L_TITLE|upper}, {SITENAME|lower}, etc We can also use all the Twig tags in our own syntax. E.g. = {% block foo %]. All tags are the same as the Twig tag names, but are in uppercase. PHPBB3-11598 --- phpBB/includes/template/twig/lexer.php | 76 ++++++++++++++++++++++++-- phpBB/includes/template/twig/twig.php | 2 +- 2 files changed, 71 insertions(+), 7 deletions(-) diff --git a/phpBB/includes/template/twig/lexer.php b/phpBB/includes/template/twig/lexer.php index c7ab1590f5..50ef403231 100644 --- a/phpBB/includes/template/twig/lexer.php +++ b/phpBB/includes/template/twig/lexer.php @@ -19,8 +19,9 @@ class phpbb_template_twig_lexer extends Twig_Lexer { public function tokenize($code, $filename = null) { - $valid_starting_tokens = array( - // Commented out tokens are handled separately from the main replace + // Our phpBB tags + // Commented out tokens are handled separately from the main replace + $phpbb_tags = array( /*'BEGIN', 'BEGINELSE', 'END',*/ @@ -39,6 +40,34 @@ class phpbb_template_twig_lexer extends Twig_Lexer 'EVENT', ); + // Twig tag masks + $twig_tags = array( + 'autoescape', + 'endautoescape', + 'block', + 'endblock', + 'use', + 'extends', + 'embed', + 'filter', + 'endfilter', + 'flush', + 'for', + 'endfor', + 'macro', + 'endmacro', + 'import', + 'from', + 'sandbox', + 'endsandbox', + 'set', + 'endset', + 'spaceless', + 'endspaceless', + 'verbatim', + 'endverbatim', + ); + // Fix tokens that may have inline variables (e.g. with Twig style, {% TOKEN %} // This also strips outer parenthesis, becomes - $code = preg_replace('##', '{% $1 $2 %}', $code); + $code = preg_replace('##', '{% $1 $2 %}', $code); + + // Replace all of our twig masks with Twig code (e.g. with {% block $1 %}) + $code = $this->replace_twig_tag_masks($code, $twig_tags); // Replace all of our language variables, {L_VARNAME}, with Twig style, {{ lang('NAME') }} - $code = preg_replace('#{L_([a-zA-Z0-9_\.]+)}#', '{{ lang(\'$1\') }}', $code); + // Appends any filters after lang() + $code = preg_replace('#{L_([a-zA-Z0-9_\.]+)(\|[^}]+)?}#', '{{ lang(\'$1\')$2 }}', $code); // Replace all of our escaped language variables, {LA_VARNAME}, with Twig style, {{ lang('NAME')|addslashes }} - $code = preg_replace('#{LA_([a-zA-Z0-9_\.]+)}#', '{{ lang(\'$1\')|addslashes }}', $code); + // Appends any filters after lang(), but before addslashes + $code = preg_replace('#{LA_([a-zA-Z0-9_\.]+)(\|[^}]+)?}}#', '{{ lang(\'$1\')$2|addslashes }}', $code); // Replace all of our variables, {VARNAME}, with Twig style, {{ VARNAME }} - $code = preg_replace('#{([a-zA-Z0-9_\.]+)}#', '{{ $1 }}', $code); + // Appends any filters + $code = preg_replace('#{([a-zA-Z0-9_\.]+)(\|[^}]+)?}#', '{{ $1$2 }}', $code); return parent::tokenize($code, $filename); } @@ -227,4 +262,33 @@ class phpbb_template_twig_lexer extends Twig_Lexer return $code; } + + /** + * Replace Twig tag masks with Twig tag calls + * + * E.g. with {% block foo %} + * + * @param string $code + * @param array $twig_tags All tags we want to create a mask for + * @return string + */ + protected function replace_twig_tag_masks($code, $twig_tags) + { + $callback = function ($matches) + { + $matches[1] = strtolower($matches[1]); + + return "{% {$matches[1]}{$matches[2]}%}"; + }; + + foreach ($twig_tags as &$tag) + { + $tag = strtoupper($tag); + } + + // twig_tags is an array of the twig tags, which are all lowercase, but we use all uppercase tags + $code = preg_replace_callback('##',$callback, $code); + + return $code; + } } diff --git a/phpBB/includes/template/twig/twig.php b/phpBB/includes/template/twig/twig.php index 621bfe0f4f..47e346ad1e 100644 --- a/phpBB/includes/template/twig/twig.php +++ b/phpBB/includes/template/twig/twig.php @@ -132,7 +132,7 @@ class phpbb_template_twig implements phpbb_template array( 'cache' => $this->cachepath, 'debug' => defined('DEBUG'), - 'auto_reload' => (bool) $this->config['load_tplcompile'], + 'auto_reload' => true,//(bool) $this->config['load_tplcompile'], 'autoescape' => false, ) ); From 864465761f45fec2732381849ee9959d7ad9b45d Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 4 Jul 2013 13:19:03 -0500 Subject: [PATCH 120/156] [feature/twig] Fix debug code PHPBB3-11598 --- phpBB/includes/template/twig/twig.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/template/twig/twig.php b/phpBB/includes/template/twig/twig.php index 47e346ad1e..621bfe0f4f 100644 --- a/phpBB/includes/template/twig/twig.php +++ b/phpBB/includes/template/twig/twig.php @@ -132,7 +132,7 @@ class phpbb_template_twig implements phpbb_template array( 'cache' => $this->cachepath, 'debug' => defined('DEBUG'), - 'auto_reload' => true,//(bool) $this->config['load_tplcompile'], + 'auto_reload' => (bool) $this->config['load_tplcompile'], 'autoescape' => false, ) ); From 4f6cb9acbdc8b3564fa30e8e291e5fa669a409b9 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 4 Jul 2013 13:19:21 -0500 Subject: [PATCH 121/156] [feature/twig] Fix helper URL test PHPBB3-11598 --- tests/controller/helper_url_test.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/controller/helper_url_test.php b/tests/controller/helper_url_test.php index e376efde66..3206460caf 100644 --- a/tests/controller/helper_url_test.php +++ b/tests/controller/helper_url_test.php @@ -51,8 +51,11 @@ class phpbb_controller_helper_url_test extends phpbb_test_case $this->style_resource_locator = new phpbb_style_resource_locator(); $this->user = $this->getMock('phpbb_user'); $this->template = new phpbb_template_twig($phpbb_root_path, $phpEx, $config, $this->user, new phpbb_template_context()); + $this->style_resource_locator = new phpbb_style_resource_locator(); + $this->style_provider = new phpbb_style_path_provider(); + $this->style = new phpbb_style($phpbb_root_path, $phpEx, new phpbb_config(array()), $this->user, $this->style_resource_locator, $this->style_provider, $this->template); - $helper = new phpbb_controller_helper($this->template, $this->user, '', 'php'); + $helper = new phpbb_controller_helper($this->style, $this->template, $this->user, '', 'php'); $this->assertEquals($helper->url($route, $params, $is_amp, $session_id), $expected); } } From fdbdd8bfd92795098b4f9a704a677972e611f455 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 4 Jul 2013 13:22:41 -0500 Subject: [PATCH 122/156] [feature/twig] Fix a regular expression PHPBB3-11598 --- phpBB/includes/template/twig/lexer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/template/twig/lexer.php b/phpBB/includes/template/twig/lexer.php index 50ef403231..394c3077a6 100644 --- a/phpBB/includes/template/twig/lexer.php +++ b/phpBB/includes/template/twig/lexer.php @@ -98,7 +98,7 @@ class phpbb_template_twig_lexer extends Twig_Lexer // Replace all of our escaped language variables, {LA_VARNAME}, with Twig style, {{ lang('NAME')|addslashes }} // Appends any filters after lang(), but before addslashes - $code = preg_replace('#{LA_([a-zA-Z0-9_\.]+)(\|[^}]+)?}}#', '{{ lang(\'$1\')$2|addslashes }}', $code); + $code = preg_replace('#{LA_([a-zA-Z0-9_\.]+)(\|[^}]+)?}#', '{{ lang(\'$1\')$2|addslashes }}', $code); // Replace all of our variables, {VARNAME}, with Twig style, {{ VARNAME }} // Appends any filters From 8cf6dbd95035f71ea8cff0f2f8d834b91b243429 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 4 Jul 2013 13:25:50 -0500 Subject: [PATCH 123/156] [feature/twig] Trying some new debug code for this mkdir error PHPBB3-11598 --- tests/test_framework/phpbb_test_case_helpers.php | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/tests/test_framework/phpbb_test_case_helpers.php b/tests/test_framework/phpbb_test_case_helpers.php index b83b1ca5ca..fdc09fbeec 100644 --- a/tests/test_framework/phpbb_test_case_helpers.php +++ b/tests/test_framework/phpbb_test_case_helpers.php @@ -94,16 +94,12 @@ class phpbb_test_case_helpers public function makedirs($path) { - if (!is_dir($path)) + if (is_dir($path) || file_exists($path)) { - // Testing - if (file_exists($path)) - { - echo $path; - } - - mkdir($path, 0777, true); + var_dump($path); + exit; } + mkdir($path, 0777, true); } static public function get_test_config() From 24be21636656bf636738449488da3810e489b4a7 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 4 Jul 2013 13:49:56 -0500 Subject: [PATCH 124/156] [feature/twig] Attempt to automatically set style dir for ext modules Extension authors can change it themselves if necessary PHPBB3-11598 --- phpBB/includes/functions_module.php | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/phpBB/includes/functions_module.php b/phpBB/includes/functions_module.php index 0d387ace6d..5a8ac276cd 100644 --- a/phpBB/includes/functions_module.php +++ b/phpBB/includes/functions_module.php @@ -455,7 +455,7 @@ class p_master */ function load_active($mode = false, $module_url = false, $execute_module = true) { - global $phpbb_root_path, $phpbb_admin_path, $phpEx, $user; + global $phpbb_root_path, $phpbb_admin_path, $phpEx, $user, $style; $module_path = $this->include_path . $this->p_class; $icat = request_var('icat', ''); @@ -491,6 +491,24 @@ class p_master $this->module = new $class_name($this); + /* + * If this is an extension module, we'll try to automatically set + * the style paths for the extension (the ext author can change them + * if necessary). + */ + $module_dir = explode('_', get_class($this->module)); + + // 0 phpbb, 1 ext, 2 vendor, 3 extension name, ... + if (!is_null($this->style) && isset($module_dir[3]) && $module_dir[1] === 'ext') + { + $module_style_dir = 'ext/' . $module_dir[2] . '/' . $module_dir[3] . '/styles'; + + if (is_dir($module_style_dir)) + { + $style->set_style(array($module_style_dir, 'styles')); + } + } + // We pre-define the action parameter we are using all over the place if (defined('IN_ADMIN')) { From 38700a80f805ae32632d88254e714699b8435f61 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 4 Jul 2013 14:09:50 -0500 Subject: [PATCH 125/156] [feature/twig] Fix copy/pasted code PHPBB3-11598 --- phpBB/includes/functions_module.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/functions_module.php b/phpBB/includes/functions_module.php index 5a8ac276cd..85ff41500f 100644 --- a/phpBB/includes/functions_module.php +++ b/phpBB/includes/functions_module.php @@ -499,7 +499,7 @@ class p_master $module_dir = explode('_', get_class($this->module)); // 0 phpbb, 1 ext, 2 vendor, 3 extension name, ... - if (!is_null($this->style) && isset($module_dir[3]) && $module_dir[1] === 'ext') + if (isset($module_dir[3]) && $module_dir[1] === 'ext') { $module_style_dir = 'ext/' . $module_dir[2] . '/' . $module_dir[3] . '/styles'; From 53496e6a473f1e5563f733365cbeaf275c2fd0af Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 4 Jul 2013 15:21:57 -0500 Subject: [PATCH 126/156] [feature/twig] acp module tpls are in ext/adm, ucp/mcp in styles/ PHPBB3-11598 --- phpBB/includes/functions_module.php | 56 +++++++++++++++++++---------- 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/phpBB/includes/functions_module.php b/phpBB/includes/functions_module.php index 85ff41500f..df0327db0f 100644 --- a/phpBB/includes/functions_module.php +++ b/phpBB/includes/functions_module.php @@ -455,7 +455,7 @@ class p_master */ function load_active($mode = false, $module_url = false, $execute_module = true) { - global $phpbb_root_path, $phpbb_admin_path, $phpEx, $user, $style; + global $phpbb_root_path, $phpbb_admin_path, $phpEx, $user, $phpbb_style; $module_path = $this->include_path . $this->p_class; $icat = request_var('icat', ''); @@ -491,27 +491,27 @@ class p_master $this->module = new $class_name($this); - /* - * If this is an extension module, we'll try to automatically set - * the style paths for the extension (the ext author can change them - * if necessary). - */ - $module_dir = explode('_', get_class($this->module)); - - // 0 phpbb, 1 ext, 2 vendor, 3 extension name, ... - if (isset($module_dir[3]) && $module_dir[1] === 'ext') - { - $module_style_dir = 'ext/' . $module_dir[2] . '/' . $module_dir[3] . '/styles'; - - if (is_dir($module_style_dir)) - { - $style->set_style(array($module_style_dir, 'styles')); - } - } - // We pre-define the action parameter we are using all over the place if (defined('IN_ADMIN')) { + /* + * If this is an extension module, we'll try to automatically set + * the style paths for the extension (the ext author can change them + * if necessary). + */ + $module_dir = explode('_', get_class($this->module)); + + // 0 phpbb, 1 ext, 2 vendor, 3 extension name, ... + if (isset($module_dir[3]) && $module_dir[1] === 'ext') + { + $module_style_dir = $phpbb_root_path .'ext/' . $module_dir[2] . '/' . $module_dir[3] . '/adm/style'; + + if (is_dir($module_style_dir)) + { + $phpbb_style->set_custom_style('admin', array($module_style_dir, $phpbb_admin_path . 'style'), array(), ''); + } + } + // Is first module automatically enabled a duplicate and the category not passed yet? if (!$icat && $this->module_ary[$this->active_module_row_id]['is_duplicate']) { @@ -523,6 +523,24 @@ class p_master } else { + /* + * If this is an extension module, we'll try to automatically set + * the style paths for the extension (the ext author can change them + * if necessary). + */ + $module_dir = explode('_', get_class($this->module)); + + // 0 phpbb, 1 ext, 2 vendor, 3 extension name, ... + if (isset($module_dir[3]) && $module_dir[1] === 'ext') + { + $module_style_dir = 'ext/' . $module_dir[2] . '/' . $module_dir[3] . '/styles'; + + if (is_dir($phpbb_root_path . $module_style_dir)) + { + $phpbb_style->set_style(array($module_style_dir, 'styles')); + } + } + // If user specified the module url we will use it... if ($module_url !== false) { From 0f3086a54bf2a9c83876a135738bdf130e0f0844 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 4 Jul 2013 15:24:42 -0500 Subject: [PATCH 127/156] [feature/twig] Spacing PHPBB3-11598 --- phpBB/includes/functions_module.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/functions_module.php b/phpBB/includes/functions_module.php index df0327db0f..99c24fcb19 100644 --- a/phpBB/includes/functions_module.php +++ b/phpBB/includes/functions_module.php @@ -504,7 +504,7 @@ class p_master // 0 phpbb, 1 ext, 2 vendor, 3 extension name, ... if (isset($module_dir[3]) && $module_dir[1] === 'ext') { - $module_style_dir = $phpbb_root_path .'ext/' . $module_dir[2] . '/' . $module_dir[3] . '/adm/style'; + $module_style_dir = $phpbb_root_path . 'ext/' . $module_dir[2] . '/' . $module_dir[3] . '/adm/style'; if (is_dir($module_style_dir)) { From 25b4732845941c488f3667ef7ec4afdc0e69d274 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 4 Jul 2013 15:32:04 -0500 Subject: [PATCH 128/156] [feature/twig] Remove debug code PHPBB3-11598 --- tests/test_framework/phpbb_test_case_helpers.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/test_framework/phpbb_test_case_helpers.php b/tests/test_framework/phpbb_test_case_helpers.php index fdc09fbeec..50b2bf03ec 100644 --- a/tests/test_framework/phpbb_test_case_helpers.php +++ b/tests/test_framework/phpbb_test_case_helpers.php @@ -94,11 +94,6 @@ class phpbb_test_case_helpers public function makedirs($path) { - if (is_dir($path) || file_exists($path)) - { - var_dump($path); - exit; - } mkdir($path, 0777, true); } From 192c9d8f867a0c7d1a81d23bc4fb11c63fe1ec40 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Fri, 5 Jul 2013 09:37:40 -0500 Subject: [PATCH 129/156] [feature/twig] Removing template/renderer.php (no longer used) PHPBB3-11598 --- phpBB/includes/template/renderer.php | 35 ---------------------------- 1 file changed, 35 deletions(-) delete mode 100644 phpBB/includes/template/renderer.php diff --git a/phpBB/includes/template/renderer.php b/phpBB/includes/template/renderer.php deleted file mode 100644 index 30e234a733..0000000000 --- a/phpBB/includes/template/renderer.php +++ /dev/null @@ -1,35 +0,0 @@ - Date: Fri, 5 Jul 2013 09:56:25 -0500 Subject: [PATCH 130/156] [feature/twig] Docs/typehinting for Twig extension PHPBB3-11598 --- phpBB/includes/template/twig/extension.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/phpBB/includes/template/twig/extension.php b/phpBB/includes/template/twig/extension.php index f73b99a4c1..5704468013 100644 --- a/phpBB/includes/template/twig/extension.php +++ b/phpBB/includes/template/twig/extension.php @@ -23,12 +23,24 @@ class phpbb_template_twig_extension extends Twig_Extension /** @var phpbb_user */ protected $user; - public function __construct(phpbb_template_context $context, $user) + /** + * Constructor + * + * @param phpbb_template_context $context + * @param phpbb_user $user + * @return phpbb_template_twig_extension + */ + public function __construct(phpbb_template_context $context, phpbb_user $user) { $this->context = $context; $this->user = $user; } + /** + * Get the name of this extension + * + * @return string + */ public function getName() { return 'phpbb'; From c1a600277d07c2dbb3ebd410f87acb22627a9d60 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Fri, 5 Jul 2013 09:57:55 -0500 Subject: [PATCH 131/156] [feature/twig] Nicer code for get_user_style.php() PHPBB3-11598 --- phpBB/includes/style/style.php | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/phpBB/includes/style/style.php b/phpBB/includes/style/style.php index b0bf3c1019..06c16fdef4 100644 --- a/phpBB/includes/style/style.php +++ b/phpBB/includes/style/style.php @@ -91,11 +91,16 @@ class phpbb_style */ public function get_user_style() { - return array_merge(array( - $this->user->style['style_path'], - ), - ($this->user->style['style_parent_id']) ? array_reverse(explode('/', $this->user->style['style_parent_tree'])) : array() + $style_list = array( + $this->user->style['style_path'], ); + + if ($this->user->style['style_parent_id']) + { + $style_list = array_merge($style_list, array_reverse(explode('/', $this->user->style['style_parent_tree']))); + } + + return $style_list; } /** From 2674740573a226dae36dc81faf8eb5453e01a31d Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Fri, 5 Jul 2013 10:03:48 -0500 Subject: [PATCH 132/156] [feature/twig] Spacing PHPBB3-11598 --- phpBB/includes/template/twig/extension.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/template/twig/extension.php b/phpBB/includes/template/twig/extension.php index 5704468013..e23dd4f119 100644 --- a/phpBB/includes/template/twig/extension.php +++ b/phpBB/includes/template/twig/extension.php @@ -144,7 +144,7 @@ class phpbb_template_twig_extension extends Twig_Extension { // When end is > 1, subset will end on the last item in an array with the specified $end // This is different from slice in that it is the number we end on rather than the number - // of items to grab (length) + // of items to grab (length) // Start must always be the actual starting number for this calculation (not negative) $start = ($start < 0) ? sizeof($item) + $start : $start; From 81f0715b8ef89e3a03a285a0c0f4639351449e9a Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Fri, 5 Jul 2013 10:05:20 -0500 Subject: [PATCH 133/156] [feature/twig] Clarify comment PHPBB3-11598 --- phpBB/includes/template/twig/extension.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/template/twig/extension.php b/phpBB/includes/template/twig/extension.php index e23dd4f119..6b066f1bd3 100644 --- a/phpBB/includes/template/twig/extension.php +++ b/phpBB/includes/template/twig/extension.php @@ -139,7 +139,7 @@ class phpbb_template_twig_extension extends Twig_Extension */ function loop_subset(Twig_Environment $env, $item, $start, $end = null, $preserveKeys = false) { - // We do almost the same thing as array_slice, except when $end is positive + // We do almost the same thing as Twig's slice (array_slice), except when $end is positive if ($end >= 1) { // When end is > 1, subset will end on the last item in an array with the specified $end From 1f4a717f9ec925d84b589547ce6c93a17ae863e9 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Fri, 5 Jul 2013 10:29:24 -0500 Subject: [PATCH 134/156] [feature/twig] Add template test for ===, !== PHPBB3-11598 --- tests/template/template_test.php | 22 ++++++++++++++++++---- tests/template/templates/if.html | 8 ++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/tests/template/template_test.php b/tests/template/template_test.php index 4970ce0363..b7c3a08512 100644 --- a/tests/template/template_test.php +++ b/tests/template/template_test.php @@ -46,28 +46,42 @@ class phpbb_template_template_test extends phpbb_template_template_test_case array(), array(), array(), - '03', + '03!false', ), array( 'if.html', array('S_VALUE' => true), array(), array(), - '1', + '1!false', ), array( 'if.html', array('S_VALUE' => true, 'S_OTHER_VALUE' => true), array(), array(), - '1', + '1!false', ), array( 'if.html', array('S_VALUE' => false, 'S_OTHER_VALUE' => true), array(), array(), - '2', + '2!false', + ), + array( + 'if.html', + array('S_TEST' => false), + array(), + array(), + '03false', + ), + array( + 'if.html', + array('S_TEST' => 0), + array(), + array(), + '03!false', ), array( 'loop.html', diff --git a/tests/template/templates/if.html b/tests/template/templates/if.html index eed431019e..c010aff7fa 100644 --- a/tests/template/templates/if.html +++ b/tests/template/templates/if.html @@ -9,3 +9,11 @@ 04 + + +false + + + +!false + From 13c356545465a457b8c55dd9638f89165bab6271 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Fri, 5 Jul 2013 12:11:59 -0500 Subject: [PATCH 135/156] [feature/twig] Remove style dependency for controller helper If a controller wants to use set_style, it can just use phpbb_style PHPBB3-11598 --- phpBB/config/services.yml | 1 - phpBB/includes/controller/helper.php | 25 +------------------------ tests/controller/helper_url_test.php | 2 +- 3 files changed, 2 insertions(+), 26 deletions(-) diff --git a/phpBB/config/services.yml b/phpBB/config/services.yml index 3d951e2a45..e228b3d83f 100644 --- a/phpBB/config/services.yml +++ b/phpBB/config/services.yml @@ -69,7 +69,6 @@ services: controller.helper: class: phpbb_controller_helper arguments: - - @style - @template - @user - %core.root_path% diff --git a/phpBB/includes/controller/helper.php b/phpBB/includes/controller/helper.php index ec09757a5d..74410ddfd1 100644 --- a/phpBB/includes/controller/helper.php +++ b/phpBB/includes/controller/helper.php @@ -23,12 +23,6 @@ use Symfony\Component\HttpFoundation\Response; */ class phpbb_controller_helper { - /** - * Style object - * @var phpbb_style - */ - protected $style; - /** * Template object * @var phpbb_template @@ -56,36 +50,19 @@ class phpbb_controller_helper /** * Constructor * - * @param phpbb_style $style Style object * @param phpbb_template $template Template object * @param phpbb_user $user User object * @param string $phpbb_root_path phpBB root path * @param string $php_ext PHP extension */ - public function __construct(phpbb_style $style, phpbb_template $template, phpbb_user $user, $phpbb_root_path, $php_ext) + public function __construct(phpbb_template $template, phpbb_user $user, $phpbb_root_path, $php_ext) { - $this->style = $style; $this->template = $template; $this->user = $user; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; } - /** - * Set style location based on (current) user's chosen style. - * - * @param array $style_directories The directories to add style paths for - * E.g. array('ext/foo/bar/styles', 'styles') - * Default: array('styles') (phpBB's style directory) - * @return phpbb_controller_helper $this - */ - public function set_style($style_base_directory = array('styles')) - { - $this->style->set_style($style_base_directory); - - return $this; - } - /** * Automate setting up the page and creating the response object. * diff --git a/tests/controller/helper_url_test.php b/tests/controller/helper_url_test.php index 3206460caf..6686b77e8f 100644 --- a/tests/controller/helper_url_test.php +++ b/tests/controller/helper_url_test.php @@ -55,7 +55,7 @@ class phpbb_controller_helper_url_test extends phpbb_test_case $this->style_provider = new phpbb_style_path_provider(); $this->style = new phpbb_style($phpbb_root_path, $phpEx, new phpbb_config(array()), $this->user, $this->style_resource_locator, $this->style_provider, $this->template); - $helper = new phpbb_controller_helper($this->style, $this->template, $this->user, '', 'php'); + $helper = new phpbb_controller_helper($this->template, $this->user, '', 'php'); $this->assertEquals($helper->url($route, $params, $is_amp, $session_id), $expected); } } From 05984be2c002133d1dd7f546e4238749b275f9f6 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Fri, 5 Jul 2013 12:47:50 -0500 Subject: [PATCH 136/156] [feature/twig] Fix S_NUM_ROWS assignment PHPBB3-11598 --- phpBB/includes/template/context.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/template/context.php b/phpBB/includes/template/context.php index e3ad6be46c..c5ce7422b9 100644 --- a/phpBB/includes/template/context.php +++ b/phpBB/includes/template/context.php @@ -165,7 +165,7 @@ class phpbb_template_context // Set S_NUM_ROWS foreach ($str[$blocks[$blockcount]] as &$mod_block) { - $mod_block['S_NUM_ROWS'] = $blockcount; + $mod_block['S_NUM_ROWS'] = sizeof($str[$blocks[$blockcount]]); } } else From 9ac61565fdb0fd3464b9c974b506f084f24e0bbd Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Fri, 5 Jul 2013 12:48:02 -0500 Subject: [PATCH 137/156] [feature/twig] Add template tests for S_NUM_ROWS and S_BLOCK_NAME PHPBB3-11598 --- tests/template/template_test.php | 33 ++++++++++++++++++++++- tests/template/templates/loop_nested.html | 4 +-- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/tests/template/template_test.php b/tests/template/template_test.php index b7c3a08512..d99e91bae4 100644 --- a/tests/template/template_test.php +++ b/tests/template/template_test.php @@ -516,4 +516,35 @@ EOT $this->template->alter_block_array($alter_block, $vararray, $key, $mode); $this->assertEquals(str_replace(array("\n", "\r", "\t"), '', $expect), str_replace(array("\n", "\r", "\t"), '', $this->display('test')), $description); } -} \ No newline at end of file + + public function test_more_alter_block_array() + { + $this->template->set_filenames(array('test' => 'loop_nested.html')); + + $this->template->assign_var('TEST_MORE', true); + + // @todo Change this + $this->template->assign_block_vars('outer', array()); + $this->template->assign_block_vars('outer.middle', array()); + $this->template->assign_block_vars('outer', array()); + $this->template->assign_block_vars('outer.middle', array()); + $this->template->assign_block_vars('outer.middle', array()); + $this->template->assign_block_vars('outer', array()); + $this->template->assign_block_vars('outer.middle', array()); + $this->template->assign_block_vars('outer.middle', array()); + $this->template->assign_block_vars('outer.middle', array()); + + $expect = 'outer - 0[outer|3]middle - 0[middle|1]outer - 1[outer|3]middle - 0[middle|2]middle - 1[middle|2]outer - 2[outer|3]middle - 0[middle|3]middle - 1[middle|3]middle - 2[middle|3]'; + $this->assertEquals($expect, str_replace(array("\n", "\r", "\t"), '', $this->display('test')), 'Ensuring template is built correctly before modification'); + + $this->template->alter_block_array('outer', array()); + + $expect = 'outer - 0[outer|4]outer - 1[outer|4]middle - 0[middle|1]outer - 2[outer|4]middle - 0[middle|2]middle - 1[middle|2]outer - 3[outer|4]middle - 0[middle|3]middle - 1[middle|3]middle - 2[middle|3]'; + $this->assertEquals($expect, str_replace(array("\n", "\r", "\t"), '', $this->display('test')), 'Ensuring S_NUM_ROWS is correct after insertion'); + + $this->template->alter_block_array('outer', array('VARIABLE' => 'test'), 2, 'change'); + + $expect = 'outer - 0[outer|4]outer - 1[outer|4]middle - 0[middle|1]outer - 2 - test[outer|4]middle - 0[middle|2]middle - 1[middle|2]outer - 3[outer|4]middle - 0[middle|3]middle - 1[middle|3]middle - 2[middle|3]'; + $this->assertEquals($expect, str_replace(array("\n", "\r", "\t"), '', $this->display('test')), 'Ensuring S_NUM_ROWS is correct after modification'); + } +} diff --git a/tests/template/templates/loop_nested.html b/tests/template/templates/loop_nested.html index 3b5ffa5cac..cf099ecc15 100644 --- a/tests/template/templates/loop_nested.html +++ b/tests/template/templates/loop_nested.html @@ -1,6 +1,6 @@ -outer - {outer.S_ROW_COUNT} - {outer.VARIABLE} +outer - {outer.S_ROW_COUNT} - {outer.VARIABLE}[{outer.S_BLOCK_NAME}|{outer.S_NUM_ROWS}] -middle - {outer.middle.S_ROW_COUNT} - {outer.middle.VARIABLE} +middle - {outer.middle.S_ROW_COUNT} - {outer.middle.VARIABLE}[{outer.middle.S_BLOCK_NAME}|{outer.middle.S_NUM_ROWS}] From 99ddbe1adc8dad125fa996f1f568bdcfa2b80d95 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Fri, 5 Jul 2013 12:55:32 -0500 Subject: [PATCH 138/156] [feature/twig] Can't use typehint here, causes tests to fail PHPBB3-11598 --- phpBB/includes/template/twig/extension.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/template/twig/extension.php b/phpBB/includes/template/twig/extension.php index 6b066f1bd3..c4d36050f9 100644 --- a/phpBB/includes/template/twig/extension.php +++ b/phpBB/includes/template/twig/extension.php @@ -30,7 +30,7 @@ class phpbb_template_twig_extension extends Twig_Extension * @param phpbb_user $user * @return phpbb_template_twig_extension */ - public function __construct(phpbb_template_context $context, phpbb_user $user) + public function __construct(phpbb_template_context $context, $user) { $this->context = $context; $this->user = $user; From c5c34ff831faf96368d34012dc65bdb9451227aa Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Fri, 5 Jul 2013 13:10:35 -0500 Subject: [PATCH 139/156] [feature/twig] Add check for defined IN_PHPBB in all new Twig related files PHPBB3-11598 --- phpBB/includes/template/twig/node/define.php | 9 +++++++++ phpBB/includes/template/twig/node/event.php | 9 +++++++++ .../template/twig/node/expression/binary/equalequal.php | 9 +++++++++ .../twig/node/expression/binary/notequalequal.php | 9 +++++++++ phpBB/includes/template/twig/node/include.php | 9 +++++++++ phpBB/includes/template/twig/node/includejs.php | 9 +++++++++ phpBB/includes/template/twig/node/includephp.php | 9 +++++++++ phpBB/includes/template/twig/node/php.php | 9 +++++++++ phpBB/includes/template/twig/tokenparser/define.php | 9 +++++++++ phpBB/includes/template/twig/tokenparser/event.php | 9 +++++++++ phpBB/includes/template/twig/tokenparser/if.php | 9 +++++++++ phpBB/includes/template/twig/tokenparser/include.php | 9 +++++++++ phpBB/includes/template/twig/tokenparser/includejs.php | 9 +++++++++ phpBB/includes/template/twig/tokenparser/includephp.php | 9 +++++++++ phpBB/includes/template/twig/tokenparser/php.php | 9 +++++++++ 15 files changed, 135 insertions(+) diff --git a/phpBB/includes/template/twig/node/define.php b/phpBB/includes/template/twig/node/define.php index 499bbdc518..fcb19cc773 100644 --- a/phpBB/includes/template/twig/node/define.php +++ b/phpBB/includes/template/twig/node/define.php @@ -7,6 +7,15 @@ * */ +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + + class phpbb_template_twig_node_define extends Twig_Node { public function __construct($capture, Twig_NodeInterface $name, Twig_NodeInterface $value, $lineno, $tag = null) diff --git a/phpBB/includes/template/twig/node/event.php b/phpBB/includes/template/twig/node/event.php index 6de270e19c..984ba35244 100644 --- a/phpBB/includes/template/twig/node/event.php +++ b/phpBB/includes/template/twig/node/event.php @@ -7,6 +7,15 @@ * */ +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + + class phpbb_template_twig_node_event extends Twig_Node { /** @var Twig_Environment */ diff --git a/phpBB/includes/template/twig/node/expression/binary/equalequal.php b/phpBB/includes/template/twig/node/expression/binary/equalequal.php index 054f63ecf9..8ec2069114 100644 --- a/phpBB/includes/template/twig/node/expression/binary/equalequal.php +++ b/phpBB/includes/template/twig/node/expression/binary/equalequal.php @@ -7,6 +7,15 @@ * */ +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + + class phpbb_template_twig_node_expression_binary_equalequal extends Twig_Node_Expression_Binary { public function operator(Twig_Compiler $compiler) diff --git a/phpBB/includes/template/twig/node/expression/binary/notequalequal.php b/phpBB/includes/template/twig/node/expression/binary/notequalequal.php index d8a1c411cf..96f32c502e 100644 --- a/phpBB/includes/template/twig/node/expression/binary/notequalequal.php +++ b/phpBB/includes/template/twig/node/expression/binary/notequalequal.php @@ -7,6 +7,15 @@ * */ +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + + class phpbb_template_twig_node_expression_binary_notequalequal extends Twig_Node_Expression_Binary { public function operator(Twig_Compiler $compiler) diff --git a/phpBB/includes/template/twig/node/include.php b/phpBB/includes/template/twig/node/include.php index a614cbe20f..5c6ae1bbcf 100644 --- a/phpBB/includes/template/twig/node/include.php +++ b/phpBB/includes/template/twig/node/include.php @@ -7,6 +7,15 @@ * */ +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + + class phpbb_template_twig_node_include extends Twig_Node_Include { /** diff --git a/phpBB/includes/template/twig/node/includejs.php b/phpBB/includes/template/twig/node/includejs.php index 6d0d67c6c9..943eb89ace 100644 --- a/phpBB/includes/template/twig/node/includejs.php +++ b/phpBB/includes/template/twig/node/includejs.php @@ -7,6 +7,15 @@ * */ +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + + class phpbb_template_twig_node_includejs extends Twig_Node { /** @var Twig_Environment */ diff --git a/phpBB/includes/template/twig/node/includephp.php b/phpBB/includes/template/twig/node/includephp.php index b5bb2ee9c9..dbe54f0e1a 100644 --- a/phpBB/includes/template/twig/node/includephp.php +++ b/phpBB/includes/template/twig/node/includephp.php @@ -7,6 +7,15 @@ * */ +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + + class phpbb_template_twig_node_includephp extends Twig_Node { /** @var Twig_Environment */ diff --git a/phpBB/includes/template/twig/node/php.php b/phpBB/includes/template/twig/node/php.php index ebf4947e48..c11539ea7f 100644 --- a/phpBB/includes/template/twig/node/php.php +++ b/phpBB/includes/template/twig/node/php.php @@ -7,6 +7,15 @@ * */ +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + + class phpbb_template_twig_node_php extends Twig_Node { /** @var Twig_Environment */ diff --git a/phpBB/includes/template/twig/tokenparser/define.php b/phpBB/includes/template/twig/tokenparser/define.php index ed77699b77..4ea15388c4 100644 --- a/phpBB/includes/template/twig/tokenparser/define.php +++ b/phpBB/includes/template/twig/tokenparser/define.php @@ -7,6 +7,15 @@ * */ +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + + class phpbb_template_twig_tokenparser_define extends Twig_TokenParser { /** diff --git a/phpBB/includes/template/twig/tokenparser/event.php b/phpBB/includes/template/twig/tokenparser/event.php index 2a6d6b6457..e4dddd6dcc 100644 --- a/phpBB/includes/template/twig/tokenparser/event.php +++ b/phpBB/includes/template/twig/tokenparser/event.php @@ -7,6 +7,15 @@ * */ +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + + class phpbb_template_twig_tokenparser_event extends Twig_TokenParser { /** diff --git a/phpBB/includes/template/twig/tokenparser/if.php b/phpBB/includes/template/twig/tokenparser/if.php index 939d679030..77881ad5f0 100644 --- a/phpBB/includes/template/twig/tokenparser/if.php +++ b/phpBB/includes/template/twig/tokenparser/if.php @@ -7,6 +7,15 @@ * */ +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + + class phpbb_template_twig_tokenparser_if extends Twig_TokenParser_If { /** diff --git a/phpBB/includes/template/twig/tokenparser/include.php b/phpBB/includes/template/twig/tokenparser/include.php index 5b5105d23e..520f9fd1a0 100644 --- a/phpBB/includes/template/twig/tokenparser/include.php +++ b/phpBB/includes/template/twig/tokenparser/include.php @@ -7,6 +7,15 @@ * */ +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + + class phpbb_template_twig_tokenparser_include extends Twig_TokenParser_Include { /** diff --git a/phpBB/includes/template/twig/tokenparser/includejs.php b/phpBB/includes/template/twig/tokenparser/includejs.php index 962d01ac45..b02b2f89ba 100644 --- a/phpBB/includes/template/twig/tokenparser/includejs.php +++ b/phpBB/includes/template/twig/tokenparser/includejs.php @@ -7,6 +7,15 @@ * */ +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + + class phpbb_template_twig_tokenparser_includejs extends Twig_TokenParser { /** diff --git a/phpBB/includes/template/twig/tokenparser/includephp.php b/phpBB/includes/template/twig/tokenparser/includephp.php index 57d804183b..13fe6de8a6 100644 --- a/phpBB/includes/template/twig/tokenparser/includephp.php +++ b/phpBB/includes/template/twig/tokenparser/includephp.php @@ -7,6 +7,15 @@ * */ +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + + class phpbb_template_twig_tokenparser_includephp extends Twig_TokenParser { /** diff --git a/phpBB/includes/template/twig/tokenparser/php.php b/phpBB/includes/template/twig/tokenparser/php.php index 62e1c4fdcd..197980a59a 100644 --- a/phpBB/includes/template/twig/tokenparser/php.php +++ b/phpBB/includes/template/twig/tokenparser/php.php @@ -7,6 +7,15 @@ * */ +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + + class phpbb_template_twig_tokenparser_php extends Twig_TokenParser { /** From 0ffbdc80d1eafdcbdc6e2aa4c82fa7e081c0a502 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Fri, 5 Jul 2013 13:15:10 -0500 Subject: [PATCH 140/156] [feature/twig] context_recursive_loop_builder isn't used anymore, removing it PHPBB3-11598 --- phpBB/includes/template/twig/environment.php | 22 -------------------- 1 file changed, 22 deletions(-) diff --git a/phpBB/includes/template/twig/environment.php b/phpBB/includes/template/twig/environment.php index acb97cfad2..b60cd72325 100644 --- a/phpBB/includes/template/twig/environment.php +++ b/phpBB/includes/template/twig/environment.php @@ -137,26 +137,4 @@ class phpbb_template_twig_environment extends Twig_Environment 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!) - * @return null - */ - 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]); - } - } } From 8d11a147f5ab05443b243559f248e7e52e2e9faf Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Fri, 5 Jul 2013 14:10:57 -0500 Subject: [PATCH 141/156] [feature/twig] Use Twig mask for IF statements instead of our own tokenparser PHPBB3-11598 --- phpBB/includes/template/twig/extension.php | 1 - phpBB/includes/template/twig/lexer.php | 8 +- .../includes/template/twig/tokenparser/if.php | 87 ------------------- 3 files changed, 6 insertions(+), 90 deletions(-) delete mode 100644 phpBB/includes/template/twig/tokenparser/if.php diff --git a/phpBB/includes/template/twig/extension.php b/phpBB/includes/template/twig/extension.php index c4d36050f9..5ffc45e75a 100644 --- a/phpBB/includes/template/twig/extension.php +++ b/phpBB/includes/template/twig/extension.php @@ -54,7 +54,6 @@ class phpbb_template_twig_extension extends Twig_Extension public function getTokenParsers() { return array( - new phpbb_template_twig_tokenparser_if, new phpbb_template_twig_tokenparser_define, new phpbb_template_twig_tokenparser_include, new phpbb_template_twig_tokenparser_includejs, diff --git a/phpBB/includes/template/twig/lexer.php b/phpBB/includes/template/twig/lexer.php index 394c3077a6..5f76c44481 100644 --- a/phpBB/includes/template/twig/lexer.php +++ b/phpBB/includes/template/twig/lexer.php @@ -24,12 +24,12 @@ class phpbb_template_twig_lexer extends Twig_Lexer $phpbb_tags = array( /*'BEGIN', 'BEGINELSE', - 'END',*/ + 'END', 'IF', 'ELSE', 'ELSEIF', 'ENDIF', - /*'DEFINE', + 'DEFINE', 'UNDEFINE',*/ 'ENDDEFINE', 'INCLUDE', @@ -44,6 +44,10 @@ class phpbb_template_twig_lexer extends Twig_Lexer $twig_tags = array( 'autoescape', 'endautoescape', + 'if', + 'elseif', + 'else', + 'endif', 'block', 'endblock', 'use', diff --git a/phpBB/includes/template/twig/tokenparser/if.php b/phpBB/includes/template/twig/tokenparser/if.php deleted file mode 100644 index 77881ad5f0..0000000000 --- a/phpBB/includes/template/twig/tokenparser/if.php +++ /dev/null @@ -1,87 +0,0 @@ -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'; - } -} From 921d44aa4dfa307eb3b7e4f24befabb07e727812 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Fri, 5 Jul 2013 14:17:46 -0500 Subject: [PATCH 142/156] [feature/twig] Put $SCRIPTS below overall_footer_after, use includejs for core Moved below overall_footer_after so events can add JS files in that event. PHPBB3-11598 --- phpBB/styles/prosilver/template/overall_footer.html | 4 +++- phpBB/styles/subsilver2/template/overall_footer.html | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/phpBB/styles/prosilver/template/overall_footer.html b/phpBB/styles/prosilver/template/overall_footer.html index 5c88209ad8..eef9f53409 100644 --- a/phpBB/styles/prosilver/template/overall_footer.html +++ b/phpBB/styles/prosilver/template/overall_footer.html @@ -56,8 +56,10 @@ -{$SCRIPTS} + +{$SCRIPTS} + diff --git a/phpBB/styles/subsilver2/template/overall_footer.html b/phpBB/styles/subsilver2/template/overall_footer.html index 2d794d9f71..d2b30c22a0 100644 --- a/phpBB/styles/subsilver2/template/overall_footer.html +++ b/phpBB/styles/subsilver2/template/overall_footer.html @@ -13,9 +13,11 @@ - -{$SCRIPTS} + + +{$SCRIPTS} + From 0894a1377013965657f29a42202a630ba83daf95 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Sat, 6 Jul 2013 16:26:56 -0500 Subject: [PATCH 143/156] [feature/twig] If DEBUG, EVENT will always look for new/missing tpl event files If debug mode is enabled, lets check for new/removed EVENT templates on page load rather than at compile. This is slower, but makes developing extensions easier (no need to purge the cache when a new event template file is added) PHPBB3-11598 --- phpBB/includes/template/twig/node/event.php | 26 ++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/phpBB/includes/template/twig/node/event.php b/phpBB/includes/template/twig/node/event.php index 984ba35244..971dea14fa 100644 --- a/phpBB/includes/template/twig/node/event.php +++ b/phpBB/includes/template/twig/node/event.php @@ -43,17 +43,37 @@ class phpbb_template_twig_node_event extends Twig_Node { $ext_namespace = str_replace('/', '_', $ext_namespace); - if ($this->environment->getLoader()->exists('@' . $ext_namespace . '/' . $location . '.html')) + if (defined('DEBUG')) + { + // If debug mode is enabled, lets check for new/removed EVENT + // templates on page load rather than at compile. This is + // slower, but makes developing extensions easier (no need to + // purge the cache when a new event template file is added) + $compiler + ->write("if (\$this->env->getLoader()->exists('@{$ext_namespace}/{$location}.html')) {\n") + ->indent() + ; + } + + if (defined('DEBUG') || $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(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") ; } + + if (defined('DEBUG')) + { + $compiler + ->outdent() + ->write("}\n\n") + ; + } } } } From 70a553e0b5471c32469961be40e408bd544b670f Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Mon, 8 Jul 2013 15:16:37 -0500 Subject: [PATCH 144/156] [feature/twig] Variable regular expressions should be lazy PHPBB3-11598 --- phpBB/includes/template/twig/lexer.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/phpBB/includes/template/twig/lexer.php b/phpBB/includes/template/twig/lexer.php index 5f76c44481..d0a84a8b7f 100644 --- a/phpBB/includes/template/twig/lexer.php +++ b/phpBB/includes/template/twig/lexer.php @@ -98,15 +98,15 @@ class phpbb_template_twig_lexer extends Twig_Lexer // Replace all of our language variables, {L_VARNAME}, with Twig style, {{ lang('NAME') }} // Appends any filters after lang() - $code = preg_replace('#{L_([a-zA-Z0-9_\.]+)(\|[^}]+)?}#', '{{ lang(\'$1\')$2 }}', $code); + $code = preg_replace('#{L_([a-zA-Z0-9_\.]+)(\|[^}]+?)?}#', '{{ lang(\'$1\')$2 }}', $code); // Replace all of our escaped language variables, {LA_VARNAME}, with Twig style, {{ lang('NAME')|addslashes }} // Appends any filters after lang(), but before addslashes - $code = preg_replace('#{LA_([a-zA-Z0-9_\.]+)(\|[^}]+)?}#', '{{ lang(\'$1\')$2|addslashes }}', $code); + $code = preg_replace('#{LA_([a-zA-Z0-9_\.]+)(\|[^}]+?)?}#', '{{ lang(\'$1\')$2|addslashes }}', $code); // Replace all of our variables, {VARNAME}, with Twig style, {{ VARNAME }} // Appends any filters - $code = preg_replace('#{([a-zA-Z0-9_\.]+)(\|[^}]+)?}#', '{{ $1$2 }}', $code); + $code = preg_replace('#{([a-zA-Z0-9_\.]+)(\|[^}]+?)?}#', '{{ $1$2 }}', $code); return parent::tokenize($code, $filename); } From 47ec38c011f3d3d86dacdc3126fc36cdec8b1072 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Mon, 8 Jul 2013 15:18:40 -0500 Subject: [PATCH 145/156] [feature/twig] Add simple test to make sure Twig filters/tags are working PHPBB3-11598 --- tests/template/template_test.php | 7 +++++++ tests/template/templates/twig.html | 6 ++++++ tests/template/templates/twig_parent.html | 7 +++++++ 3 files changed, 20 insertions(+) create mode 100644 tests/template/templates/twig.html create mode 100644 tests/template/templates/twig_parent.html diff --git a/tests/template/template_test.php b/tests/template/template_test.php index d99e91bae4..fedfeba33a 100644 --- a/tests/template/template_test.php +++ b/tests/template/template_test.php @@ -309,6 +309,13 @@ class phpbb_template_template_test extends phpbb_template_template_test_case "a\nb\nc\nd", ), */ + array( + 'twig.html', + array('VARIABLE' => 'FOObar',), + array(), + array(), + "13FOOBAR|foobar", + ), ); } diff --git a/tests/template/templates/twig.html b/tests/template/templates/twig.html new file mode 100644 index 0000000000..17b94ad8d4 --- /dev/null +++ b/tests/template/templates/twig.html @@ -0,0 +1,6 @@ + + + +3{VARIABLE|upper}|{VARIABLE|lower} + + diff --git a/tests/template/templates/twig_parent.html b/tests/template/templates/twig_parent.html new file mode 100644 index 0000000000..af528e0da4 --- /dev/null +++ b/tests/template/templates/twig_parent.html @@ -0,0 +1,7 @@ + +1 + + + +2 + \ No newline at end of file From 9725eb19f8dbc124febe0189799c0b2af0215c63 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Wed, 10 Jul 2013 11:43:52 -0400 Subject: [PATCH 146/156] [feature/twig] Unit tests for includejs PHPBB3-11598 --- tests/template/template_includejs_test.php | 24 ++++++++++++++++------ tests/template/templates/includejs.html | 15 +++++++++++++- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/tests/template/template_includejs_test.php b/tests/template/template_includejs_test.php index a57b219150..0061163eeb 100644 --- a/tests/template/template_includejs_test.php +++ b/tests/template/template_includejs_test.php @@ -18,12 +18,24 @@ class phpbb_template_template_includejs_test extends phpbb_template_template_tes // Prepare correct result $scripts = array( - '', - '', - '', - '', - '', - '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', ); // Run test diff --git a/tests/template/templates/includejs.html b/tests/template/templates/includejs.html index 229f1ccc19..dd7b059f12 100644 --- a/tests/template/templates/includejs.html +++ b/tests/template/templates/includejs.html @@ -1,8 +1,21 @@ + + + + -{$SCRIPTS} + + + + + + + + + +{SCRIPTS} From ab5a79a823de50667798d4e49fc7758a3fd9f132 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Wed, 10 Jul 2013 13:19:34 -0500 Subject: [PATCH 147/156] [ticket/11388] includejs inherit from includeasset Copied from the INCLUDECSS PR, since this needed to be modified. Added checks for argument strings/anchors/http/https paths in asset files to load files properly PHPBB3-11388 --- .../template/twig/node/includeasset.php | 66 +++++++++++++++++++ .../includes/template/twig/node/includejs.php | 38 ++--------- 2 files changed, 73 insertions(+), 31 deletions(-) create mode 100644 phpBB/includes/template/twig/node/includeasset.php diff --git a/phpBB/includes/template/twig/node/includeasset.php b/phpBB/includes/template/twig/node/includeasset.php new file mode 100644 index 0000000000..181e3b5aa5 --- /dev/null +++ b/phpBB/includes/template/twig/node/includeasset.php @@ -0,0 +1,66 @@ +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); + + $config = $this->environment->get_phpbb_config(); + + $compiler + ->write("\$asset_file = ") + ->subcompile($this->getNode('expr')) + ->raw(";\n") + ->write("\$argument_string = '?assets_version={$config['assets_version']}';\n") + ->write("\$anchor_string = '';\n") + ->write("if ((\$argument_string_start = strpos(\$asset_file, '?')) !== false) {\n") + ->indent() + ->write("\$argument_string = substr(\$asset_file, \$argument_string_start);\n") + ->write("\$asset_file = substr(\$asset_file, 0, \$argument_string_start);\n") + ->write("if ((\$anchor_string_start = strpos(\$argument_string, '#')) !== false) {\n") + ->indent() + ->write("\$anchor_string = substr(\$argument_string, \$anchor_string_start);\n") + ->write("\$argument_string = substr(\$argument_string, 0, \$anchor_string_start);\n") + ->outdent() + ->write("}\n") + ->write("\$argument_string .= '&assets_version=" . $config['assets_version'] . "';\n") + ->outdent() + ->write("}\n") + ->write("if (strpos(\$asset_file, 'http://') !== 0 && strpos(\$asset_file, 'https://') !== 0 && !file_exists(\$asset_file)) {\n") + ->indent() + ->write("\$asset_file = \$this->getEnvironment()->getLoader()->getCacheKey(\$asset_file);\n") + ->outdent() + ->write("}\n") + ->write("\$asset_file .= \$argument_string . \$anchor_string;\n") + ->write("\$context['definition']->append('{$this->get_definition_name()}', '") + ; + + $this->append_asset($compiler); + + $compiler + ->raw("\n');\n") + ; + } +} diff --git a/phpBB/includes/template/twig/node/includejs.php b/phpBB/includes/template/twig/node/includejs.php index 943eb89ace..fdf2bea3ed 100644 --- a/phpBB/includes/template/twig/node/includejs.php +++ b/phpBB/includes/template/twig/node/includejs.php @@ -7,25 +7,11 @@ * */ -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) +class phpbb_template_twig_node_includejs extends phpbb_template_twig_node_includeasset { - exit; -} - - -class phpbb_template_twig_node_includejs extends Twig_Node -{ - /** @var Twig_Environment */ - protected $environment; - - public function __construct(Twig_Node_Expression $expr, phpbb_template_twig_environment $environment, $lineno, $tag = null) + public function get_definition_name() { - $this->environment = $environment; - - parent::__construct(array('expr' => $expr), array(), $lineno, $tag); + return 'SCRIPTS'; } /** @@ -33,24 +19,14 @@ class phpbb_template_twig_node_includejs extends Twig_Node * * @param Twig_Compiler A Twig_Compiler instance */ - public function compile(Twig_Compiler $compiler) + protected function append_asset(Twig_Compiler $compiler) { - $compiler->addDebugInfo($this); - $config = $this->environment->get_phpbb_config(); $compiler - ->write("\$js_file = ") - ->subcompile($this->getNode('expr')) - ->raw(";\n") - ->write("if (!file_exists(\$js_file)) {\n") - ->indent() - ->write("\$js_file = \$this->getEnvironment()->getLoader()->getCacheKey(\$js_file);\n") - ->outdent() - ->write("}\n") - ->write("\$context['definition']->append('SCRIPTS', '\n');\n") + ->raw("\n") ; } } From 8d8979eda76cba8e98e6428542db9aaf00edf2d8 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Wed, 10 Jul 2013 13:23:36 -0500 Subject: [PATCH 148/156] [ticket/11388] Fixing includejs test Changed expected output to file?(any supplied argument string)&asset_version =($config['asset_version'])#(any supplied anchor string) Testing lines one at a time to make checking them easier. PHPBB3-11388 --- tests/template/template_includejs_test.php | 105 ++++++++++++++++----- tests/template/templates/includejs.html | 57 ++++++----- 2 files changed, 118 insertions(+), 44 deletions(-) diff --git a/tests/template/template_includejs_test.php b/tests/template/template_includejs_test.php index 0061163eeb..b644c8b6f0 100644 --- a/tests/template/template_includejs_test.php +++ b/tests/template/template_includejs_test.php @@ -11,34 +11,93 @@ require_once dirname(__FILE__) . '/template_test_case_with_tree.php'; class phpbb_template_template_includejs_test extends phpbb_template_template_test_case_with_tree { - public function test_includejs_compilation() + public function template_data() + { + return array( + /* + array( + // vars + // expected + ), + */ + array( + array('TEST' => 1), + '', + ), + array( + array('TEST' => 2), + '', + ), + array( + array('TEST' => 3), + '', + ), + array( + array('TEST' => 4), + '', + ), + array( + array('TEST' => 5), + '', + ), + array( + array('TEST' => 6), + '', + ), + array( + array('TEST' => 7), + '', + ), + array( + array('TEST' => 8), + '', + ), + array( + array('TEST' => 9), + '', + ), + array( + array('TEST' => 10), + '', + ), + array( + array('TEST' => 11), + '', + ), + array( + array('TEST' => 12), + '', + ), + array( + array('TEST' => 13), + '', + ), + array( + array('TEST' => 14), + '', + ), + array( + array('TEST' => 15), + '', + ), + array( + array('TEST' => 16), + '', + ), + ); + } + + /** + * @dataProvider template_data + */ + public function test_includejs_compilation($vars, $expected) { // Reset the engine state $this->setup_engine(array('assets_version' => 1)); - // Prepare correct result - $scripts = array( - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - ); + $this->template->assign_vars($vars); // Run test - $this->run_template('includejs.html', array('PARENT' => 'parent_only.js', 'SUBDIR' => 'subdir', 'EXT' => 'js'), array(), array(), implode('', $scripts)); + $this->run_template('includejs.html', array_merge(array('PARENT' => 'parent_only.js', 'SUBDIR' => 'subdir', 'EXT' => 'js'), $vars), array(), array(), $expected); } } diff --git a/tests/template/templates/includejs.html b/tests/template/templates/includejs.html index dd7b059f12..030681337b 100644 --- a/tests/template/templates/includejs.html +++ b/tests/template/templates/includejs.html @@ -1,21 +1,36 @@ - - - - - - - - - - - - - - - - - - - - -{SCRIPTS} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{$SCRIPTS} From 99c7483ade84e492f7bffb72cc2463fce2f65b94 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 11 Jul 2013 08:36:16 -0500 Subject: [PATCH 149/156] [ticket/11388] INCLUDEJS supports //(url) PHPBB3-11388 --- phpBB/includes/template/twig/node/includeasset.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/template/twig/node/includeasset.php b/phpBB/includes/template/twig/node/includeasset.php index 181e3b5aa5..647ae22d81 100644 --- a/phpBB/includes/template/twig/node/includeasset.php +++ b/phpBB/includes/template/twig/node/includeasset.php @@ -48,7 +48,7 @@ class phpbb_template_twig_node_includeasset extends Twig_Node ->write("\$argument_string .= '&assets_version=" . $config['assets_version'] . "';\n") ->outdent() ->write("}\n") - ->write("if (strpos(\$asset_file, 'http://') !== 0 && strpos(\$asset_file, 'https://') !== 0 && !file_exists(\$asset_file)) {\n") + ->write("if (strpos(\$asset_file, '//') !== 0 && strpos(\$asset_file, 'http://') !== 0 && strpos(\$asset_file, 'https://') !== 0 && !file_exists(\$asset_file)) {\n") ->indent() ->write("\$asset_file = \$this->getEnvironment()->getLoader()->getCacheKey(\$asset_file);\n") ->outdent() From 648e1e51fad1c2198a30f62c50d7d2272134c399 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 11 Jul 2013 08:44:48 -0500 Subject: [PATCH 150/156] [ticket/11388] INCLUDEJS test for //(url) PHPBB3-11388 --- tests/template/template_includejs_test.php | 4 ++++ tests/template/templates/includejs.html | 2 ++ 2 files changed, 6 insertions(+) diff --git a/tests/template/template_includejs_test.php b/tests/template/template_includejs_test.php index b644c8b6f0..d4a384a1c5 100644 --- a/tests/template/template_includejs_test.php +++ b/tests/template/template_includejs_test.php @@ -84,6 +84,10 @@ class phpbb_template_template_includejs_test extends phpbb_template_template_tes array('TEST' => 16), '', ), + array( + array('TEST' => 17), + '', + ), ); } diff --git a/tests/template/templates/includejs.html b/tests/template/templates/includejs.html index 030681337b..3bcad76af5 100644 --- a/tests/template/templates/includejs.html +++ b/tests/template/templates/includejs.html @@ -32,5 +32,7 @@ + + {$SCRIPTS} From ac6b4319b3e59b1766e8e9278567a90cd3758882 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 11 Jul 2013 10:32:13 -0500 Subject: [PATCH 151/156] [ticket/11388] typehits PHPBB3-11388 --- phpBB/includes/template/twig/twig.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/template/twig/twig.php b/phpBB/includes/template/twig/twig.php index 621bfe0f4f..ae50124f5c 100644 --- a/phpBB/includes/template/twig/twig.php +++ b/phpBB/includes/template/twig/twig.php @@ -109,7 +109,7 @@ class phpbb_template_twig implements phpbb_template * @param phpbb_extension_manager $extension_manager extension manager, if null then template events will not be invoked * @param string $adm_relative_path relative path to adm directory */ - public function __construct($phpbb_root_path, $php_ext, $config, $user, phpbb_template_context $context, phpbb_extension_manager $extension_manager = null, $adm_relative_path = null) + public function __construct($phpbb_root_path, $php_ext, phpbb_config $config, phpbb_user $user, phpbb_template_context $context, phpbb_extension_manager $extension_manager = null, $adm_relative_path = null) { $this->phpbb_root_path = $phpbb_root_path; $this->adm_relative_path = $adm_relative_path; From bc4b5c87a9e899968a0f7af115fa1844348ddaac Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 11 Jul 2013 10:45:23 -0500 Subject: [PATCH 152/156] [ticket/11388] Do not modify by reference PHPBB3-11388 --- phpBB/includes/style/style.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/phpBB/includes/style/style.php b/phpBB/includes/style/style.php index 06c16fdef4..7001d10f21 100644 --- a/phpBB/includes/style/style.php +++ b/phpBB/includes/style/style.php @@ -132,12 +132,13 @@ class phpbb_style $this->provider->set_styles($paths); $this->locator->set_paths($this->provider); - foreach ($paths as &$path) + $new_paths = array(); + foreach ($paths as $path) { - $path .= '/template/'; + $new_paths = $path . '/template/'; } - $this->template->set_style_names($this->names, $paths, ($style_directories === array('styles'))); + $this->template->set_style_names($this->names, $new_paths1, ($style_directories === array('styles'))); return true; } @@ -174,12 +175,13 @@ class phpbb_style $this->locator->set_template_path($template_path); } - foreach ($paths as &$path) + $new_paths = array(); + foreach ($paths as $path) { - $path .= '/' . (($template_path !== false) ? $template_path : 'template/'); + $new_paths = $path . '/' . (($template_path !== false) ? $template_path : 'template/'); } - $this->template->set_style_names($names, $paths); + $this->template->set_style_names($names, $new_paths); return true; } From a846048918a0e54a01cfd8ea72bf383c354aac47 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 11 Jul 2013 11:03:28 -0500 Subject: [PATCH 153/156] [ticket/11388] Disable cache if IN_INSTALL defined PHPBB3-11388 --- phpBB/includes/template/twig/twig.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/template/twig/twig.php b/phpBB/includes/template/twig/twig.php index ae50124f5c..d5c12dc713 100644 --- a/phpBB/includes/template/twig/twig.php +++ b/phpBB/includes/template/twig/twig.php @@ -130,7 +130,7 @@ class phpbb_template_twig implements phpbb_template $this->phpbb_root_path, $loader, array( - 'cache' => $this->cachepath, + 'cache' => (defined('IN_INSTALL')) ? false : $this->cachepath, 'debug' => defined('DEBUG'), 'auto_reload' => (bool) $this->config['load_tplcompile'], 'autoescape' => false, From dd7f9f08d5b62f5060c89af92989451ca27de43b Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 11 Jul 2013 11:24:45 -0500 Subject: [PATCH 154/156] [ticket/11388] Remove typehints (causing tests to fail) PHPBB3-11388 --- phpBB/includes/template/twig/twig.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/template/twig/twig.php b/phpBB/includes/template/twig/twig.php index d5c12dc713..f5638972a3 100644 --- a/phpBB/includes/template/twig/twig.php +++ b/phpBB/includes/template/twig/twig.php @@ -109,7 +109,7 @@ class phpbb_template_twig implements phpbb_template * @param phpbb_extension_manager $extension_manager extension manager, if null then template events will not be invoked * @param string $adm_relative_path relative path to adm directory */ - public function __construct($phpbb_root_path, $php_ext, phpbb_config $config, phpbb_user $user, phpbb_template_context $context, phpbb_extension_manager $extension_manager = null, $adm_relative_path = null) + public function __construct($phpbb_root_path, $php_ext, $config, $user, phpbb_template_context $context, phpbb_extension_manager $extension_manager = null, $adm_relative_path = null) { $this->phpbb_root_path = $phpbb_root_path; $this->adm_relative_path = $adm_relative_path; From abd4159f87db8db5030afc439f072d6aa7b715e3 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 11 Jul 2013 11:26:38 -0500 Subject: [PATCH 155/156] [ticket/11388] Fix typo PHPBB3-11388 --- phpBB/includes/style/style.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/phpBB/includes/style/style.php b/phpBB/includes/style/style.php index 7001d10f21..034f518091 100644 --- a/phpBB/includes/style/style.php +++ b/phpBB/includes/style/style.php @@ -135,10 +135,10 @@ class phpbb_style $new_paths = array(); foreach ($paths as $path) { - $new_paths = $path . '/template/'; + $new_paths[] = $path . '/template/'; } - $this->template->set_style_names($this->names, $new_paths1, ($style_directories === array('styles'))); + $this->template->set_style_names($this->names, $new_paths, ($style_directories === array('styles'))); return true; } @@ -178,7 +178,7 @@ class phpbb_style $new_paths = array(); foreach ($paths as $path) { - $new_paths = $path . '/' . (($template_path !== false) ? $template_path : 'template/'); + $new_paths[] = $path . '/' . (($template_path !== false) ? $template_path : 'template/'); } $this->template->set_style_names($names, $new_paths); From 947b907efef43704c620507db17aff4fe115f219 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 11 Jul 2013 11:28:35 -0500 Subject: [PATCH 156/156] [ticket/11388] Do not append assets_version if using remote path (e.g. http) PHPBB3-11388 --- phpBB/includes/template/twig/node/includeasset.php | 5 ++--- tests/template/template_includejs_test.php | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/phpBB/includes/template/twig/node/includeasset.php b/phpBB/includes/template/twig/node/includeasset.php index 647ae22d81..5abff10e3f 100644 --- a/phpBB/includes/template/twig/node/includeasset.php +++ b/phpBB/includes/template/twig/node/includeasset.php @@ -33,8 +33,7 @@ class phpbb_template_twig_node_includeasset extends Twig_Node ->write("\$asset_file = ") ->subcompile($this->getNode('expr')) ->raw(";\n") - ->write("\$argument_string = '?assets_version={$config['assets_version']}';\n") - ->write("\$anchor_string = '';\n") + ->write("\$argument_string = \$anchor_string = '';\n") ->write("if ((\$argument_string_start = strpos(\$asset_file, '?')) !== false) {\n") ->indent() ->write("\$argument_string = substr(\$asset_file, \$argument_string_start);\n") @@ -45,12 +44,12 @@ class phpbb_template_twig_node_includeasset extends Twig_Node ->write("\$argument_string = substr(\$argument_string, 0, \$anchor_string_start);\n") ->outdent() ->write("}\n") - ->write("\$argument_string .= '&assets_version=" . $config['assets_version'] . "';\n") ->outdent() ->write("}\n") ->write("if (strpos(\$asset_file, '//') !== 0 && strpos(\$asset_file, 'http://') !== 0 && strpos(\$asset_file, 'https://') !== 0 && !file_exists(\$asset_file)) {\n") ->indent() ->write("\$asset_file = \$this->getEnvironment()->getLoader()->getCacheKey(\$asset_file);\n") + ->write("\$argument_string .= ((\$argument_string) ? '&' : '?') . 'assets_version={$config['assets_version']}';\n") ->outdent() ->write("}\n") ->write("\$asset_file .= \$argument_string . \$anchor_string;\n") diff --git a/tests/template/template_includejs_test.php b/tests/template/template_includejs_test.php index d4a384a1c5..ea5c30891b 100644 --- a/tests/template/template_includejs_test.php +++ b/tests/template/template_includejs_test.php @@ -78,15 +78,15 @@ class phpbb_template_template_includejs_test extends phpbb_template_template_tes ), array( array('TEST' => 15), - '', + '', ), array( array('TEST' => 16), - '', + '', ), array( array('TEST' => 17), - '', + '', ), ); }