mirror of
https://github.com/phpbb/phpbb.git
synced 2025-08-16 21:54:00 +02:00
Merge branch '3.2.x' into ticket/15068
This commit is contained in:
@@ -20,15 +20,20 @@ class asset
|
||||
/** @var \phpbb\path_helper **/
|
||||
protected $path_helper;
|
||||
|
||||
/** @var \phpbb\filesystem\filesystem */
|
||||
protected $filesystem;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $url URL
|
||||
* @param \phpbb\path_helper $path_helper Path helper object
|
||||
* @param \phpbb\filesystem\filesystem $filesystem
|
||||
*/
|
||||
public function __construct($url, \phpbb\path_helper $path_helper)
|
||||
public function __construct($url, \phpbb\path_helper $path_helper, \phpbb\filesystem\filesystem $filesystem)
|
||||
{
|
||||
$this->path_helper = $path_helper;
|
||||
$this->filesystem = $filesystem;
|
||||
|
||||
$this->set_url($url);
|
||||
}
|
||||
@@ -152,18 +157,18 @@ class asset
|
||||
*/
|
||||
public function set_path($path, $urlencode = false)
|
||||
{
|
||||
// Since 1.7.0 Twig returns the real path of the file. We need it to be relative to the working directory.
|
||||
$real_root_path = realpath($this->path_helper->get_phpbb_root_path()) . DIRECTORY_SEPARATOR;
|
||||
// Since 1.7.0 Twig returns the real path of the file. We need it to be relative.
|
||||
$real_root_path = $this->filesystem->realpath($this->path_helper->get_phpbb_root_path()) . DIRECTORY_SEPARATOR;
|
||||
|
||||
// If the asset is under the phpBB root path we need to remove its path and then prepend $phpbb_root_path
|
||||
if (substr($path . DIRECTORY_SEPARATOR, 0, strlen($real_root_path)) === $real_root_path)
|
||||
if ($real_root_path && substr($path . DIRECTORY_SEPARATOR, 0, strlen($real_root_path)) === $real_root_path)
|
||||
{
|
||||
$path = $this->path_helper->get_phpbb_root_path() . str_replace('\\', '/', substr($path, strlen($real_root_path)));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Else we make the path relative to the current working directory
|
||||
$real_root_path = realpath('.') . DIRECTORY_SEPARATOR;
|
||||
$real_root_path = $this->filesystem->realpath('.') . DIRECTORY_SEPARATOR;
|
||||
if ($real_root_path && substr($path . DIRECTORY_SEPARATOR, 0, strlen($real_root_path)) === $real_root_path)
|
||||
{
|
||||
$path = str_replace('\\', '/', substr($path, strlen($real_root_path)));
|
||||
|
95
phpBB/phpbb/template/assets_bag.php
Normal file
95
phpBB/phpbb/template/assets_bag.php
Normal file
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\template;
|
||||
|
||||
class assets_bag
|
||||
{
|
||||
/** @var asset[] */
|
||||
protected $stylesheets = [];
|
||||
|
||||
/** @var asset[] */
|
||||
protected $scripts = [];
|
||||
|
||||
/**
|
||||
* Add a css asset to the bag
|
||||
*
|
||||
* @param asset $asset
|
||||
*/
|
||||
public function add_stylesheet(asset $asset)
|
||||
{
|
||||
$this->stylesheets[] = $asset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a js script asset to the bag
|
||||
*
|
||||
* @param asset $asset
|
||||
*/
|
||||
public function add_script(asset $asset)
|
||||
{
|
||||
$this->scripts[] = $asset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all css assets
|
||||
*
|
||||
* @return asset[]
|
||||
*/
|
||||
public function get_stylesheets()
|
||||
{
|
||||
return $this->stylesheets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all js assets
|
||||
*
|
||||
* @return asset[]
|
||||
*/
|
||||
public function get_scripts()
|
||||
{
|
||||
return $this->scripts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTML code to includes all css assets
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_stylesheets_content()
|
||||
{
|
||||
$output = '';
|
||||
foreach ($this->stylesheets as $stylesheet)
|
||||
{
|
||||
$output .= "<link href=\"{$stylesheet->get_url()}\" rel=\"stylesheet\" type=\"text/css\" media=\"screen\" />\n";
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTML code to includes all js assets
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_scripts_content()
|
||||
{
|
||||
$output = '';
|
||||
foreach ($this->scripts as $script)
|
||||
{
|
||||
$output .= "<script type=\"text/javascript\" src=\"{$script->get_url()}\"></script>\n";
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
@@ -161,6 +161,14 @@ abstract class base implements template
|
||||
return $this->context->alter_block_array($blockname, $vararray, $key, $mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function find_key_index($blockname, $key)
|
||||
{
|
||||
return $this->context->find_key_index($blockname, $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls hook if any is defined.
|
||||
*
|
||||
|
@@ -336,6 +336,89 @@ class context
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the index for a specified key in the innermost specified block
|
||||
*
|
||||
* @param string $blockname the blockname, for example 'loop'
|
||||
* @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 search for]
|
||||
*
|
||||
* If key is false the position is set to 0
|
||||
* If key is true the position is set to the last entry
|
||||
*
|
||||
* @return mixed false if not found, index position otherwise; be sure to test with ===
|
||||
*/
|
||||
public function find_key_index($blockname, $key)
|
||||
{
|
||||
// For nested block, $blockcount > 0, for top-level block, $blockcount == 0
|
||||
$blocks = explode('.', $blockname);
|
||||
$blockcount = sizeof($blocks) - 1;
|
||||
|
||||
$block = $this->tpldata;
|
||||
for ($i = 0; $i < $blockcount; $i++)
|
||||
{
|
||||
if (($pos = strpos($blocks[$i], '[')) !== false)
|
||||
{
|
||||
$name = substr($blocks[$i], 0, $pos);
|
||||
|
||||
if (strpos($blocks[$i], '[]') === $pos)
|
||||
{
|
||||
$index = sizeof($block[$name]) - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$index = min((int) substr($blocks[$i], $pos + 1, -1), sizeof($block[$name]) - 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$name = $blocks[$i];
|
||||
$index = sizeof($block[$name]) - 1;
|
||||
}
|
||||
if (!isset($block[$name]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
$block = $block[$name];
|
||||
if (!isset($block[$index]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
$block = $block[$index];
|
||||
}
|
||||
|
||||
if (!isset($block[$blocks[$i]]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
$block = $block[$blocks[$i]]; // Traverse the last block
|
||||
|
||||
// Change key to zero (change first position) if false and to last position if true
|
||||
if ($key === false || $key === true)
|
||||
{
|
||||
return ($key === false) ? 0 : sizeof($block) - 1;
|
||||
}
|
||||
|
||||
// Get correct position if array given
|
||||
if (is_array($key))
|
||||
{
|
||||
// Search array to get correct position
|
||||
list($search_key, $search_value) = @each($key);
|
||||
foreach ($block as $i => $val_ary)
|
||||
{
|
||||
if ($val_ary[$search_key] === $search_value)
|
||||
{
|
||||
return $i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (is_int($key) && ((0 <= $key) && ($key < sizeof($block)))) ? $key : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change already assigned key variable pair (one-dimensional - single loop entry)
|
||||
*
|
||||
@@ -366,45 +449,49 @@ class context
|
||||
public function alter_block_array($blockname, array $vararray, $key = false, $mode = 'insert')
|
||||
{
|
||||
$this->num_rows_is_set = false;
|
||||
if (strpos($blockname, '.') !== false)
|
||||
|
||||
// For nested block, $blockcount > 0, for top-level block, $blockcount == 0
|
||||
$blocks = explode('.', $blockname);
|
||||
$blockcount = sizeof($blocks) - 1;
|
||||
|
||||
$block = &$this->tpldata;
|
||||
for ($i = 0; $i < $blockcount; $i++)
|
||||
{
|
||||
// Nested block.
|
||||
$blocks = explode('.', $blockname);
|
||||
$blockcount = sizeof($blocks) - 1;
|
||||
|
||||
$block = &$this->tpldata;
|
||||
for ($i = 0; $i < $blockcount; $i++)
|
||||
if (($pos = strpos($blocks[$i], '[')) !== false)
|
||||
{
|
||||
if (($pos = strpos($blocks[$i], '[')) !== false)
|
||||
{
|
||||
$name = substr($blocks[$i], 0, $pos);
|
||||
$name = substr($blocks[$i], 0, $pos);
|
||||
|
||||
if (strpos($blocks[$i], '[]') === $pos)
|
||||
{
|
||||
$index = sizeof($block[$name]) - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$index = min((int) substr($blocks[$i], $pos + 1, -1), sizeof($block[$name]) - 1);
|
||||
}
|
||||
if (strpos($blocks[$i], '[]') === $pos)
|
||||
{
|
||||
$index = sizeof($block[$name]) - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$name = $blocks[$i];
|
||||
$index = sizeof($block[$name]) - 1;
|
||||
$index = min((int) substr($blocks[$i], $pos + 1, -1), sizeof($block[$name]) - 1);
|
||||
}
|
||||
$block = &$block[$name];
|
||||
$block = &$block[$index];
|
||||
}
|
||||
else
|
||||
{
|
||||
$name = $blocks[$i];
|
||||
$index = sizeof($block[$name]) - 1;
|
||||
}
|
||||
$block = &$block[$name];
|
||||
$block = &$block[$index];
|
||||
}
|
||||
$name = $blocks[$i];
|
||||
|
||||
$block = &$block[$blocks[$i]]; // Traverse the last block
|
||||
}
|
||||
else
|
||||
// If last block does not exist and we are inserting, and not searching for key, we create it empty; otherwise, nothing to do
|
||||
if (!isset($block[$name]))
|
||||
{
|
||||
// Top-level block.
|
||||
$block = &$this->tpldata[$blockname];
|
||||
if ($mode != 'insert' || is_array($key))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
$block[$name] = array();
|
||||
}
|
||||
|
||||
$block = &$block[$name]; // Now we can traverse the last block
|
||||
|
||||
// Change key to zero (change first position) if false and to last position if true
|
||||
if ($key === false || $key === true)
|
||||
{
|
||||
@@ -438,20 +525,21 @@ class context
|
||||
if ($mode == 'insert')
|
||||
{
|
||||
// Make sure we are not exceeding the last iteration
|
||||
if ($key >= sizeof($this->tpldata[$blockname]))
|
||||
if ($key >= sizeof($block))
|
||||
{
|
||||
$key = sizeof($this->tpldata[$blockname]);
|
||||
unset($this->tpldata[$blockname][($key - 1)]['S_LAST_ROW']);
|
||||
$key = sizeof($block);
|
||||
unset($block[($key - 1)]['S_LAST_ROW']);
|
||||
$vararray['S_LAST_ROW'] = true;
|
||||
}
|
||||
else if ($key === 0)
|
||||
if ($key <= 0)
|
||||
{
|
||||
unset($this->tpldata[$blockname][0]['S_FIRST_ROW']);
|
||||
$key = 0;
|
||||
unset($block[0]['S_FIRST_ROW']);
|
||||
$vararray['S_FIRST_ROW'] = true;
|
||||
}
|
||||
|
||||
// Assign S_BLOCK_NAME
|
||||
$vararray['S_BLOCK_NAME'] = $blockname;
|
||||
$vararray['S_BLOCK_NAME'] = $name;
|
||||
|
||||
// Re-position template blocks
|
||||
for ($i = sizeof($block); $i > $key; $i--)
|
||||
@@ -471,6 +559,12 @@ class context
|
||||
// Which block to change?
|
||||
if ($mode == 'change')
|
||||
{
|
||||
// If key is out of bounds, do not change anything
|
||||
if ($key > sizeof($block) || $key < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($key == sizeof($block))
|
||||
{
|
||||
$key--;
|
||||
|
22
phpBB/phpbb/template/exception/user_object_not_available.php
Normal file
22
phpBB/phpbb/template/exception/user_object_not_available.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\template\exception;
|
||||
|
||||
/**
|
||||
* This exception is thrown when the user object was not set but it is required by the called method
|
||||
*/
|
||||
class user_object_not_available extends \phpbb\exception\runtime_exception
|
||||
{
|
||||
|
||||
}
|
@@ -196,6 +196,23 @@ interface template
|
||||
*/
|
||||
public function alter_block_array($blockname, array $vararray, $key = false, $mode = 'insert');
|
||||
|
||||
/**
|
||||
* Find the index for a specified key in the innermost specified block
|
||||
*
|
||||
* @param string $blockname the blockname, for example 'loop'
|
||||
* @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 search for]
|
||||
*
|
||||
* If key is false the position is set to 0
|
||||
* If key is true the position is set to the last entry
|
||||
*
|
||||
* @return mixed false if not found, index position otherwise; be sure to test with ===
|
||||
*/
|
||||
public function find_key_index($blockname, $key);
|
||||
|
||||
/**
|
||||
* Get path to template for handle (required for BBCode parser)
|
||||
*
|
||||
|
@@ -13,14 +13,22 @@
|
||||
|
||||
namespace phpbb\template\twig;
|
||||
|
||||
use phpbb\template\assets_bag;
|
||||
|
||||
class environment extends \Twig_Environment
|
||||
{
|
||||
/** @var \phpbb\config\config */
|
||||
protected $phpbb_config;
|
||||
|
||||
/** @var \phpbb\filesystem\filesystem */
|
||||
protected $filesystem;
|
||||
|
||||
/** @var \phpbb\path_helper */
|
||||
protected $phpbb_path_helper;
|
||||
|
||||
/** @var \Symfony\Component\DependencyInjection\ContainerInterface */
|
||||
protected $container;
|
||||
|
||||
/** @var \phpbb\extension\manager */
|
||||
protected $extension_manager;
|
||||
|
||||
@@ -33,26 +41,41 @@ class environment extends \Twig_Environment
|
||||
/** @var array **/
|
||||
protected $namespace_look_up_order = array('__main__');
|
||||
|
||||
/** @var assets_bag */
|
||||
protected $assets_bag;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param \phpbb\config\config $phpbb_config The phpBB configuration
|
||||
* @param \phpbb\filesystem\filesystem $filesystem
|
||||
* @param \phpbb\path_helper $path_helper phpBB path helper
|
||||
* @param string $cache_path The path to the cache directory
|
||||
* @param \phpbb\extension\manager $extension_manager phpBB extension manager
|
||||
* @param \Twig_LoaderInterface $loader Twig loader interface
|
||||
* @param array $options Array of options to pass to Twig
|
||||
*/
|
||||
public function __construct($phpbb_config, \phpbb\path_helper $path_helper, \phpbb\extension\manager $extension_manager = null, \Twig_LoaderInterface $loader = null, $options = array())
|
||||
public function __construct(\phpbb\config\config $phpbb_config, \phpbb\filesystem\filesystem $filesystem, \phpbb\path_helper $path_helper, $cache_path, \phpbb\extension\manager $extension_manager = null, \Twig_LoaderInterface $loader = null, $options = array())
|
||||
{
|
||||
$this->phpbb_config = $phpbb_config;
|
||||
|
||||
$this->filesystem = $filesystem;
|
||||
$this->phpbb_path_helper = $path_helper;
|
||||
$this->extension_manager = $extension_manager;
|
||||
|
||||
$this->phpbb_root_path = $this->phpbb_path_helper->get_phpbb_root_path();
|
||||
$this->web_root_path = $this->phpbb_path_helper->get_web_root_path();
|
||||
|
||||
return parent::__construct($loader, $options);
|
||||
$this->assets_bag = new assets_bag();
|
||||
|
||||
$options = array_merge(array(
|
||||
'cache' => (defined('IN_INSTALL')) ? false : $cache_path,
|
||||
'debug' => false,
|
||||
'auto_reload' => (bool) $this->phpbb_config['load_tplcompile'],
|
||||
'autoescape' => false,
|
||||
), $options);
|
||||
|
||||
parent::__construct($loader, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,15 +101,25 @@ class environment extends \Twig_Environment
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the phpBB root path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
* Get the phpBB root path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_phpbb_root_path()
|
||||
{
|
||||
return $this->phpbb_root_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the filesystem object
|
||||
*
|
||||
* @return \phpbb\filesystem\filesystem
|
||||
*/
|
||||
public function get_filesystem()
|
||||
{
|
||||
return $this->filesystem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the web root path
|
||||
*
|
||||
@@ -107,6 +140,16 @@ class environment extends \Twig_Environment
|
||||
return $this->phpbb_path_helper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the assets bag
|
||||
*
|
||||
* @return assets_bag
|
||||
*/
|
||||
public function get_assets_bag()
|
||||
{
|
||||
return $this->assets_bag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the namespace look up order
|
||||
*
|
||||
@@ -130,6 +173,55 @@ class environment extends \Twig_Environment
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function render($name, array $context = [])
|
||||
{
|
||||
return $this->display_with_assets($name, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function display($name, array $context = [])
|
||||
{
|
||||
echo $this->display_with_assets($name, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
private function display_with_assets($name, array $context = [])
|
||||
{
|
||||
$placeholder_salt = unique_id();
|
||||
|
||||
if (array_key_exists('definition', $context))
|
||||
{
|
||||
$context['definition']->set('SCRIPTS', '__SCRIPTS_' . $placeholder_salt . '__');
|
||||
$context['definition']->set('STYLESHEETS', '__STYLESHEETS_' . $placeholder_salt . '__');
|
||||
}
|
||||
|
||||
$output = parent::render($name, $context);
|
||||
|
||||
return $this->inject_assets($output, $placeholder_salt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Injects the assets (from INCLUDECSS/JS) in the output.
|
||||
*
|
||||
* @param string $output
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function inject_assets($output, $placeholder_salt)
|
||||
{
|
||||
$output = str_replace('__STYLESHEETS_' . $placeholder_salt . '__', $this->assets_bag->get_stylesheets_content(), $output);
|
||||
$output = str_replace('__SCRIPTS_' . $placeholder_salt . '__', $this->assets_bag->get_scripts_content(), $output);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a template by name.
|
||||
*
|
||||
|
@@ -18,20 +18,20 @@ class extension extends \Twig_Extension
|
||||
/** @var \phpbb\template\context */
|
||||
protected $context;
|
||||
|
||||
/** @var \phpbb\user */
|
||||
protected $user;
|
||||
/** @var \phpbb\language\language */
|
||||
protected $language;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param \phpbb\template\context $context
|
||||
* @param \phpbb\user $user
|
||||
* @param \phpbb\language\language $language
|
||||
* @return \phpbb\template\twig\extension
|
||||
*/
|
||||
public function __construct(\phpbb\template\context $context, $user)
|
||||
public function __construct(\phpbb\template\context $context, $language)
|
||||
{
|
||||
$this->context = $context;
|
||||
$this->user = $user;
|
||||
$this->language = $language;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,6 +71,7 @@ class extension extends \Twig_Extension
|
||||
{
|
||||
return array(
|
||||
new \Twig_SimpleFilter('subset', array($this, 'loop_subset'), array('needs_environment' => true)),
|
||||
// @deprecated 3.2.0 Uses twig's JS escape method instead of addslashes
|
||||
new \Twig_SimpleFilter('addslashes', 'addslashes'),
|
||||
);
|
||||
}
|
||||
@@ -169,17 +170,16 @@ class extension extends \Twig_Extension
|
||||
$args = func_get_args();
|
||||
$key = $args[0];
|
||||
|
||||
$context = $this->context->get_data_ref();
|
||||
$context_vars = $context['.'][0];
|
||||
$context_vars = $this->context->get_root_ref();
|
||||
|
||||
if (isset($context_vars['L_' . $key]))
|
||||
{
|
||||
return $context_vars['L_' . $key];
|
||||
}
|
||||
|
||||
// LA_ is transformed into lang(\'$1\')|addslashes, so we should not
|
||||
// LA_ is transformed into lang(\'$1\')|escape('js'), so we should not
|
||||
// need to check for it
|
||||
|
||||
return call_user_func_array(array($this->user, 'lang'), $args);
|
||||
return call_user_func_array(array($this->language, 'lang'), $args);
|
||||
}
|
||||
}
|
||||
|
43
phpBB/phpbb/template/twig/extension/routing.php
Normal file
43
phpBB/phpbb/template/twig/extension/routing.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\template\twig\extension;
|
||||
|
||||
use Symfony\Bridge\Twig\Extension\RoutingExtension;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
|
||||
class routing extends RoutingExtension
|
||||
{
|
||||
/** @var \phpbb\controller\helper */
|
||||
protected $helper;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param \phpbb\routing\helper $helper
|
||||
*/
|
||||
public function __construct(\phpbb\routing\helper $helper)
|
||||
{
|
||||
$this->helper = $helper;
|
||||
}
|
||||
|
||||
public function getPath($name, $parameters = array(), $relative = false)
|
||||
{
|
||||
return $this->helper->route($name, $parameters, true, false, $relative ? UrlGeneratorInterface::RELATIVE_PATH : UrlGeneratorInterface::ABSOLUTE_PATH);
|
||||
}
|
||||
|
||||
public function getUrl($name, $parameters = array(), $schemeRelative = false)
|
||||
{
|
||||
return $this->helper->route($name, $parameters, true, false, $schemeRelative ? UrlGeneratorInterface::NETWORK_PATH : UrlGeneratorInterface::ABSOLUTE_URL);
|
||||
}
|
||||
}
|
@@ -15,6 +15,11 @@ namespace phpbb\template\twig;
|
||||
|
||||
class lexer extends \Twig_Lexer
|
||||
{
|
||||
public function set_environment(\Twig_Environment $env)
|
||||
{
|
||||
$this->env = $env;
|
||||
}
|
||||
|
||||
public function tokenize($code, $filename = null)
|
||||
{
|
||||
// Our phpBB tags
|
||||
@@ -112,9 +117,9 @@ class lexer extends \Twig_Lexer
|
||||
// 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 }}
|
||||
// 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 escaped language variables, {LA_VARNAME}, with Twig style, {{ lang('NAME')|escape('js') }}
|
||||
// Appends any filters after lang(), but before escape('js')
|
||||
$code = preg_replace('#{LA_([a-zA-Z0-9_\.]+)(\|[^}]+?)?}#', '{{ lang(\'$1\')$2|escape(\'js\') }}', $code);
|
||||
|
||||
// Replace all of our variables, {VARNAME}, with Twig style, {{ VARNAME }}
|
||||
// Appends any filters
|
||||
|
@@ -20,6 +20,24 @@ class loader extends \Twig_Loader_Filesystem
|
||||
{
|
||||
protected $safe_directories = array();
|
||||
|
||||
/**
|
||||
* @var \phpbb\filesystem\filesystem_interface
|
||||
*/
|
||||
protected $filesystem;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param \phpbb\filesystem\filesystem_interface $filesystem
|
||||
* @param string|array $paths
|
||||
*/
|
||||
public function __construct(\phpbb\filesystem\filesystem_interface $filesystem, $paths = array())
|
||||
{
|
||||
$this->filesystem = $filesystem;
|
||||
|
||||
parent::__construct($paths);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set safe directories
|
||||
*
|
||||
@@ -49,7 +67,7 @@ class loader extends \Twig_Loader_Filesystem
|
||||
*/
|
||||
public function addSafeDirectory($directory)
|
||||
{
|
||||
$directory = phpbb_realpath($directory);
|
||||
$directory = $this->filesystem->realpath($directory);
|
||||
|
||||
if ($directory !== false)
|
||||
{
|
||||
@@ -82,6 +100,16 @@ class loader extends \Twig_Loader_Filesystem
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a realpath call to fix a BC break in Twig 1.26 (https://github.com/twigphp/Twig/issues/2145)
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addPath($path, $namespace = self::MAIN_NAMESPACE)
|
||||
{
|
||||
return parent::addPath($this->filesystem->realpath($path), $namespace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the template
|
||||
*
|
||||
@@ -119,7 +147,7 @@ class loader extends \Twig_Loader_Filesystem
|
||||
// can now check if we're within a "safe" directory
|
||||
|
||||
// Find the real path of the directory the file is in
|
||||
$directory = phpbb_realpath(dirname($file));
|
||||
$directory = $this->filesystem->realpath(dirname($file));
|
||||
|
||||
if ($directory === false)
|
||||
{
|
||||
|
@@ -46,7 +46,7 @@ class event extends \Twig_Node
|
||||
{
|
||||
$ext_namespace = str_replace('/', '_', $ext_namespace);
|
||||
|
||||
if (defined('DEBUG'))
|
||||
if ($this->environment->isDebug())
|
||||
{
|
||||
// If debug mode is enabled, lets check for new/removed EVENT
|
||||
// templates on page load rather than at compile. This is
|
||||
@@ -58,7 +58,7 @@ class event extends \Twig_Node
|
||||
;
|
||||
}
|
||||
|
||||
if (defined('DEBUG') || $this->environment->getLoader()->exists('@' . $ext_namespace . '/' . $location . '.html'))
|
||||
if ($this->environment->isDebug() || $this->environment->getLoader()->exists('@' . $ext_namespace . '/' . $location . '.html'))
|
||||
{
|
||||
$compiler
|
||||
->write("\$previous_look_up_order = \$this->env->getNamespaceLookUpOrder();\n")
|
||||
@@ -70,7 +70,7 @@ class event extends \Twig_Node
|
||||
;
|
||||
}
|
||||
|
||||
if (defined('DEBUG'))
|
||||
if ($this->environment->isDebug())
|
||||
{
|
||||
$compiler
|
||||
->outdent()
|
||||
|
@@ -39,7 +39,7 @@ abstract class includeasset extends \Twig_Node
|
||||
->write("\$asset_file = ")
|
||||
->subcompile($this->getNode('expr'))
|
||||
->raw(";\n")
|
||||
->write("\$asset = new \phpbb\\template\\asset(\$asset_file, \$this->getEnvironment()->get_path_helper());\n")
|
||||
->write("\$asset = new \phpbb\\template\\asset(\$asset_file, \$this->getEnvironment()->get_path_helper(), \$this->getEnvironment()->get_filesystem());\n")
|
||||
->write("if (substr(\$asset_file, 0, 2) !== './' && \$asset->is_relative()) {\n")
|
||||
->indent()
|
||||
->write("\$asset_path = \$asset->get_path();")
|
||||
@@ -49,33 +49,18 @@ abstract class includeasset extends \Twig_Node
|
||||
->write("\$local_file = \$this->getEnvironment()->findTemplate(\$asset_path);\n")
|
||||
->write("\$asset->set_path(\$local_file, true);\n")
|
||||
->outdent()
|
||||
->write("\$asset->add_assets_version('{$config['assets_version']}');\n")
|
||||
->write("\$asset_file = \$asset->get_url();\n")
|
||||
->write("}\n")
|
||||
->write("\$asset->add_assets_version('{$config['assets_version']}');\n")
|
||||
->outdent()
|
||||
->write("}\n")
|
||||
->write("\$context['definition']->append('{$this->get_definition_name()}', '")
|
||||
;
|
||||
|
||||
$this->append_asset($compiler);
|
||||
|
||||
$compiler
|
||||
->raw("\n');\n")
|
||||
->write("\$this->getEnvironment()->get_assets_bag()->add_{$this->get_setters_name()}(\$asset);")
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the definition name
|
||||
* Get the name of the assets bag setter
|
||||
*
|
||||
* @return string (e.g. 'SCRIPTS')
|
||||
* @return string (e.g. 'script')
|
||||
*/
|
||||
abstract public function get_definition_name();
|
||||
|
||||
/**
|
||||
* Append the output code for the asset
|
||||
*
|
||||
* @param \Twig_Compiler A Twig_Compiler instance
|
||||
* @return null
|
||||
*/
|
||||
abstract protected function append_asset(\Twig_Compiler $compiler);
|
||||
abstract public function get_setters_name();
|
||||
}
|
||||
|
@@ -18,20 +18,8 @@ class includecss extends \phpbb\template\twig\node\includeasset
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get_definition_name()
|
||||
public function get_setters_name()
|
||||
{
|
||||
return 'STYLESHEETS';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function append_asset(\Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->raw("<link href=\"' . ")
|
||||
->raw("\$asset_file . '\"")
|
||||
->raw(' rel="stylesheet" type="text/css" media="screen" />')
|
||||
;
|
||||
return 'stylesheet';
|
||||
}
|
||||
}
|
||||
|
@@ -18,22 +18,8 @@ class includejs extends \phpbb\template\twig\node\includeasset
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get_definition_name()
|
||||
public function get_setters_name()
|
||||
{
|
||||
return 'SCRIPTS';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function append_asset(\Twig_Compiler $compiler)
|
||||
{
|
||||
$config = $this->environment->get_phpbb_config();
|
||||
|
||||
$compiler
|
||||
->raw("<script type=\"text/javascript\" src=\"' . ")
|
||||
->raw("\$asset_file")
|
||||
->raw(". '\"></script>\n")
|
||||
;
|
||||
return 'script';
|
||||
}
|
||||
}
|
||||
|
@@ -13,6 +13,8 @@
|
||||
|
||||
namespace phpbb\template\twig;
|
||||
|
||||
use phpbb\template\exception\user_object_not_available;
|
||||
|
||||
/**
|
||||
* Twig Template class.
|
||||
*/
|
||||
@@ -76,11 +78,14 @@ class twig extends \phpbb\template\base
|
||||
*
|
||||
* @param \phpbb\path_helper $path_helper
|
||||
* @param \phpbb\config\config $config
|
||||
* @param \phpbb\user $user
|
||||
* @param \phpbb\template\context $context template context
|
||||
* @param \phpbb\template\twig\environment $twig_environment
|
||||
* @param string $cache_path
|
||||
* @param \phpbb\user|null $user
|
||||
* @param array|\ArrayAccess $extensions
|
||||
* @param \phpbb\extension\manager $extension_manager extension manager, if null then template events will not be invoked
|
||||
*/
|
||||
public function __construct(\phpbb\path_helper $path_helper, $config, $user, \phpbb\template\context $context, \phpbb\extension\manager $extension_manager = null)
|
||||
public function __construct(\phpbb\path_helper $path_helper, $config, \phpbb\template\context $context, \phpbb\template\twig\environment $twig_environment, $cache_path, \phpbb\user $user = null, $extensions = array(), \phpbb\extension\manager $extension_manager = null)
|
||||
{
|
||||
$this->path_helper = $path_helper;
|
||||
$this->phpbb_root_path = $path_helper->get_phpbb_root_path();
|
||||
@@ -89,41 +94,14 @@ class twig extends \phpbb\template\base
|
||||
$this->user = $user;
|
||||
$this->context = $context;
|
||||
$this->extension_manager = $extension_manager;
|
||||
$this->cachepath = $cache_path;
|
||||
$this->twig = $twig_environment;
|
||||
|
||||
$this->cachepath = $this->phpbb_root_path . 'cache/twig/';
|
||||
|
||||
// Initiate the loader, __main__ namespace paths will be setup later in set_style_names()
|
||||
$loader = new \phpbb\template\twig\loader('');
|
||||
|
||||
$this->twig = new \phpbb\template\twig\environment(
|
||||
$this->config,
|
||||
$this->path_helper,
|
||||
$this->extension_manager,
|
||||
$loader,
|
||||
array(
|
||||
'cache' => (defined('IN_INSTALL')) ? false : $this->cachepath,
|
||||
'debug' => defined('DEBUG'),
|
||||
'auto_reload' => (bool) $this->config['load_tplcompile'],
|
||||
'autoescape' => false,
|
||||
)
|
||||
);
|
||||
|
||||
$this->twig->addExtension(
|
||||
new \phpbb\template\twig\extension(
|
||||
$this->context,
|
||||
$this->user
|
||||
)
|
||||
);
|
||||
|
||||
if (defined('DEBUG'))
|
||||
foreach ($extensions as $extension)
|
||||
{
|
||||
$this->twig->addExtension(new \Twig_Extension_Debug());
|
||||
$this->twig->addExtension($extension);
|
||||
}
|
||||
|
||||
$lexer = new \phpbb\template\twig\lexer($this->twig);
|
||||
|
||||
$this->twig->setLexer($lexer);
|
||||
|
||||
// Add admin namespace
|
||||
if ($this->path_helper->get_adm_relative_path() !== null && is_dir($this->phpbb_root_path . $this->path_helper->get_adm_relative_path() . 'style/'))
|
||||
{
|
||||
@@ -150,9 +128,16 @@ class twig extends \phpbb\template\base
|
||||
* Get the style tree of the style preferred by the current user
|
||||
*
|
||||
* @return array Style tree, most specific first
|
||||
*
|
||||
* @throws \phpbb\template\exception\user_object_not_available When user service was not set
|
||||
*/
|
||||
public function get_user_style()
|
||||
{
|
||||
if ($this->user === null)
|
||||
{
|
||||
throw new user_object_not_available();
|
||||
}
|
||||
|
||||
$style_list = array(
|
||||
$this->user->style['style_path'],
|
||||
);
|
||||
@@ -368,14 +353,24 @@ class twig extends \phpbb\template\base
|
||||
$context_vars['.'][0], // To get normal vars
|
||||
array(
|
||||
'definition' => new \phpbb\template\twig\definition(),
|
||||
'user' => $this->user,
|
||||
'loops' => $context_vars, // To get loops
|
||||
)
|
||||
);
|
||||
|
||||
if ($this->user instanceof \phpbb\user)
|
||||
{
|
||||
$vars['user'] = $this->user;
|
||||
}
|
||||
|
||||
// cleanup
|
||||
unset($vars['loops']['.']);
|
||||
|
||||
// Inject in the main context the value added by assign_block_vars() to be able to use directly the Twig loops.
|
||||
foreach ($vars['loops'] as $key => &$value)
|
||||
{
|
||||
$vars[$key] = $value;
|
||||
}
|
||||
|
||||
return $vars;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user