diff options
Diffstat (limited to 'phpBB/phpbb')
28 files changed, 1359 insertions, 313 deletions
| diff --git a/phpBB/phpbb/cache/driver/null.php b/phpBB/phpbb/cache/driver/dummy.php index 298731ea54..1f74f6dd77 100644 --- a/phpBB/phpbb/cache/driver/null.php +++ b/phpBB/phpbb/cache/driver/dummy.php @@ -14,9 +14,9 @@  namespace phpbb\cache\driver;  /** -* ACM Null Caching +* ACM dummy Caching  */ -class null extends \phpbb\cache\driver\base +class dummy extends \phpbb\cache\driver\base  {  	/**  	* Set cache path diff --git a/phpBB/phpbb/captcha/plugins/captcha_abstract.php b/phpBB/phpbb/captcha/plugins/captcha_abstract.php index 799947a84e..b29f144f97 100644 --- a/phpBB/phpbb/captcha/plugins/captcha_abstract.php +++ b/phpBB/phpbb/captcha/plugins/captcha_abstract.php @@ -195,7 +195,7 @@ abstract class captcha_abstract  	{  		global $config, $db, $user; -		if (empty($user->lang)) +		if (!$user->is_setup())  		{  			$user->setup();  		} diff --git a/phpBB/phpbb/controller/exception.php b/phpBB/phpbb/controller/exception.php index 437558b06a..e227c7c37b 100644 --- a/phpBB/phpbb/controller/exception.php +++ b/phpBB/phpbb/controller/exception.php @@ -16,6 +16,6 @@ namespace phpbb\controller;  /**  * Controller exception class  */ -class exception extends \RuntimeException +class exception extends \phpbb\exception\runtime_exception  {  } diff --git a/phpBB/phpbb/controller/resolver.php b/phpBB/phpbb/controller/resolver.php index 948a6a218c..4f432c3323 100644 --- a/phpBB/phpbb/controller/resolver.php +++ b/phpBB/phpbb/controller/resolver.php @@ -23,12 +23,6 @@ use Symfony\Component\HttpFoundation\Request;  class resolver implements ControllerResolverInterface  {  	/** -	* User object -	* @var \phpbb\user -	*/ -	protected $user; - -	/**  	* ContainerInterface object  	* @var ContainerInterface  	*/ @@ -55,14 +49,12 @@ class resolver implements ControllerResolverInterface  	/**  	* Construct method  	* -	* @param \phpbb\user $user User Object  	* @param ContainerInterface $container ContainerInterface object  	* @param string $phpbb_root_path Relative path to phpBB root  	* @param \phpbb\template\template $template  	*/ -	public function __construct(\phpbb\user $user, ContainerInterface $container, $phpbb_root_path, \phpbb\template\template $template = null) +	public function __construct(ContainerInterface $container, $phpbb_root_path, \phpbb\template\template $template = null)  	{ -		$this->user = $user;  		$this->container = $container;  		$this->template = $template;  		$this->type_cast_helper = new \phpbb\request\type_cast_helper(); @@ -82,20 +74,20 @@ class resolver implements ControllerResolverInterface  		if (!$controller)  		{ -			throw new \phpbb\controller\exception($this->user->lang['CONTROLLER_NOT_SPECIFIED']); +			throw new \phpbb\controller\exception('CONTROLLER_NOT_SPECIFIED');  		}  		// Require a method name along with the service name  		if (stripos($controller, ':') === false)  		{ -			throw new \phpbb\controller\exception($this->user->lang['CONTROLLER_METHOD_NOT_SPECIFIED']); +			throw new \phpbb\controller\exception('CONTROLLER_METHOD_NOT_SPECIFIED');  		}  		list($service, $method) = explode(':', $controller);  		if (!$this->container->has($service))  		{ -			throw new \phpbb\controller\exception($this->user->lang('CONTROLLER_SERVICE_UNDEFINED', $service)); +			throw new \phpbb\controller\exception('CONTROLLER_SERVICE_UNDEFINED', array($service));  		}  		$controller_object = $this->container->get($service); @@ -166,7 +158,7 @@ class resolver implements ControllerResolverInterface  			}  			else  			{ -				throw new \phpbb\controller\exception($this->user->lang('CONTROLLER_ARGUMENT_VALUE_MISSING', $param->getPosition() + 1, get_class($object) . ':' . $method, $param->name)); +				throw new \phpbb\controller\exception('CONTROLLER_ARGUMENT_VALUE_MISSING', array($param->getPosition() + 1, get_class($object) . ':' . $method, $param->name));  			}  		} diff --git a/phpBB/phpbb/db/extractor/postgres_extractor.php b/phpBB/phpbb/db/extractor/postgres_extractor.php index 9eff1f568d..a98e39621c 100644 --- a/phpBB/phpbb/db/extractor/postgres_extractor.php +++ b/phpBB/phpbb/db/extractor/postgres_extractor.php @@ -72,6 +72,7 @@ class postgres_extractor extends base_extractor  				$this->flush($sql_data . ";\n");  			}  		} +		$this->db->sql_freeresult($result);  		$sql_data = '-- Table: ' . $table_name . "\n";  		$sql_data .= "DROP TABLE $table_name;\n"; diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_14.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_14.php new file mode 100644 index 0000000000..51475f5a05 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_14.php @@ -0,0 +1,37 @@ +<?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\db\migration\data\v30x; + +class release_3_0_14 extends \phpbb\db\migration\migration +{ +	public function effectively_installed() +	{ +		return phpbb_version_compare($this->config['version'], '3.0.14', '>=') && phpbb_version_compare($this->config['version'], '3.1.0-dev', '<'); +	} + +	static public function depends_on() +	{ +		return array('\phpbb\db\migration\data\v30x\release_3_0_14_rc1'); +	} + +	public function update_data() +	{ +		return array( +			array('if', array( +				phpbb_version_compare($this->config['version'], '3.0.14', '<'), +				array('config.update', array('version', '3.0.14')), +			)), +		); +	} +} diff --git a/phpBB/phpbb/db/migration/data/v31x/v314.php b/phpBB/phpbb/db/migration/data/v31x/v314.php new file mode 100644 index 0000000000..b7793ca569 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v31x/v314.php @@ -0,0 +1,32 @@ +<?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\db\migration\data\v31x; + +class v314 extends \phpbb\db\migration\migration +{ +	static public function depends_on() +	{ +		return array( +			'\phpbb\db\migration\data\v30x\release_3_0_14', +			'\phpbb\db\migration\data\v31x\v314rc2', +		); +	} + +	public function update_data() +	{ +		return array( +			array('config.update', array('version', '3.1.4')), +		); +	} +} diff --git a/phpBB/phpbb/db/migration/data/v31x/v314rc2.php b/phpBB/phpbb/db/migration/data/v31x/v314rc2.php new file mode 100644 index 0000000000..b75b7a9be8 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v31x/v314rc2.php @@ -0,0 +1,32 @@ +<?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\db\migration\data\v31x; + +class v314rc2 extends \phpbb\db\migration\migration +{ +	static public function depends_on() +	{ +		return array( +			'\phpbb\db\migration\data\v30x\release_3_0_14_rc1', +			'\phpbb\db\migration\data\v31x\v314rc1', +		); +	} + +	public function update_data() +	{ +		return array( +			array('config.update', array('version', '3.1.4-RC2')), +		); +	} +} diff --git a/phpBB/phpbb/event/md_exporter.php b/phpBB/phpbb/event/md_exporter.php index 84b10e79c1..05e898a157 100644 --- a/phpBB/phpbb/event/md_exporter.php +++ b/phpBB/phpbb/event/md_exporter.php @@ -24,6 +24,12 @@ class md_exporter  	/** @var string phpBB Root Path */  	protected $root_path; +	/** @var string The minimum version for the events to return */ +	protected $min_version; + +	/** @var string The maximum version for the events to return */ +	protected $max_version; +  	/** @var string */  	protected $filter; @@ -36,8 +42,10 @@ class md_exporter  	/**  	* @param string $phpbb_root_path  	* @param mixed $extension	String 'vendor/ext' to filter, null for phpBB core +	* @param string $min_version +	* @param string $max_version  	*/ -	public function __construct($phpbb_root_path, $extension = null) +	public function __construct($phpbb_root_path, $extension = null, $min_version = null, $max_version = null)  	{  		$this->root_path = $phpbb_root_path;  		$this->path = $this->root_path; @@ -49,6 +57,8 @@ class md_exporter  		$this->events = array();  		$this->events_by_file = array();  		$this->filter = $this->current_event = ''; +		$this->min_version = $min_version; +		$this->max_version = $max_version;  	}  	/** @@ -152,6 +162,11 @@ class md_exporter  			$files = $this->validate_file_list($file_details);  			$since = $this->validate_since($since); +			if (!$this->version_is_filtered($since)) +			{ +				continue; +			} +  			$this->events[$event_name] = array(  				'event'			=> $this->current_event,  				'files'			=> $files, @@ -164,20 +179,47 @@ class md_exporter  	}  	/** +	 * The version to check +	 * +	 * @param string $version +	 */ +	protected function version_is_filtered($version) +	{ +		return (!$this->min_version || phpbb_version_compare($this->min_version, $version, '<=')) +		&& (!$this->max_version || phpbb_version_compare($this->max_version, $version, '>=')); +	} + +	/**  	* Format the php events as a wiki table +	* +	* @param string $action  	* @return string		Number of events found  	*/ -	public function export_events_for_wiki() +	public function export_events_for_wiki($action = '')  	{  		if ($this->filter === 'adm')  		{ -			$wiki_page = '= ACP Template Events =' . "\n"; +			if ($action === 'diff') +			{ +				$wiki_page = '=== ACP Template Events ===' . "\n"; +			} +			else +			{ +				$wiki_page = '= ACP Template Events =' . "\n"; +			}  			$wiki_page .= '{| class="zebra sortable" cellspacing="0" cellpadding="5"' . "\n";  			$wiki_page .= '! Identifier !! Placement !! Added in Release !! Explanation' . "\n";  		}  		else  		{ -			$wiki_page = '= Template Events =' . "\n"; +			if ($action === 'diff') +			{ +				$wiki_page = '=== Template Events ===' . "\n"; +			} +			else +			{ +				$wiki_page = '= Template Events =' . "\n"; +			}  			$wiki_page .= '{| class="zebra sortable" cellspacing="0" cellpadding="5"' . "\n";  			$wiki_page .= '! Identifier !! Prosilver Placement (If applicable) !! Added in Release !! Explanation' . "\n";  		} diff --git a/phpBB/phpbb/event/php_exporter.php b/phpBB/phpbb/event/php_exporter.php index 35144eeeec..8cffa4620f 100644 --- a/phpBB/phpbb/event/php_exporter.php +++ b/phpBB/phpbb/event/php_exporter.php @@ -25,6 +25,12 @@ class php_exporter  	/** @var string phpBB Root Path */  	protected $root_path; +	/** @var string The minimum version for the events to return */ +	protected $min_version; + +	/** @var string The maximum version for the events to return */ +	protected $max_version; +  	/** @var string */  	protected $current_file; @@ -43,14 +49,18 @@ class php_exporter  	/**  	* @param string $phpbb_root_path  	* @param mixed $extension	String 'vendor/ext' to filter, null for phpBB core +	* @param string $min_version +	* @param string $max_version  	*/ -	public function __construct($phpbb_root_path, $extension = null) +	public function __construct($phpbb_root_path, $extension = null, $min_version = null, $max_version = null)  	{  		$this->root_path = $phpbb_root_path;  		$this->path = $phpbb_root_path;  		$this->events = $this->file_lines = array();  		$this->current_file = $this->current_event = '';  		$this->current_event_line = 0; +		$this->min_version = $min_version; +		$this->max_version = $max_version;  		$this->path = $this->root_path;  		if ($extension) @@ -148,11 +158,20 @@ class php_exporter  	/**  	* Format the php events as a wiki table +	* +	* @param string $action  	* @return string  	*/ -	public function export_events_for_wiki() +	public function export_events_for_wiki($action = '')  	{ -		$wiki_page = '= PHP Events (Hook Locations) =' . "\n"; +		if ($action === 'diff') +		{ +			$wiki_page = '=== PHP Events (Hook Locations) ===' . "\n"; +		} +		else +		{ +			$wiki_page = '= PHP Events (Hook Locations) =' . "\n"; +		}  		$wiki_page .= '{| class="sortable zebra" cellspacing="0" cellpadding="5"' . "\n";  		$wiki_page .= '! Identifier !! Placement !! Arguments !! Added in Release !! Explanation' . "\n";  		foreach ($this->events as $event) @@ -215,6 +234,34 @@ class php_exporter  					$since_line_num = $this->find_since();  					$since = $this->validate_since($this->file_lines[$since_line_num]); +					$changed_line_nums = $this->find_changed('changed'); +					if (empty($changed_line_nums)) +					{ +						$changed_line_nums = $this->find_changed('change'); +					} +					$changed_versions = array(); +					if (!empty($changed_line_nums)) +					{ +						foreach ($changed_line_nums as $changed_line_num) +						{ +							$changed_versions[] = $this->validate_changed($this->file_lines[$changed_line_num]); +						} +					} + +					if (!$this->version_is_filtered($since)) +					{ +						$valid_version = false; +						foreach ($changed_versions as $changed) +						{ +							$valid_version = $valid_version || $this->version_is_filtered($changed); +						} + +						if (!$valid_version) +						{ +							continue; +						} +					} +  					// Find event description line  					$description_line_num = $this->find_description();  					$description = substr(trim($this->file_lines[$description_line_num]), strlen('* ')); @@ -243,6 +290,17 @@ class php_exporter  	}  	/** +	 * The version to check +	 * +	 * @param string $version +	 */ +	protected function version_is_filtered($version) +	{ +		return (!$this->min_version || phpbb_version_compare($this->min_version, $version, '<=')) +			&& (!$this->max_version || phpbb_version_compare($this->max_version, $version, '>=')); +	} + +	/**  	* Find the name of the event inside the dispatch() line  	*  	* @param int $event_line @@ -449,6 +507,33 @@ class php_exporter  	}  	/** +	* Find the "@changed" Information lines +	* +	* @param string $tag_name Should be 'changed' or 'change' +	* @return array Absolute line numbers +	* @throws \LogicException +	*/ +	public function find_changed($tag_name) +	{ +		$lines = array(); +		$last_line = 0; +		try +		{ +			while ($line = $this->find_tag($tag_name, array('since'), $last_line)) +			{ +				$lines[] = $line; +				$last_line = $line; +			} +		} +		catch (\LogicException $e) +		{ +			// Not changed? No problem! +		} + +		return $lines; +	} + +	/**  	* Find the "@event" Information line  	*  	* @return int Absolute line number @@ -464,13 +549,14 @@ class php_exporter  	* @param string $find_tag		Name of the tag we are trying to find  	* @param array $disallowed_tags		List of tags that must not appear between  	*									the tag and the actual event +	* @param int $skip_to_line		Skip lines until this one  	* @return int Absolute line number  	* @throws \LogicException  	*/ -	public function find_tag($find_tag, $disallowed_tags) +	public function find_tag($find_tag, $disallowed_tags, $skip_to_line = 0)  	{ -		$find_tag_line = 0; -		$found_comment_end = false; +		$find_tag_line = $skip_to_line ? $this->current_event_line - $skip_to_line + 1 : 0; +		$found_comment_end = ($skip_to_line) ? true : false;  		while (strpos(ltrim($this->file_lines[$this->current_event_line - $find_tag_line], "\t "), '* @' . $find_tag . ' ') !== 0)  		{  			if ($found_comment_end && ltrim($this->file_lines[$this->current_event_line - $find_tag_line], "\t") === '/**') @@ -561,6 +647,27 @@ class php_exporter  	}  	/** +	* Validate "@changed" Information +	* +	* @param string $line +	* @return string +	* @throws \LogicException +	*/ +	public function validate_changed($line) +	{ +		$match = array(); +		$line = str_replace("\t", ' ', ltrim($line, "\t ")); +		preg_match('#^\* @change(d)? (\d+\.\d+\.\d+(?:-(?:a|b|RC|pl)\d+)?)( (?:.*))?$#', $line, $match); +		if (!isset($match[2])) +		{ +			throw new \LogicException("Invalid '@changed' information for event " +				. "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'"); +		} + +		return $match[2]; +	} + +	/**  	* Validate "@event" Information  	*  	* @param string $event_name diff --git a/phpBB/phpbb/extension/exception.php b/phpBB/phpbb/extension/exception.php index 3f7d251a4e..9050449bf1 100644 --- a/phpBB/phpbb/extension/exception.php +++ b/phpBB/phpbb/extension/exception.php @@ -16,10 +16,6 @@ namespace phpbb\extension;  /**   * Exception class for metadata   */ -class exception extends \UnexpectedValueException +class exception extends \phpbb\exception\runtime_exception  { -	public function __toString() -	{ -		return $this->getMessage(); -	}  } diff --git a/phpBB/phpbb/extension/manager.php b/phpBB/phpbb/extension/manager.php index 40fda74065..98d2d27278 100644 --- a/phpBB/phpbb/extension/manager.php +++ b/phpBB/phpbb/extension/manager.php @@ -26,7 +26,6 @@ class manager  	protected $db;  	protected $config;  	protected $cache; -	protected $user;  	protected $php_ext;  	protected $extensions;  	protected $extension_table; @@ -40,14 +39,13 @@ class manager  	* @param \phpbb\db\driver\driver_interface $db A database connection  	* @param \phpbb\config\config $config Config object  	* @param \phpbb\filesystem\filesystem_interface $filesystem -	* @param \phpbb\user $user User object  	* @param string $extension_table The name of the table holding extensions  	* @param string $phpbb_root_path Path to the phpbb includes directory.  	* @param string $php_ext php file extension, defaults to php  	* @param \phpbb\cache\driver\driver_interface $cache A cache instance or null  	* @param string $cache_name The name of the cache variable, defaults to _ext  	*/ -	public function __construct(ContainerInterface $container, \phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\filesystem\filesystem_interface $filesystem, \phpbb\user $user, $extension_table, $phpbb_root_path, $php_ext = 'php', \phpbb\cache\driver\driver_interface $cache = null, $cache_name = '_ext') +	public function __construct(ContainerInterface $container, \phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\filesystem\filesystem_interface $filesystem, $extension_table, $phpbb_root_path, $php_ext = 'php', \phpbb\cache\driver\driver_interface $cache = null, $cache_name = '_ext')  	{  		$this->cache = $cache;  		$this->cache_name = $cache_name; @@ -58,7 +56,6 @@ class manager  		$this->filesystem = $filesystem;  		$this->phpbb_root_path = $phpbb_root_path;  		$this->php_ext = $php_ext; -		$this->user = $user;  		$this->extensions = ($this->cache) ? $this->cache->get($this->cache_name) : false; @@ -154,7 +151,7 @@ class manager  	*/  	public function create_extension_metadata_manager($name, \phpbb\template\template $template)  	{ -		return new \phpbb\extension\metadata_manager($name, $this->config, $this, $template, $this->user, $this->phpbb_root_path); +		return new \phpbb\extension\metadata_manager($name, $this->config, $this, $template, $this->phpbb_root_path);  	}  	/** diff --git a/phpBB/phpbb/extension/metadata_manager.php b/phpBB/phpbb/extension/metadata_manager.php index a64d88fe39..4f080647c8 100644 --- a/phpBB/phpbb/extension/metadata_manager.php +++ b/phpBB/phpbb/extension/metadata_manager.php @@ -37,12 +37,6 @@ class metadata_manager  	protected $template;  	/** -	* phpBB User instance -	* @var \phpbb\user -	*/ -	protected $user; - -	/**  	* phpBB root path  	* @var string  	*/ @@ -73,15 +67,13 @@ class metadata_manager  	* @param \phpbb\config\config		$config				phpBB Config instance  	* @param \phpbb\extension\manager	$extension_manager	An instance of the phpBB extension manager  	* @param \phpbb\template\template	$template			phpBB Template instance -	* @param \phpbb\user 		$user 				User instance  	* @param string				$phpbb_root_path	Path to the phpbb includes directory.  	*/ -	public function __construct($ext_name, \phpbb\config\config $config, \phpbb\extension\manager $extension_manager, \phpbb\template\template $template, \phpbb\user $user, $phpbb_root_path) +	public function __construct($ext_name, \phpbb\config\config $config, \phpbb\extension\manager $extension_manager, \phpbb\template\template $template, $phpbb_root_path)  	{  		$this->config = $config;  		$this->extension_manager = $extension_manager;  		$this->template = $template; -		$this->user = $user;  		$this->phpbb_root_path = $phpbb_root_path;  		$this->ext_name = $ext_name; @@ -149,7 +141,7 @@ class metadata_manager  		if (!file_exists($this->metadata_file))  		{ -			throw new \phpbb\extension\exception($this->user->lang('FILE_NOT_FOUND', $this->metadata_file)); +			throw new \phpbb\extension\exception('FILE_NOT_FOUND', array($this->metadata_file));  		}  	} @@ -163,18 +155,18 @@ class metadata_manager  	{  		if (!file_exists($this->metadata_file))  		{ -			throw new \phpbb\extension\exception($this->user->lang('FILE_NOT_FOUND', $this->metadata_file)); +			throw new \phpbb\extension\exception('FILE_NOT_FOUND', array($this->metadata_file));  		}  		else  		{  			if (!($file_contents = file_get_contents($this->metadata_file)))  			{ -				throw new \phpbb\extension\exception($this->user->lang('FILE_CONTENT_ERR', $this->metadata_file)); +				throw new \phpbb\extension\exception('FILE_CONTENT_ERR', array($this->metadata_file));  			}  			if (($metadata = json_decode($file_contents, true)) === null)  			{ -				throw new \phpbb\extension\exception($this->user->lang('FILE_JSON_DECODE_ERR', $this->metadata_file)); +				throw new \phpbb\extension\exception('FILE_JSON_DECODE_ERR', array($this->metadata_file));  			}  			array_walk_recursive($metadata, array($this, 'sanitize_json')); @@ -246,12 +238,12 @@ class metadata_manager  				{  					if (!isset($this->metadata[$name]))  					{ -						throw new \phpbb\extension\exception($this->user->lang('META_FIELD_NOT_SET', $name)); +						throw new \phpbb\extension\exception('META_FIELD_NOT_SET', array($name));  					}  					if (!preg_match($fields[$name], $this->metadata[$name]))  					{ -						throw new \phpbb\extension\exception($this->user->lang('META_FIELD_INVALID', $name)); +						throw new \phpbb\extension\exception('META_FIELD_INVALID', array($name));  					}  				}  			break; @@ -270,14 +262,14 @@ class metadata_manager  	{  		if (empty($this->metadata['authors']))  		{ -			throw new \phpbb\extension\exception($this->user->lang('META_FIELD_NOT_SET', 'authors')); +			throw new \phpbb\extension\exception('META_FIELD_NOT_SET', array('authors'));  		}  		foreach ($this->metadata['authors'] as $author)  		{  			if (!isset($author['name']))  			{ -				throw new \phpbb\extension\exception($this->user->lang('META_FIELD_NOT_SET', 'author name')); +				throw new \phpbb\extension\exception('META_FIELD_NOT_SET', array('author name'));  			}  		} diff --git a/phpBB/phpbb/filesystem/filesystem.php b/phpBB/phpbb/filesystem/filesystem.php index 370dff77e5..2112882d1d 100644 --- a/phpBB/phpbb/filesystem/filesystem.php +++ b/phpBB/phpbb/filesystem/filesystem.php @@ -613,7 +613,7 @@ class filesystem implements filesystem_interface  			}  			else  			{ -				$handle = @fopen($file, 'w'); +				$handle = @fopen($file, 'c');  				if (is_resource($handle))  				{ diff --git a/phpBB/phpbb/language/exception/invalid_plural_rule_exception.php b/phpBB/phpbb/language/exception/invalid_plural_rule_exception.php new file mode 100644 index 0000000000..94e3466208 --- /dev/null +++ b/phpBB/phpbb/language/exception/invalid_plural_rule_exception.php @@ -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\language\exception; + +/** + * Thrown when nonexistent plural rule is specified + */ +class invalid_plural_rule_exception extends language_exception +{ + +} diff --git a/phpBB/phpbb/language/exception/language_exception.php b/phpBB/phpbb/language/exception/language_exception.php new file mode 100644 index 0000000000..b1258414aa --- /dev/null +++ b/phpBB/phpbb/language/exception/language_exception.php @@ -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\language\exception; + +/** + * Base exception class for language exceptions + */ +class language_exception extends \phpbb\exception\runtime_exception +{ + +} diff --git a/phpBB/phpbb/language/exception/language_file_not_found.php b/phpBB/phpbb/language/exception/language_file_not_found.php new file mode 100644 index 0000000000..89364267eb --- /dev/null +++ b/phpBB/phpbb/language/exception/language_file_not_found.php @@ -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\language\exception; + +/** + * This exception is thrown when the language file is not found + */ +class language_file_not_found extends language_exception +{ + +} diff --git a/phpBB/phpbb/language/language.php b/phpBB/phpbb/language/language.php new file mode 100644 index 0000000000..3298908365 --- /dev/null +++ b/phpBB/phpbb/language/language.php @@ -0,0 +1,571 @@ +<?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\language; + +use phpbb\language\exception\invalid_plural_rule_exception; + +/** + * Wrapper class for loading translations + */ +class language +{ +	/** +	 * Global fallback language +	 * +	 * ISO code of the language to fallback to when the specified language entries +	 * cannot be found. +	 * +	 * @var string +	 */ +	const FALLBACK_LANGUAGE = 'en'; + +	/** +	 * @var array	List of common language files +	 */ +	protected $common_language_files; + +	/** +	 * @var bool +	 */ +	protected $common_language_files_loaded; + +	/** +	 * @var string	ISO code of the default board language +	 */ +	protected $default_language; + +	/** +	 * @var string	ISO code of the User's language +	 */ +	protected $user_language; + +	/** +	 * @var array	Language fallback array (the order is important) +	 */ +	protected $language_fallback; + +	/** +	 * @var array	Array of language variables +	 */ +	protected $lang; + +	/** +	 * @var array	Loaded language sets +	 */ +	protected $loaded_language_sets; + +	/** +	 * @var \phpbb\language\language_file_loader Language file loader +	 */ +	protected $loader; + +	/** +	 * Constructor +	 * +	 * @param \phpbb\language\language_file_loader	$loader			Language file loader +	 * @param array|null							$common_modules	Array of common language modules to load (optional) +	 */ +	public function __construct(language_file_loader $loader, $common_modules = null) +	{ +		$this->loader = $loader; + +		// Set up default information +		$this->user_language		= false; +		$this->default_language		= false; +		$this->lang					= array( +			// For BC with user::help array +			'__help' => array(), +		); +		$this->loaded_language_sets	= array( +			'core'	=> array(), +			'ext'	=> array(), +		); + +		// Common language files +		if (is_array($common_modules)) +		{ +			$this->common_language_files = $common_modules; +		} +		else +		{ +			$this->common_language_files = array( +				'common', +			); +		} + +		$this->common_language_files_loaded = false; + +		$this->language_fallback = array(self::FALLBACK_LANGUAGE); +	} + +	/** +	 * Function to set user's language to display. +	 * +	 * @param string	$user_lang_iso	ISO code of the User's language +	 */ +	public function set_user_language($user_lang_iso) +	{ +		$this->user_language = $user_lang_iso; + +		$this->set_fallback_array(); +	} + +	/** +	 * Function to set the board's default language to display. +	 * +	 * @param string	$default_lang_iso	ISO code of the board's default language +	 */ +	public function set_default_language($default_lang_iso) +	{ +		$this->default_language = $default_lang_iso; + +		$this->set_fallback_array(); +	} + +	/** +	 * Returns language array +	 * +	 * Note: This function is needed for the BC purposes, until \phpbb\user::lang[] is +	 *       not removed. +	 * +	 * @return array	Array of loaded language strings +	 */ +	public function get_lang_array() +	{ +		// Load common language files if they not loaded yet +		if (!$this->common_language_files_loaded) +		{ +			$this->load_common_language_files(); +		} + +		return $this->lang; +	} + +	/** +	 * Add Language Items +	 * +	 * Note: $use_help is assigned where needed (only use them to force inclusion). +	 * +	 * Examples: +	 * <code> +	 * $component = array('posting'); +	 * $component = array('posting', 'viewtopic') +	 * $component = 'posting' +	 * </code> +	 * +	 * @param string|array	$component		The name of the language component to load +	 * @param string|null	$extension_name	Name of the extension to load component from, or null for core file +	 */ +	public function add_lang($component, $extension_name = null) +	{ +		// Load common language files if they not loaded yet +		// This needs to be here to correctly merge language arrays +		if (!$this->common_language_files_loaded) +		{ +			$this->load_common_language_files(); +		} + +		if (!is_array($component)) +		{ +			if (!is_null($extension_name)) +			{ +				$this->load_extension($extension_name, $component); +			} +			else +			{ +				$this->load_core_file($component); +			} +		} +		else +		{ +			foreach ($component as $lang_file) +			{ +				$this->add_lang($lang_file, $extension_name); +			} +		} +	} + +	/** +	 * Advanced language substitution +	 * +	 * Function to mimic sprintf() with the possibility of using phpBB's language system to substitute nullar/singular/plural forms. +	 * Params are the language key and the parameters to be substituted. +	 * This function/functionality is inspired by SHS` and Ashe. +	 * +	 * Example call: <samp>$user->lang('NUM_POSTS_IN_QUEUE', 1);</samp> +	 * +	 * If the first parameter is an array, the elements are used as keys and subkeys to get the language entry: +	 * Example: <samp>$user->lang(array('datetime', 'AGO'), 1)</samp> uses $user->lang['datetime']['AGO'] as language entry. +	 * +	 * @return string	Return localized string or the language key if the translation is not available +	 */ +	public function lang() +	{ +		// Load common language files if they not loaded yet +		if (!$this->common_language_files_loaded) +		{ +			$this->load_common_language_files(); +		} + +		$args = func_get_args(); +		$key = $args[0]; + +		if (is_array($key)) +		{ +			$lang = &$this->lang[array_shift($key)]; + +			foreach ($key as $_key) +			{ +				$lang = &$lang[$_key]; +			} +		} +		else +		{ +			$lang = &$this->lang[$key]; +		} + +		// Return if language string does not exist +		if (!isset($lang) || (!is_string($lang) && !is_array($lang))) +		{ +			return $key; +		} + +		// If the language entry is a string, we simply mimic sprintf() behaviour +		if (is_string($lang)) +		{ +			if (sizeof($args) == 1) +			{ +				return $lang; +			} + +			// Replace key with language entry and simply pass along... +			$args[0] = $lang; +			return call_user_func_array('sprintf', $args); +		} +		else if (sizeof($lang) == 0) +		{ +			// If the language entry is an empty array, we just return the language key +			return $args[0]; +		} + +		// It is an array... now handle different nullar/singular/plural forms +		$key_found = false; + +		// We now get the first number passed and will select the key based upon this number +		for ($i = 1, $num_args = sizeof($args); $i < $num_args; $i++) +		{ +			if (is_int($args[$i]) || is_float($args[$i])) +			{ +				if ($args[$i] == 0 && isset($lang[0])) +				{ +					// We allow each translation using plural forms to specify a version for the case of 0 things, +					// so that "0 users" may be displayed as "No users". +					$key_found = 0; +					break; +				} +				else +				{ +					$use_plural_form = $this->get_plural_form($args[$i]); +					if (isset($lang[$use_plural_form])) +					{ +						// The key we should use exists, so we use it. +						$key_found = $use_plural_form; +					} +					else +					{ +						// If the key we need to use does not exist, we fall back to the previous one. +						$numbers = array_keys($lang); + +						foreach ($numbers as $num) +						{ +							if ($num > $use_plural_form) +							{ +								break; +							} + +							$key_found = $num; +						} +					} +					break; +				} +			} +		} + +		// Ok, let's check if the key was found, else use the last entry (because it is mostly the plural form) +		if ($key_found === false) +		{ +			$numbers = array_keys($lang); +			$key_found = end($numbers); +		} + +		// Use the language string we determined and pass it to sprintf() +		$args[0] = $lang[$key_found]; +		return call_user_func_array('sprintf', $args); +	} + +	/** +	 * Loads common language files +	 */ +	protected function load_common_language_files() +	{ +		if (!$this->common_language_files_loaded) +		{ +			foreach ($this->common_language_files as $lang_file) +			{ +				$this->load_core_file($lang_file); +			} + +			$this->common_language_files_loaded = true; +		} +	} + +	/** +	 * Determine which plural form we should use. +	 * +	 * For some languages this is not as simple as for English. +	 * +	 * @param int|float		$number		The number we want to get the plural case for. Float numbers are floored. +	 * @param int|bool		$force_rule	False to use the plural rule of the language package +	 *									or an integer to force a certain plural rule +	 * +	 * @return int	The plural-case we need to use for the number plural-rule combination +	 * +	 * @throws \phpbb\language\exception\invalid_plural_rule_exception	When $force_rule has an invalid value +	 */ +	public function get_plural_form($number, $force_rule = false) +	{ +		$number			= (int) $number; +		$plural_rule	= ($force_rule !== false) ? $force_rule : ((isset($this->lang['PLURAL_RULE'])) ? $this->lang['PLURAL_RULE'] : 1); + +		if ($plural_rule > 15 || $plural_rule < 0) +		{ +			throw new invalid_plural_rule_exception('INVALID_PLURAL_RULE', array( +				'plural_rule' => $plural_rule, +			)); +		} + +		/** +		 * The following plural rules are based on a list published by the Mozilla Developer Network +		 * https://developer.mozilla.org/en/Localization_and_Plurals +		 */ +		switch ($plural_rule) +		{ +			case 0: +				/** +				 * Families: Asian (Chinese, Japanese, Korean, Vietnamese), Persian, Turkic/Altaic (Turkish), Thai, Lao +				 * 1 - everything: 0, 1, 2, ... +				 */ +				return 1; + +			case 1: +				/** +				 * Families: Germanic (Danish, Dutch, English, Faroese, Frisian, German, Norwegian, Swedish), Finno-Ugric (Estonian, Finnish, Hungarian), Language isolate (Basque), Latin/Greek (Greek), Semitic (Hebrew), Romanic (Italian, Portuguese, Spanish, Catalan) +				 * 1 - 1 +				 * 2 - everything else: 0, 2, 3, ... +				 */ +				return ($number === 1) ? 1 : 2; + +			case 2: +				/** +				 * Families: Romanic (French, Brazilian Portuguese) +				 * 1 - 0, 1 +				 * 2 - everything else: 2, 3, ... +				 */ +				return (($number === 0) || ($number === 1)) ? 1 : 2; + +			case 3: +				/** +				 * Families: Baltic (Latvian) +				 * 1 - 0 +				 * 2 - ends in 1, not 11: 1, 21, ... 101, 121, ... +				 * 3 - everything else: 2, 3, ... 10, 11, 12, ... 20, 22, ... +				 */ +				return ($number === 0) ? 1 : ((($number % 10 === 1) && ($number % 100 != 11)) ? 2 : 3); + +			case 4: +				/** +				 * Families: Celtic (Scottish Gaelic) +				 * 1 - is 1 or 11: 1, 11 +				 * 2 - is 2 or 12: 2, 12 +				 * 3 - others between 3 and 19: 3, 4, ... 10, 13, ... 18, 19 +				 * 4 - everything else: 0, 20, 21, ... +				 */ +				return ($number === 1 || $number === 11) ? 1 : (($number === 2 || $number === 12) ? 2 : (($number >= 3 && $number <= 19) ? 3 : 4)); + +			case 5: +				/** +				 * Families: Romanic (Romanian) +				 * 1 - 1 +				 * 2 - is 0 or ends in 01-19: 0, 2, 3, ... 19, 101, 102, ... 119, 201, ... +				 * 3 - everything else: 20, 21, ... +				 */ +				return ($number === 1) ? 1 : ((($number === 0) || (($number % 100 > 0) && ($number % 100 < 20))) ? 2 : 3); + +			case 6: +				/** +				 * Families: Baltic (Lithuanian) +				 * 1 - ends in 1, not 11: 1, 21, 31, ... 101, 121, ... +				 * 2 - ends in 0 or ends in 10-20: 0, 10, 11, 12, ... 19, 20, 30, 40, ... +				 * 3 - everything else: 2, 3, ... 8, 9, 22, 23, ... 29, 32, 33, ... +				 */ +				return (($number % 10 === 1) && ($number % 100 != 11)) ? 1 : ((($number % 10 < 2) || (($number % 100 >= 10) && ($number % 100 < 20))) ? 2 : 3); + +			case 7: +				/** +				 * Families: Slavic (Croatian, Serbian, Russian, Ukrainian) +				 * 1 - ends in 1, not 11: 1, 21, 31, ... 101, 121, ... +				 * 2 - ends in 2-4, not 12-14: 2, 3, 4, 22, 23, 24, 32, ... +				 * 3 - everything else: 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 25, 26, ... +				 */ +				return (($number % 10 === 1) && ($number % 100 != 11)) ? 1 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 10) || ($number % 100 >= 20))) ? 2 : 3); + +			case 8: +				/** +				 * Families: Slavic (Slovak, Czech) +				 * 1 - 1 +				 * 2 - 2, 3, 4 +				 * 3 - everything else: 0, 5, 6, 7, ... +				 */ +				return ($number === 1) ? 1 : ((($number >= 2) && ($number <= 4)) ? 2 : 3); + +			case 9: +				/** +				 * Families: Slavic (Polish) +				 * 1 - 1 +				 * 2 - ends in 2-4, not 12-14: 2, 3, 4, 22, 23, 24, 32, ... 104, 122, ... +				 * 3 - everything else: 0, 5, 6, ... 11, 12, 13, 14, 15, ... 20, 21, 25, ... +				 */ +				return ($number === 1) ? 1 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 12) || ($number % 100 > 14))) ? 2 : 3); + +			case 10: +				/** +				 * Families: Slavic (Slovenian, Sorbian) +				 * 1 - ends in 01: 1, 101, 201, ... +				 * 2 - ends in 02: 2, 102, 202, ... +				 * 3 - ends in 03-04: 3, 4, 103, 104, 203, 204, ... +				 * 4 - everything else: 0, 5, 6, 7, 8, 9, 10, 11, ... +				 */ +				return ($number % 100 === 1) ? 1 : (($number % 100 === 2) ? 2 : ((($number % 100 === 3) || ($number % 100 === 4)) ? 3 : 4)); + +			case 11: +				/** +				 * Families: Celtic (Irish Gaeilge) +				 * 1 - 1 +				 * 2 - 2 +				 * 3 - is 3-6: 3, 4, 5, 6 +				 * 4 - is 7-10: 7, 8, 9, 10 +				 * 5 - everything else: 0, 11, 12, ... +				 */ +				return ($number === 1) ? 1 : (($number === 2) ? 2 : (($number >= 3 && $number <= 6) ? 3 : (($number >= 7 && $number <= 10) ? 4 : 5))); + +			case 12: +				/** +				 * Families: Semitic (Arabic) +				 * 1 - 1 +				 * 2 - 2 +				 * 3 - ends in 03-10: 3, 4, ... 10, 103, 104, ... 110, 203, 204, ... +				 * 4 - ends in 11-99: 11, ... 99, 111, 112, ... +				 * 5 - everything else: 100, 101, 102, 200, 201, 202, ... +				 * 6 - 0 +				 */ +				return ($number === 1) ? 1 : (($number === 2) ? 2 : ((($number % 100 >= 3) && ($number % 100 <= 10)) ? 3 : ((($number % 100 >= 11) && ($number % 100 <= 99)) ? 4 : (($number != 0) ? 5 : 6)))); + +			case 13: +				/** +				 * Families: Semitic (Maltese) +				 * 1 - 1 +				 * 2 - is 0 or ends in 01-10: 0, 2, 3, ... 9, 10, 101, 102, ... +				 * 3 - ends in 11-19: 11, 12, ... 18, 19, 111, 112, ... +				 * 4 - everything else: 20, 21, ... +				 */ +				return ($number === 1) ? 1 : ((($number === 0) || (($number % 100 > 1) && ($number % 100 < 11))) ? 2 : ((($number % 100 > 10) && ($number % 100 < 20)) ? 3 : 4)); + +			case 14: +				/** +				 * Families: Slavic (Macedonian) +				 * 1 - ends in 1: 1, 11, 21, ... +				 * 2 - ends in 2: 2, 12, 22, ... +				 * 3 - everything else: 0, 3, 4, ... 10, 13, 14, ... 20, 23, ... +				 */ +				return ($number % 10 === 1) ? 1 : (($number % 10 === 2) ? 2 : 3); + +			case 15: +				/** +				 * Families: Icelandic +				 * 1 - ends in 1, not 11: 1, 21, 31, ... 101, 121, 131, ... +				 * 2 - everything else: 0, 2, 3, ... 10, 11, 12, ... 20, 22, ... +				 */ +				return (($number % 10 === 1) && ($number % 100 != 11)) ? 1 : 2; +		} +	} + +	/** +	 * Returns language fallback data +	 * +	 * @return array +	 */ +	protected function set_fallback_array() +	{ +		$fallback_array = array(); + +		if ($this->user_language !== false) +		{ +			$fallback_array[] = $this->user_language; +		} + +		if ($this->default_language !== false) +		{ +			$fallback_array[] = $this->default_language; +		} + +		$fallback_array[] = self::FALLBACK_LANGUAGE; + +		$this->language_fallback = $fallback_array; +	} + +	/** +	 * Load core language file +	 * +	 * @param string	$component	Name of the component to load +	 */ +	protected function load_core_file($component) +	{ +		// Check if the component is already loaded +		if (isset($this->loaded_language_sets['core'][$component])) +		{ +			return; +		} + +		$this->loader->load($component, $this->language_fallback, $this->lang); +		$this->loaded_language_sets['core'][$component] = true; +	} + +	/** +	 * Load extension language file +	 * +	 * @param string	$extension_name	Name of the extension to load language from +	 * @param string	$component		Name of the component to load +	 */ +	protected function load_extension($extension_name, $component) +	{ +		// Check if the component is already loaded +		if (isset($this->loaded_language_sets['ext'][$extension_name][$component])) +		{ +			return; +		} + +		$this->loader->load_extension($extension_name, $component, $this->language_fallback, $this->lang); +		$this->loaded_language_sets['ext'][$extension_name][$component] = true; +	} +} diff --git a/phpBB/phpbb/language/language_file_helper.php b/phpBB/phpbb/language/language_file_helper.php new file mode 100644 index 0000000000..18d7b62e21 --- /dev/null +++ b/phpBB/phpbb/language/language_file_helper.php @@ -0,0 +1,71 @@ +<?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\language; + +use Symfony\Component\Finder\Finder; + +/** + * Helper class for language file related functions + */ +class language_file_helper +{ +	/** +	 * @var string	Path to phpBB's root +	 */ +	protected $phpbb_root_path; + +	/** +	 * Constructor +	 * +	 * @param string	$phpbb_root_path	Path to phpBB's root +	 */ +	public function __construct($phpbb_root_path) +	{ +		$this->phpbb_root_path = $phpbb_root_path; +	} + +	/** +	 * Returns available languages +	 * +	 * @return array +	 */ +	public function get_available_languages() +	{ +		// Find available language packages +		$finder = new Finder(); +		$finder->files() +			->name('iso.txt') +			->depth('== 1') +			->in($this->phpbb_root_path . 'language'); + +		$available_languages = array(); +		foreach ($finder as $file) +		{ +			$path = $file->getRelativePath(); +			$info = explode("\n", $file->getContents()); + +			$available_languages[] = array( +				// Get the name of the directory containing iso.txt +				'iso' => $path, + +				// Recover data from file +				'name' => trim($info[0]), +				'local_name' => trim($info[1]), +				'author' => trim($info[2]) +			); +		} + +		return $available_languages; +	} +} diff --git a/phpBB/phpbb/language/language_file_loader.php b/phpBB/phpbb/language/language_file_loader.php new file mode 100644 index 0000000000..510a29279a --- /dev/null +++ b/phpBB/phpbb/language/language_file_loader.php @@ -0,0 +1,212 @@ +<?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\language; + +use \phpbb\language\exception\language_file_not_found; + +/** + * Language file loader + */ +class language_file_loader +{ +	/** +	 * @var string	Path to phpBB's root +	 */ +	protected $phpbb_root_path; + +	/** +	 * @var string	Extension of PHP files +	 */ +	protected $php_ext; + +	/** +	 * @var \phpbb\extension\manager	Extension manager +	 */ +	protected $extension_manager; + +	/** +	 * Constructor +	 * +	 * @param string	$phpbb_root_path	Path to phpBB's root +	 * @param string	$php_ext			Extension of PHP files +	 */ +	public function __construct($phpbb_root_path, $php_ext) +	{ +		$this->phpbb_root_path	= $phpbb_root_path; +		$this->php_ext			= $php_ext; + +		$this->extension_manager = null; +	} + +	/** +	 * Extension manager setter +	 * +	 * @param \phpbb\extension\manager	$extension_manager	Extension manager +	 */ +	public function set_extension_manager(\phpbb\extension\manager $extension_manager) +	{ +		$this->extension_manager = $extension_manager; +	} + +	/** +	 * Loads language array for the given component +	 * +	 * @param string		$component	Name of the language component +	 * @param string|array	$locale		ISO code of the language to load, or array of ISO codes if you want to +	 * 									specify additional language fallback steps +	 * @param array			$lang		Array reference containing language strings +	 */ +	public function load($component, $locale, &$lang) +	{ +		$locale = (array) $locale; + +		// Determine path to language directory +		$path = $this->phpbb_root_path . 'language/'; + +		$this->load_file($path, $component, $locale, $lang); +	} + +	/** +	 * Loads language array for the given extension component +	 * +	 * @param string		$extension	Name of the extension +	 * @param string		$component	Name of the language component +	 * @param string|array	$locale		ISO code of the language to load, or array of ISO codes if you want to +	 * 									specify additional language fallback steps +	 * @param array			$lang		Array reference containing language strings +	 */ +	public function load_extension($extension, $component, $locale, &$lang) +	{ +		// Check if extension manager was loaded +		if ($this->extension_manager === null) +		{ +			// If not, let's return +			return; +		} + +		$locale = (array) $locale; + +		// Determine path to language directory +		$path = $this->extension_manager->get_extension_path($extension, true) . 'language/'; + +		$this->load_file($path, $component, $locale, $lang); +	} + +	/** +	 * Prepares language file loading +	 * +	 * @param string	$path		Path to search for file in +	 * @param string	$component	Name of the language component +	 * @param array		$locale		Array containing language fallback options +	 * @param array		$lang		Array reference of language strings +	 */ +	protected function load_file($path, $component, $locale, &$lang) +	{ +		// This is BC stuff and not the best idea as it makes language fallback +		// implementation quite hard like below. +		if (strpos($this->phpbb_root_path . $component, $path) === 0) +		{ +			// Filter out the path +			$path_diff = str_replace($path, '', dirname($this->phpbb_root_path . $component)); +			$language_file = basename($component, '.' . $this->php_ext); +			$component = ''; + +			// This step is needed to resolve language/en/subdir style $component +			// $path already points to the language base directory so we need to eliminate +			// the first directory from the path (that should be the language directory) +			$path_diff_parts = explode('/', $path_diff); + +			if (sizeof($path_diff_parts) > 1) +			{ +				array_shift($path_diff_parts); +				$component = implode('/', $path_diff_parts) . '/'; +			} + +			$component .= $language_file; +		} + +		// Determine filename +		$filename = $component . '.' . $this->php_ext; + +		// Determine path to file +		$file_path = $this->get_language_file_path($path, $filename, $locale); + +		// Load language array +		$this->load_language_file($file_path, $lang); +	} + +	/** +	 * This function implements language fallback logic +	 * +	 * @param string	$path		Path to language directory +	 * @param string	$filename	Filename to load language strings from +	 * +	 * @return string	Relative path to language file +	 * +	 * @throws \phpbb\language\exception\language_file_not_exists	When the path to the file cannot be resolved +	 */ +	protected function get_language_file_path($path, $filename, $locales) +	{ +		// Language fallback logic +		foreach ($locales as $locale) +		{ +			$language_file_path = $path . $locale . '/' . $filename; + +			// If we are in install, try to use the updated version, when available +			if (defined('IN_INSTALL')) +			{ +				$install_language_path = str_replace('language/', 'install/update/new/language/', $language_file_path); +				if (file_exists($install_language_path)) +				{ +					return $install_language_path; +				} +			} + +			if (file_exists($language_file_path)) +			{ +				return $language_file_path; +			} +		} + +		// The language file is not exist +		throw new language_file_not_found('Language file ' . $language_file_path . ' couldn\'t be opened.'); +	} + +	/** +	 * Loads language file +	 * +	 * @param string	$path	Path to language file to load +	 * @param array		$lang	Reference of the array of language strings +	 */ +	protected function load_language_file($path, &$lang) +	{ +		// BC code for language files with help +		$help = array(); + +		// Do not suppress error if in DEBUG mode +		if (defined('DEBUG')) +		{ +			include $path; +		} +		else +		{ +			@include $path; +		} + +		if (!empty($help)) +		{ +			$lang['__help'] = array_merge($lang['__help'], $help); +		} +	} +} diff --git a/phpBB/phpbb/log/null.php b/phpBB/phpbb/log/dummy.php index baa78895ea..5c2d145e15 100644 --- a/phpBB/phpbb/log/null.php +++ b/phpBB/phpbb/log/dummy.php @@ -14,9 +14,9 @@  namespace phpbb\log;  /** -* Null logger +* Dummy logger  */ -class null implements log_interface +class dummy implements log_interface  {  	/**  	* {@inheritdoc} diff --git a/phpBB/phpbb/notification/exception.php b/phpBB/phpbb/notification/exception.php index 83c4526df7..e416438061 100644 --- a/phpBB/phpbb/notification/exception.php +++ b/phpBB/phpbb/notification/exception.php @@ -17,10 +17,6 @@ namespace phpbb\notification;  * Notifications exception  */ -class exception extends \Exception +class exception extends \phpbb\exception\runtime_exception  { -	public function __toString() -	{ -		return $this->getMessage(); -	}  } diff --git a/phpBB/phpbb/notification/manager.php b/phpBB/phpbb/notification/manager.php index db92170dd8..38d7a13165 100644 --- a/phpBB/phpbb/notification/manager.php +++ b/phpBB/phpbb/notification/manager.php @@ -943,7 +943,7 @@ class manager  		{  			if (!isset($this->notification_types[$notification_type_name]) && !isset($this->notification_types['notification.type.' . $notification_type_name]))  			{ -				throw new \phpbb\notification\exception($this->user->lang('NOTIFICATION_TYPE_NOT_EXIST', $notification_type_name)); +				throw new \phpbb\notification\exception('NOTIFICATION_TYPE_NOT_EXIST', array($notification_type_name));  			}  			$sql = 'INSERT INTO ' . $this->notification_types_table . ' ' . $this->db->sql_build_array('INSERT', array( diff --git a/phpBB/phpbb/template/asset.php b/phpBB/phpbb/template/asset.php index 4729685459..cb00f16549 100644 --- a/phpBB/phpbb/template/asset.php +++ b/phpBB/phpbb/template/asset.php @@ -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,10 +157,22 @@ 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('.') . 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))); +		// 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 ($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 = $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))); +			}  		}  		if ($urlencode) diff --git a/phpBB/phpbb/template/twig/environment.php b/phpBB/phpbb/template/twig/environment.php index 0ba7a265e4..e7b8aeab89 100644 --- a/phpBB/phpbb/template/twig/environment.php +++ b/phpBB/phpbb/template/twig/environment.php @@ -18,6 +18,9 @@ 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; @@ -40,6 +43,7 @@ class environment extends \Twig_Environment  	* 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 \Symfony\Component\DependencyInjection\ContainerInterface $container The dependency injection container  	* @param string $cache_path The path to the cache directory @@ -47,10 +51,11 @@ class environment extends \Twig_Environment  	* @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, \Symfony\Component\DependencyInjection\ContainerInterface $container, $cache_path, \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, \Symfony\Component\DependencyInjection\ContainerInterface $container, $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->container = $container; @@ -106,16 +111,26 @@ 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  	*  	* @return string diff --git a/phpBB/phpbb/template/twig/extension.php b/phpBB/phpbb/template/twig/extension.php index 14d1258c09..92f87a0331 100644 --- a/phpBB/phpbb/template/twig/extension.php +++ b/phpBB/phpbb/template/twig/extension.php @@ -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;  	}  	/** @@ -181,6 +181,6 @@ class extension extends \Twig_Extension  		// 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);  	}  } diff --git a/phpBB/phpbb/template/twig/node/includeasset.php b/phpBB/phpbb/template/twig/node/includeasset.php index 15195a226b..324823b8d7 100644 --- a/phpBB/phpbb/template/twig/node/includeasset.php +++ b/phpBB/phpbb/template/twig/node/includeasset.php @@ -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();") diff --git a/phpBB/phpbb/user.php b/phpBB/phpbb/user.php index 882e9cef26..c33070d6f4 100644 --- a/phpBB/phpbb/user.php +++ b/phpBB/phpbb/user.php @@ -21,8 +21,11 @@ namespace phpbb;  */  class user extends \phpbb\session  { -	var $lang = array(); -	var $help = array(); +	/** +	 * @var \phpbb\language\language +	 */ +	protected $language; +  	var $style = array();  	var $date_format; @@ -42,35 +45,63 @@ class user extends \phpbb\session  	var $img_lang;  	var $img_array = array(); +	/** @var bool */ +	protected $is_setup_flag; +  	// Able to add new options (up to id 31)  	var $keyoptions = array('viewimg' => 0, 'viewflash' => 1, 'viewsmilies' => 2, 'viewsigs' => 3, 'viewavatars' => 4, 'viewcensors' => 5, 'attachsig' => 6, 'bbcode' => 8, 'smilies' => 9, 'sig_bbcode' => 15, 'sig_smilies' => 16, 'sig_links' => 17);  	/**  	* Constructor to set the lang path +	*  	* @param string $datetime_class Class name of datetime class +	* @param \phpbb\language\language	$lang	phpBB's Language loader  	*/ -	function __construct($datetime_class) +	function __construct(\phpbb\language\language $lang, $datetime_class)  	{  		global $phpbb_root_path;  		$this->lang_path = $phpbb_root_path . 'language/'; +		$this->language = $lang;  		$this->datetime = $datetime_class; + +		$this->is_setup_flag = false;  	}  	/** -	* Function to set custom language path (able to use directory outside of phpBB) -	* -	* @param string $lang_path New language path used. -	* @access public -	*/ -	function set_custom_lang_path($lang_path) +	 * Returns whether user::setup was called +	 * +	 * @return bool +	 */ +	public function is_setup()  	{ -		$this->lang_path = $lang_path; +		return $this->is_setup_flag; +	} -		if (substr($this->lang_path, -1) != '/') +	/** +	 * Magic getter for BC compatibility +	 * +	 * Implement array access for user::lang. +	 * +	 * @param string	$param_name	Name of the BC component the user want to access +	 * +	 * @return array	The appropriate array +	 * +	 * @deprecated 3.2.0-dev (To be removed: 4.0.0) +	 */ +	public function __get($param_name) +	{ +		if ($param_name === 'lang') +		{ +			return $this->language->get_lang_array(); +		} +		else if ($param_name === 'help')  		{ -			$this->lang_path .= '/'; +			$help_array = $this->language->get_lang_array(); +			return $help_array['__help'];  		} + +		return array();  	}  	/** @@ -81,6 +112,8 @@ class user extends \phpbb\session  		global $db, $request, $template, $config, $auth, $phpEx, $phpbb_root_path, $cache;  		global $phpbb_dispatcher; +		$this->language->set_default_language($config['default_lang']); +  		if ($this->data['user_id'] != ANONYMOUS)  		{  			$user_lang_name = (file_exists($this->lang_path . $this->data['user_lang'] . "/common.$phpEx")) ? $this->data['user_lang'] : basename($config['default_lang']); @@ -98,6 +131,7 @@ class user extends \phpbb\session  			{  				$lang_override = $request->variable($config['cookie_name'] . '_lang', '', true, \phpbb\request\request_interface::COOKIE);  			} +  			if ($lang_override)  			{  				$use_lang = basename($lang_override); @@ -108,6 +142,7 @@ class user extends \phpbb\session  			{  				$user_lang_name = basename($config['default_lang']);  			} +  			$user_date_format = $config['default_dateformat'];  			$user_timezone = $config['board_timezone']; @@ -187,6 +222,8 @@ class user extends \phpbb\session  		$this->lang_name = $user_lang_name;  		$this->date_format = $user_date_format; +		$this->language->set_user_language($user_lang_name); +  		try  		{  			$this->timezone = new \DateTimeZone($user_timezone); @@ -197,17 +234,6 @@ class user extends \phpbb\session  			$this->timezone = new \DateTimeZone('UTC');  		} -		// We include common language file here to not load it every time a custom language file is included -		$lang = &$this->lang; - -		// Do not suppress error if in DEBUG mode -		$include_result = (defined('DEBUG')) ? (include $this->lang_path . $this->lang_name . "/common.$phpEx") : (@include $this->lang_path . $this->lang_name . "/common.$phpEx"); - -		if ($include_result === false) -		{ -			die('Language file ' . $this->lang_path . $this->lang_name . "/common.$phpEx" . " couldn't be opened."); -		} -  		$this->add_lang($lang_set);  		unset($lang_set); @@ -393,6 +419,8 @@ class user extends \phpbb\session  			}  		} +		$this->is_setup_flag = true; +  		return;  	} @@ -406,103 +434,13 @@ class user extends \phpbb\session  	*  	* If the first parameter is an array, the elements are used as keys and subkeys to get the language entry:  	* Example: <samp>$user->lang(array('datetime', 'AGO'), 1)</samp> uses $user->lang['datetime']['AGO'] as language entry. +	* +	* @deprecated 3.2.0-dev (To be removed 4.0.0)  	*/  	function lang()  	{  		$args = func_get_args(); -		$key = $args[0]; - -		if (is_array($key)) -		{ -			$lang = &$this->lang[array_shift($key)]; - -			foreach ($key as $_key) -			{ -				$lang = &$lang[$_key]; -			} -		} -		else -		{ -			$lang = &$this->lang[$key]; -		} - -		// Return if language string does not exist -		if (!isset($lang) || (!is_string($lang) && !is_array($lang))) -		{ -			return $key; -		} - -		// If the language entry is a string, we simply mimic sprintf() behaviour -		if (is_string($lang)) -		{ -			if (sizeof($args) == 1) -			{ -				return $lang; -			} - -			// Replace key with language entry and simply pass along... -			$args[0] = $lang; -			return call_user_func_array('sprintf', $args); -		} -		else if (sizeof($lang) == 0) -		{ -			// If the language entry is an empty array, we just return the language key -			return $args[0]; -		} - -		// It is an array... now handle different nullar/singular/plural forms -		$key_found = false; - -		// We now get the first number passed and will select the key based upon this number -		for ($i = 1, $num_args = sizeof($args); $i < $num_args; $i++) -		{ -			if (is_int($args[$i]) || is_float($args[$i])) -			{ -				if ($args[$i] == 0 && isset($lang[0])) -				{ -					// We allow each translation using plural forms to specify a version for the case of 0 things, -					// so that "0 users" may be displayed as "No users". -					$key_found = 0; -					break; -				} -				else -				{ -					$use_plural_form = $this->get_plural_form($args[$i]); -					if (isset($lang[$use_plural_form])) -					{ -						// The key we should use exists, so we use it. -						$key_found = $use_plural_form; -					} -					else -					{ -						// If the key we need to use does not exist, we fall back to the previous one. -						$numbers = array_keys($lang); - -						foreach ($numbers as $num) -						{ -							if ($num > $use_plural_form) -							{ -								break; -							} - -							$key_found = $num; -						} -					} -					break; -				} -			} -		} - -		// Ok, let's check if the key was found, else use the last entry (because it is mostly the plural form) -		if ($key_found === false) -		{ -			$numbers = array_keys($lang); -			$key_found = end($numbers); -		} - -		// Use the language string we determined and pass it to sprintf() -		$args[0] = $lang[$key_found]; -		return call_user_func_array('sprintf', $args); +		return call_user_func_array(array($this->language, 'lang'), $args);  	}  	/** @@ -512,24 +450,22 @@ class user extends \phpbb\session  	* @param $number        int|float   The number we want to get the plural case for. Float numbers are floored.  	* @param $force_rule    mixed   False to use the plural rule of the language package  	*                               or an integer to force a certain plural rule -	* @return   int     The plural-case we need to use for the number plural-rule combination +	* @return int|bool     The plural-case we need to use for the number plural-rule combination, false if $force_rule +	* 					   was invalid. +	* +	* @deprecated: 3.2.0-dev (To be removed: 3.3.0)  	*/  	function get_plural_form($number, $force_rule = false)  	{ -		$number = (int) $number; - -		// Default to English system -		$plural_rule = ($force_rule !== false) ? $force_rule : ((isset($this->lang['PLURAL_RULE'])) ? $this->lang['PLURAL_RULE'] : 1); - -		return phpbb_get_plural_form($plural_rule, $number); +		return $this->language->get_plural_form($number, $force_rule);  	}  	/**  	* Add Language Items - use_db and use_help are assigned where needed (only use them to force inclusion)  	*  	* @param mixed $lang_set specifies the language entries to include -	* @param bool $use_db internal variable for recursion, do not use -	* @param bool $use_help internal variable for recursion, do not use +	* @param bool $use_db internal variable for recursion, do not use	@deprecated 3.2.0-dev (To be removed: 3.3.0) +	* @param bool $use_help internal variable for recursion, do not use	@deprecated 3.2.0-dev (To be removed: 3.3.0)  	* @param string $ext_name The extension to load language from, or empty for core files  	*  	* Examples: @@ -540,11 +476,14 @@ class user extends \phpbb\session  	* $lang_set = 'posting'  	* $lang_set = array('help' => 'faq', 'db' => array('help:faq', 'posting'))  	* </code> +	* +	* Note: $use_db and $use_help should be removed. The old function was kept for BC purposes, +	* 		so the BC logic is handled here. +	* +	* @deprecated: 3.2.0-dev (To be removed: 3.3.0)  	*/  	function add_lang($lang_set, $use_db = false, $use_help = false, $ext_name = '')  	{ -		global $phpEx; -  		if (is_array($lang_set))  		{  			foreach ($lang_set as $key => $lang_file) @@ -555,6 +494,7 @@ class user extends \phpbb\session  				if ($key == 'db')  				{ +					// This is never used  					$this->add_lang($lang_file, true, $use_help, $ext_name);  				}  				else if ($key == 'help') @@ -563,7 +503,7 @@ class user extends \phpbb\session  				}  				else if (!is_array($lang_file))  				{ -					$this->set_lang($this->lang, $this->help, $lang_file, $use_db, $use_help, $ext_name); +					$this->set_lang($lang_file, $use_help, $ext_name);  				}  				else  				{ @@ -574,8 +514,37 @@ class user extends \phpbb\session  		}  		else if ($lang_set)  		{ -			$this->set_lang($this->lang, $this->help, $lang_set, $use_db, $use_help, $ext_name); +			$this->set_lang($lang_set, $use_help, $ext_name); +		} +	} + +	/** +	 * BC function for loading language files +	 * +	 * @deprecated 3.2.0-dev (To be removed: 3.3.0) +	 */ +	private function set_lang($lang_set, $use_help, $ext_name) +	{ +		if (empty($ext_name)) +		{ +			$ext_name = null; +		} + +		if ($use_help && strpos($lang_set, '/') !== false) +		{ +			$component = dirname($lang_set) . '/help_' . basename($lang_set); + +			if ($component[0] === '/') +			{ +				$component = substr($component, 1); +			} +		} +		else +		{ +			$component = (($use_help) ? 'help_' : '') . $lang_set;  		} + +		$this->language->add_lang($component, $ext_name);  	}  	/** @@ -585,6 +554,10 @@ class user extends \phpbb\session  	* @param mixed $lang_set specifies the language entries to include  	* @param bool $use_db internal variable for recursion, do not use  	* @param bool $use_help internal variable for recursion, do not use +	* +	* Note: $use_db and $use_help should be removed. Kept for BC purposes. +	* +	* @deprecated: 3.2.0-dev (To be removed: 3.3.0)  	*/  	function add_lang_ext($ext_name, $lang_set, $use_db = false, $use_help = false)  	{ @@ -597,109 +570,6 @@ class user extends \phpbb\session  	}  	/** -	* Set language entry (called by add_lang) -	* @access private -	*/ -	function set_lang(&$lang, &$help, $lang_file, $use_db = false, $use_help = false, $ext_name = '') -	{ -		global $phpbb_root_path, $phpEx; - -		// Make sure the language name is set (if the user setup did not happen it is not set) -		if (!$this->lang_name) -		{ -			global $config; -			$this->lang_name = basename($config['default_lang']); -		} - -		// $lang == $this->lang -		// $help == $this->help -		// - add appropriate variables here, name them as they are used within the language file... -		if (!$use_db) -		{ -			if ($use_help && strpos($lang_file, '/') !== false) -			{ -				$filename = dirname($lang_file) . '/help_' . basename($lang_file); -			} -			else -			{ -				$filename = (($use_help) ? 'help_' : '') . $lang_file; -			} - -			if ($ext_name) -			{ -				global $phpbb_extension_manager; -				$ext_path = $phpbb_extension_manager->get_extension_path($ext_name, true); - -				$lang_path = $ext_path . 'language/'; -			} -			else -			{ -				$lang_path = $this->lang_path; -			} - -			if (strpos($phpbb_root_path . $filename, $lang_path . $this->lang_name . '/') === 0) -			{ -				$language_filename = $phpbb_root_path . $filename; -			} -			else -			{ -				$language_filename = $lang_path . $this->lang_name . '/' . $filename . '.' . $phpEx; -			} - -			// If we are in install, try to use the updated version, when available -			$install_language_filename = str_replace('language/', 'install/update/new/language/', $language_filename); -			if (defined('IN_INSTALL') && file_exists($install_language_filename)) -			{ -				$language_filename = $install_language_filename; -			} - -			if (!file_exists($language_filename)) -			{ -				global $config; - -				if ($this->lang_name == 'en') -				{ -					// The user's selected language is missing the file, the board default's language is missing the file, and the file doesn't exist in /en. -					$language_filename = str_replace($lang_path . 'en', $lang_path . $this->data['user_lang'], $language_filename); -					trigger_error('Language file ' . $language_filename . ' couldn\'t be opened.', E_USER_ERROR); -				} -				else if ($this->lang_name == basename($config['default_lang'])) -				{ -					// Fall back to the English Language -					$reset_lang_name = $this->lang_name; -					$this->lang_name = 'en'; -					$this->set_lang($lang, $help, $lang_file, $use_db, $use_help, $ext_name); -					$this->lang_name = $reset_lang_name; -				} -				else if ($this->lang_name == $this->data['user_lang']) -				{ -					// Fall back to the board default language -					$reset_lang_name = $this->lang_name; -					$this->lang_name = basename($config['default_lang']); -					$this->set_lang($lang, $help, $lang_file, $use_db, $use_help, $ext_name); -					$this->lang_name = $reset_lang_name; -				} - -				return; -			} - -			// Do not suppress error if in DEBUG mode -			$include_result = (defined('DEBUG')) ? (include $language_filename) : (@include $language_filename); - -			if ($include_result === false) -			{ -				trigger_error('Language file ' . $language_filename . ' couldn\'t be opened.', E_USER_ERROR); -			} -		} -		else if ($use_db) -		{ -			// Get Database Language Strings -			// Put them into $lang if nothing is prefixed, put them into $help if help: is prefixed -			// For example: help:faq, posting -		} -	} - -	/**  	* Format user date  	*  	* @param int $gmepoch unix timestamp @@ -808,7 +678,7 @@ class user extends \phpbb\session  		if ($alt)  		{ -			$alt = $this->lang($alt); +			$alt = $this->language->lang($alt);  			$title = ' title="' . $alt . '"';  		}  		return '<span class="imageset ' . $img . '"' . $title . '>' . $alt . '</span>'; | 
