aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/includes/style
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB/includes/style')
-rw-r--r--phpBB/includes/style/resource_locator.php82
-rw-r--r--phpBB/includes/style/style.php28
-rw-r--r--phpBB/includes/style/template.php57
-rw-r--r--phpBB/includes/style/template_compile.php18
-rw-r--r--phpBB/includes/style/template_filter.php61
5 files changed, 233 insertions, 13 deletions
diff --git a/phpBB/includes/style/resource_locator.php b/phpBB/includes/style/resource_locator.php
index 39505cedb5..3e6dd5d6aa 100644
--- a/phpBB/includes/style/resource_locator.php
+++ b/phpBB/includes/style/resource_locator.php
@@ -185,9 +185,12 @@ class phpbb_style_resource_locator
* handle to a path without any filesystem or styles tree checks.
*
* @param string $handle Template handle (i.e. "friendly" template name)
+ * @param bool $find_all If true, each root path will be checked and function
+ * will return array of files instead of string and will not
+ * trigger a error if template does not exist
* @return string Source file path
*/
- public function get_source_file_for_handle($handle)
+ public function get_source_file_for_handle($handle, $find_all = false)
{
// If we don't have a file assigned to this handle, die.
if (!isset($this->files['style'][0][$handle]))
@@ -198,20 +201,91 @@ class phpbb_style_resource_locator
// locate a source file that exists
$source_file = $this->files['style'][0][$handle];
$tried = $source_file;
+ $found = false;
+ $found_all = array();
foreach ($this->roots as $root_key => $root_paths)
{
foreach ($root_paths as $root_index => $root)
{
$source_file = $this->files[$root_key][$root_index][$handle];
+ $tried .= ', ' . $source_file;
if (file_exists($source_file))
{
- return $source_file;
+ $found = true;
+ break;
+ }
+ }
+ if ($found)
+ {
+ if ($find_all)
+ {
+ $found_all[] = $source_file;
+ $found = false;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+
+ // search failed
+ if (!$found && !$find_all)
+ {
+ trigger_error("style resource locator: File for handle $handle does not exist. Could not find: $tried", E_USER_ERROR);
+ }
+
+ return ($find_all) ? $found_all : $source_file;
+ }
+
+ /**
+ * Locates source file path, accounting for styles tree and verifying that
+ * the path exists.
+ *
+ * Unlike previous functions, this function works without template handle
+ * and it can search for more than one file. If more than one file name is
+ * specified, it will return location of file that it finds first.
+ *
+ * @param array $files List of files to locate.
+ * @param bool $return_default Determines what to return if file does not
+ * exist. If true, function will return location where file is
+ * supposed to be. If false, function will return false.
+ * @param bool $return_full_path If true, function will return full path
+ * to file. If false, function will return file name. This
+ * parameter can be used to check which one of set of files
+ * is available.
+ * @return string or boolean Source file path if file exists or $return_default is
+ * true. False if file does not exist and $return_default is false
+ */
+ public function get_first_file_location($files, $return_default = false, $return_full_path = true)
+ {
+ // set default value
+ $default_result = false;
+
+ // check all available paths
+ foreach ($this->roots as $root_paths)
+ {
+ foreach ($root_paths as $path)
+ {
+ // check all files
+ foreach ($files as $filename)
+ {
+ $source_file = $path . '/' . $filename;
+ if (file_exists($source_file))
+ {
+ return ($return_full_path) ? $source_file : $filename;
+ }
+
+ // assign first file as result if $return_default is true
+ if ($return_default && $default_result === false)
+ {
+ $default_result = $source_file;
+ }
}
- $tried .= ', ' . $source_file;
}
}
// search failed
- trigger_error("style resource locator: File for handle $handle does not exist. Could not find: $tried", E_USER_ERROR);
+ return $default_result;
}
}
diff --git a/phpBB/includes/style/style.php b/phpBB/includes/style/style.php
index dc1e71dff6..5ac61c9f10 100644
--- a/phpBB/includes/style/style.php
+++ b/phpBB/includes/style/style.php
@@ -150,4 +150,32 @@ class phpbb_style
{
$this->provider->set_ext_dir_prefix($ext_dir_prefix);
}
+
+ /**
+ * Locates source file path, accounting for styles tree and verifying that
+ * the path exists.
+ *
+ * @param string or array $files List of files to locate. If there is only
+ * one file, $files can be a string to make code easier to read.
+ * @param bool $return_default Determines what to return if file does not
+ * exist. If true, function will return location where file is
+ * supposed to be. If false, function will return false.
+ * @param bool $return_full_path If true, function will return full path
+ * to file. If false, function will return file name. This
+ * parameter can be used to check which one of set of files
+ * is available.
+ * @return string or boolean Source file path if file exists or $return_default is
+ * true. False if file does not exist and $return_default is false
+ */
+ public function locate($files, $return_default = false, $return_full_path = true)
+ {
+ // convert string to array
+ if (is_string($files))
+ {
+ $files = array($files);
+ }
+
+ // use resource locator to find files
+ return $this->locator->get_first_file_location($files, $return_default, $return_full_path);
+ }
}
diff --git a/phpBB/includes/style/template.php b/phpBB/includes/style/template.php
index 21a2e821dd..3f15355f7a 100644
--- a/phpBB/includes/style/template.php
+++ b/phpBB/includes/style/template.php
@@ -288,7 +288,7 @@ class phpbb_style_template
return new phpbb_style_template_renderer_include($output_file, $this);
}
- $compile = new phpbb_style_template_compile($this->config['tpl_allow_php']);
+ $compile = new phpbb_style_template_compile($this->config['tpl_allow_php'], $this->locator, $this->phpbb_root_path);
if ($compile->compile_file_to_file($source_file, $output_file) !== false)
{
@@ -456,4 +456,59 @@ class phpbb_style_template
}
include($file);
}
+
+ /**
+ * Locates source template path, accounting for styles tree and verifying that
+ * the path exists.
+ *
+ * @param string or array $files List of templates to locate. If there is only
+ * one template, $files can be a string to make code easier to read.
+ * @param bool $return_default Determines what to return if template does not
+ * exist. If true, function will return location where template is
+ * supposed to be. If false, function will return false.
+ * @param bool $return_full_path If true, function will return full path
+ * to template. If false, function will return template file name.
+ * This parameter can be used to check which one of set of template
+ * files is available.
+ * @return string or boolean Source template path if template exists or $return_default is
+ * true. False if template does not exist and $return_default is false
+ */
+ public function locate($files, $return_default = false, $return_full_path = true)
+ {
+ // add tempalte path prefix
+ $templates = array();
+ if (is_string($files))
+ {
+ $templates[] = $this->template_path . $files;
+ }
+ else
+ {
+ foreach ($files as $file)
+ {
+ $templates[] = $this->template_path . $file;
+ }
+ }
+
+ // use resource locator to find files
+ return $this->locator->get_first_file_location($templates, $return_default, $return_full_path);
+ }
+
+ /**
+ * Include JS file
+ *
+ * @param string $file file name
+ * @param bool $locate True if file needs to be located
+ */
+ public function _js_include($file, $locate = false)
+ {
+ // Locate file
+ if ($locate)
+ {
+ $file = $this->locator->get_first_file_location(array($file), true, true);
+ }
+
+ // Add HTML code
+ $code = '<script src="' . htmlspecialchars($file) . '"></script>';
+ $this->context->append_var('SCRIPTS', $code);
+ }
}
diff --git a/phpBB/includes/style/template_compile.php b/phpBB/includes/style/template_compile.php
index 3ef3fffc00..fa0928f424 100644
--- a/phpBB/includes/style/template_compile.php
+++ b/phpBB/includes/style/template_compile.php
@@ -26,20 +26,26 @@ stream_filter_register('phpbb_template', 'phpbb_style_template_filter');
class phpbb_style_template_compile
{
/**
- * Whether <!-- PHP --> tags are allowed
+ * Array of parameters to forward to template filter
*
- * @var bool
+ * @var array
*/
- private $allow_php;
+ private $filter_params;
/**
* Constructor.
*
* @param bool @allow_php Whether PHP code will be allowed in templates (inline PHP code, PHP tag and INCLUDEPHP tag)
+ * @param phpbb_style_resource_locator $locator Resource locator
+ * @param string $phpbb_root_path Path to phpBB root directory
*/
- public function __construct($allow_php)
+ public function __construct($allow_php, $locator, $phpbb_root_path)
{
- $this->allow_php = $allow_php;
+ $this->filter_params = array(
+ 'allow_php' => $allow_php,
+ 'locator' => $locator,
+ 'phpbb_root_path' => $phpbb_root_path
+ );
}
/**
@@ -116,7 +122,7 @@ class phpbb_style_template_compile
*/
private function compile_stream_to_stream($source_stream, $dest_stream)
{
- stream_filter_append($source_stream, 'phpbb_template', null, array('allow_php' => $this->allow_php));
+ stream_filter_append($source_stream, 'phpbb_template', null, $this->filter_params);
stream_copy_to_stream($source_stream, $dest_stream);
}
}
diff --git a/phpBB/includes/style/template_filter.php b/phpBB/includes/style/template_filter.php
index 04fe85e07f..d62ad0ba1e 100644
--- a/phpBB/includes/style/template_filter.php
+++ b/phpBB/includes/style/template_filter.php
@@ -76,6 +76,18 @@ class phpbb_style_template_filter extends php_user_filter
private $allow_php;
/**
+ * Resource locator.
+ *
+ * @var phpbb_template_locator
+ */
+ private $locator;
+
+ /**
+ * @var string phpBB root path
+ */
+ private $phpbb_root_path;
+
+ /**
* Stream filter
*
* Is invoked for evey chunk of the stream, allowing us
@@ -126,14 +138,16 @@ class phpbb_style_template_filter extends php_user_filter
/**
* Initializer, called on creation.
*
- * Get the allow_php option from params, which is passed
- * to stream_filter_append.
+ * Get the allow_php option, root directory and locator from params,
+ * which are passed to stream_filter_append.
*/
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'];
return true;
}
@@ -281,6 +295,10 @@ class phpbb_style_template_filter extends php_user_filter
return ($this->allow_php) ? '<?php ' . $this->compile_tag_include_php($matches[2]) . ' ?>' : '';
break;
+ case 'INCLUDEJS':
+ return '<?php ' . $this->compile_tag_include_js($matches[2]) . ' ?>';
+ break;
+
case 'PHP':
if ($this->allow_php)
{
@@ -857,6 +875,45 @@ class phpbb_style_template_filter extends php_user_filter
}
/**
+ * Compile INCLUDEJS tag
+ *
+ * @param string $tag_args Expression given with INCLUDEJS in source template
+ * @return string compiled template code
+ */
+ private function compile_tag_include_js($tag_args)
+ {
+ // Process dynamic includes
+ if ($tag_args[0] == '{')
+ {
+ $var = $this->get_varref($tag_args, $is_expr);
+ if (!$is_expr)
+ {
+ return " \$_template->_js_include($var, true);";
+ }
+ return '';
+ }
+
+ // 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); ';
+ }
+
+ // Relative path, remove root path from it
+ $filename = substr($filename, strlen($this->phpbb_root_path));
+ return ' global $phpbb_root_path; $_template->_js_include($phpbb_root_path . \'' . addslashes($filename) . '\', false); ';
+ }
+
+ /**
* 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'] . '