diff options
Diffstat (limited to 'phpBB/phpbb/avatar/driver')
| -rw-r--r-- | phpBB/phpbb/avatar/driver/driver.php | 131 | ||||
| -rw-r--r-- | phpBB/phpbb/avatar/driver/driver_interface.php | 113 | ||||
| -rw-r--r-- | phpBB/phpbb/avatar/driver/gravatar.php | 185 | ||||
| -rw-r--r-- | phpBB/phpbb/avatar/driver/local.php | 201 | ||||
| -rw-r--r-- | phpBB/phpbb/avatar/driver/remote.php | 221 | ||||
| -rw-r--r-- | phpBB/phpbb/avatar/driver/upload.php | 214 | 
6 files changed, 1065 insertions, 0 deletions
diff --git a/phpBB/phpbb/avatar/driver/driver.php b/phpBB/phpbb/avatar/driver/driver.php new file mode 100644 index 0000000000..b3ced7edf7 --- /dev/null +++ b/phpBB/phpbb/avatar/driver/driver.php @@ -0,0 +1,131 @@ +<?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\avatar\driver; + +/** +* Base class for avatar drivers +*/ +abstract class driver implements \phpbb\avatar\driver\driver_interface +{ +	/** +	* Avatar driver name +	* @var string +	*/ +	protected $name; + +	/** +	* Current board configuration +	* @var \phpbb\config\config +	*/ +	protected $config; + +	/** +	* Current $phpbb_root_path +	* @var string +	*/ +	protected $phpbb_root_path; + +	/** +	* Current $php_ext +	* @var string +	*/ +	protected $php_ext; + +	/** +	* Path Helper +	* @var \phpbb\path_helper +	*/ +	protected $path_helper; + +	/** +	* Cache driver +	* @var \phpbb\cache\driver\driver_interface +	*/ +	protected $cache; + +	/** +	* Array of allowed avatar image extensions +	* Array is used for setting the allowed extensions in the fileupload class +	* and as a base for a regex of allowed extensions, which will be formed by +	* imploding the array with a "|". +	* +	* @var array +	*/ +	protected $allowed_extensions = array( +		'gif', +		'jpg', +		'jpeg', +		'png', +	); + +	/** +	* Construct a driver object +	* +	* @param \phpbb\config\config $config phpBB configuration +	* @param string $phpbb_root_path Path to the phpBB root +	* @param string $php_ext PHP file extension +	* @param \phpbb\path_helper $path_helper phpBB path helper +	* @param \phpbb\cache\driver\driver_interface $cache Cache driver +	*/ +	public function __construct(\phpbb\config\config $config, $phpbb_root_path, $php_ext, \phpbb\path_helper $path_helper, \phpbb\cache\driver\driver_interface $cache = null) +	{ +		$this->config = $config; +		$this->phpbb_root_path = $phpbb_root_path; +		$this->php_ext = $php_ext; +		$this->path_helper = $path_helper; +		$this->cache = $cache; +	} + +	/** +	* {@inheritdoc} +	*/ +	public function get_custom_html($user, $row, $alt = '') +	{ +		return ''; +	} + +	/** +	* {@inheritdoc} +	*/ +	public function prepare_form_acp($user) +	{ +		return array(); +	} + +	/** +	* {@inheritdoc} +	*/ +	public function delete($row) +	{ +		return true; +	} + +	/** +	* {@inheritdoc} +	*/ +	public function get_name() +	{ +		return $this->name; +	} + +	/** +	* Sets the name of the driver. +	* +	* @param string	$name Driver name +	*/ +	public function set_name($name) +	{ +		$this->name = $name; +	} +} diff --git a/phpBB/phpbb/avatar/driver/driver_interface.php b/phpBB/phpbb/avatar/driver/driver_interface.php new file mode 100644 index 0000000000..835609745a --- /dev/null +++ b/phpBB/phpbb/avatar/driver/driver_interface.php @@ -0,0 +1,113 @@ +<?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\avatar\driver; + +/** +* Interface for avatar drivers +*/ +interface driver_interface +{ +	/** +	* Returns the name of the driver. +	* +	* @return string	Name of driver. +	*/ +	public function get_name(); + +	/** +	* Get the avatar url and dimensions +	* +	* @param array	$row User data or group data that has been cleaned with +	*        \phpbb\avatar\manager::clean_row +	* @return array Avatar data, must have keys src, width and height, e.g. +	*        ['src' => '', 'width' => 0, 'height' => 0] +	*/ +	public function get_data($row); + +	/** +	* Returns custom html if it is needed for displaying this avatar +	* +	* @param \phpbb\user $user phpBB user object +	* @param array	$row User data or group data that has been cleaned with +	*        \phpbb\avatar\manager::clean_row +	* @param string $alt Alternate text for avatar image +	* +	* @return string HTML +	*/ +	public function get_custom_html($user, $row, $alt = ''); + +	/** +	* Prepare form for changing the settings of this avatar +	* +	* @param \phpbb\request\request $request Request object +	* @param \phpbb\template\template	$template Template object +	* @param \phpbb\user $user User object +	* @param array	$row User data or group data that has been cleaned with +	*        \phpbb\avatar\manager::clean_row +	* @param array	&$error Reference to an error array that is filled by this +	*        function. Key values can either be a string with a language key or +	*        an array that will be passed to vsprintf() with the language key in +	*        the first array key. +	* +	* @return bool True if form has been successfully prepared +	*/ +	public function prepare_form($request, $template, $user, $row, &$error); + +	/** +	* Prepare form for changing the acp settings of this avatar +	* +	* @param \phpbb\user $user phpBB user object +	* +	* @return array Array of configuration options as consumed by acp_board. +	*        The setting for enabling/disabling the avatar will be handled by +	*        the avatar manager. +	*/ +	public function prepare_form_acp($user); + +	/** +	* Process form data +	* +	* @param \phpbb\request\request $request Request object +	* @param \phpbb\template\template	$template Template object +	* @param \phpbb\user $user User object +	* @param array	$row User data or group data that has been cleaned with +	*        \phpbb\avatar\manager::clean_row +	* @param array	&$error Reference to an error array that is filled by this +	*        function. Key values can either be a string with a language key or +	*        an array that will be passed to vsprintf() with the language key in +	*        the first array key. +	* +	* @return array Array containing the avatar data as follows: +	*        ['avatar'], ['avatar_width'], ['avatar_height'] +	*/ +	public function process_form($request, $template, $user, $row, &$error); + +	/** +	* Delete avatar +	* +	* @param array $row User data or group data that has been cleaned with +	*        \phpbb\avatar\manager::clean_row +	* +	* @return bool True if avatar has been deleted or there is no need to delete, +	*        i.e. when the avatar is not hosted locally. +	*/ +	public function delete($row); + +	/** +	* Get the avatar driver's template name +	* +	* @return string Avatar driver's template name +	*/ +	public function get_template_name(); +} diff --git a/phpBB/phpbb/avatar/driver/gravatar.php b/phpBB/phpbb/avatar/driver/gravatar.php new file mode 100644 index 0000000000..2082e0fd02 --- /dev/null +++ b/phpBB/phpbb/avatar/driver/gravatar.php @@ -0,0 +1,185 @@ +<?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\avatar\driver; + +/** +* Handles avatars hosted at gravatar.com +*/ +class gravatar extends \phpbb\avatar\driver\driver +{ +	/** +	* The URL for the gravatar service +	*/ +	const GRAVATAR_URL = '//secure.gravatar.com/avatar/'; + +	/** +	* {@inheritdoc} +	*/ +	public function get_data($row) +	{ +		return array( +			'src' => $row['avatar'], +			'width' => $row['avatar_width'], +			'height' => $row['avatar_height'], +		); +	} + +	/** +	* {@inheritdoc} +	*/ +	public function get_custom_html($user, $row, $alt = '') +	{ +		return '<img src="' . $this->get_gravatar_url($row) . '" ' . +			($row['avatar_width'] ? ('width="' . $row['avatar_width'] . '" ') : '') . +			($row['avatar_height'] ? ('height="' . $row['avatar_height'] . '" ') : '') . +			'alt="' . ((!empty($user->lang[$alt])) ? $user->lang[$alt] : $alt) . '" />'; +	} + +	/** +	* {@inheritdoc} +	*/ +	public function prepare_form($request, $template, $user, $row, &$error) +	{ +		$template->assign_vars(array( +			'AVATAR_GRAVATAR_WIDTH' => (($row['avatar_type'] == $this->get_name() || $row['avatar_type'] == 'gravatar') && $row['avatar_width']) ? $row['avatar_width'] : $request->variable('avatar_gravatar_width', 0), +			'AVATAR_GRAVATAR_HEIGHT' => (($row['avatar_type'] == $this->get_name() || $row['avatar_type'] == 'gravatar') && $row['avatar_height']) ? $row['avatar_height'] : $request->variable('avatar_gravatar_width', 0), +			'AVATAR_GRAVATAR_EMAIL' => (($row['avatar_type'] == $this->get_name() || $row['avatar_type'] == 'gravatar') && $row['avatar']) ? $row['avatar'] : '', +		)); + +		return true; +	} + +	/** +	* {@inheritdoc} +	*/ +	public function process_form($request, $template, $user, $row, &$error) +	{ +		$row['avatar'] = $request->variable('avatar_gravatar_email', ''); +		$row['avatar_width'] = $request->variable('avatar_gravatar_width', 0); +		$row['avatar_height'] = $request->variable('avatar_gravatar_height', 0); + +		if (empty($row['avatar'])) +		{ +			return false; +		} + +		if (!function_exists('validate_data')) +		{ +			require($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext); +		} + +		$validate_array = validate_data( +			array( +				'email' => $row['avatar'], +			), +			array( +				'email' => array( +					array('string', false, 6, 60), +					array('email'), +				), +			) +		); + +		$error = array_merge($error, $validate_array); + +		if (!empty($error)) +		{ +			return false; +		} + +		// Make sure getimagesize works... +		if (function_exists('getimagesize') && ($row['avatar_width'] <= 0 || $row['avatar_height'] <= 0)) +		{ +			/** +			* default to the minimum of the maximum allowed avatar size if the size +			* is not or only partially entered +			*/ +			$row['avatar_width'] = $row['avatar_height'] = min($this->config['avatar_max_width'], $this->config['avatar_max_height']); +			$url = $this->get_gravatar_url($row); + +			if (($row['avatar_width'] <= 0 || $row['avatar_height'] <= 0) && (($image_data = getimagesize($url)) === false)) +			{ +				$error[] = 'UNABLE_GET_IMAGE_SIZE'; +				return false; +			} + +			if (!empty($image_data) && ($image_data[0] <= 0 || $image_data[1] <= 0)) +			{ +				$error[] = 'AVATAR_NO_SIZE'; +				return false; +			} + +			$row['avatar_width'] = ($row['avatar_width'] && $row['avatar_height']) ? $row['avatar_width'] : $image_data[0]; +			$row['avatar_height'] = ($row['avatar_width'] && $row['avatar_height']) ? $row['avatar_height'] : $image_data[1]; +		} + +		if ($row['avatar_width'] <= 0 || $row['avatar_height'] <= 0) +		{ +			$error[] = 'AVATAR_NO_SIZE'; +			return false; +		} + +		if ($this->config['avatar_max_width'] || $this->config['avatar_max_height']) +		{ +			if ($row['avatar_width'] > $this->config['avatar_max_width'] || $row['avatar_height'] > $this->config['avatar_max_height']) +			{ +				$error[] = array('AVATAR_WRONG_SIZE', $this->config['avatar_min_width'], $this->config['avatar_min_height'], $this->config['avatar_max_width'], $this->config['avatar_max_height'], $row['avatar_width'], $row['avatar_height']); +				return false; +			} +		} + +		if ($this->config['avatar_min_width'] || $this->config['avatar_min_height']) +		{ +			if ($row['avatar_width'] < $this->config['avatar_min_width'] || $row['avatar_height'] < $this->config['avatar_min_height']) +			{ +				$error[] = array('AVATAR_WRONG_SIZE', $this->config['avatar_min_width'], $this->config['avatar_min_height'], $this->config['avatar_max_width'], $this->config['avatar_max_height'], $row['avatar_width'], $row['avatar_height']); +				return false; +			} +		} + +		return array( +			'avatar' => $row['avatar'], +			'avatar_width' => $row['avatar_width'], +			'avatar_height' => $row['avatar_height'], +		); +	} + +	/** +	* {@inheritdoc} +	*/ +	public function get_template_name() +	{ +		return 'ucp_avatar_options_gravatar.html'; +	} + +	/** +	* Build gravatar URL for output on page +	* +	* @param array $row User data or group data that has been cleaned with +	*        \phpbb\avatar\manager::clean_row +	* @return string Gravatar URL +	*/ +	protected function get_gravatar_url($row) +	{ +		$url = self::GRAVATAR_URL; +		$url .=  md5(strtolower(trim($row['avatar']))); + +		if ($row['avatar_width'] || $row['avatar_height']) +		{ +			$url .= '?s=' . max($row['avatar_width'], $row['avatar_height']); +		} + +		return $url; +	} +} diff --git a/phpBB/phpbb/avatar/driver/local.php b/phpBB/phpbb/avatar/driver/local.php new file mode 100644 index 0000000000..8888686b2d --- /dev/null +++ b/phpBB/phpbb/avatar/driver/local.php @@ -0,0 +1,201 @@ +<?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\avatar\driver; + +/** +* Handles avatars selected from the board gallery +*/ +class local extends \phpbb\avatar\driver\driver +{ +	/** +	* {@inheritdoc} +	*/ +	public function get_data($row) +	{ +		return array( +			'src' => $this->path_helper->get_web_root_path() . $this->config['avatar_gallery_path'] . '/' . $row['avatar'], +			'width' => $row['avatar_width'], +			'height' => $row['avatar_height'], +		); +	} + +	/** +	* {@inheritdoc} +	*/ +	public function prepare_form($request, $template, $user, $row, &$error) +	{ +		$avatar_list = $this->get_avatar_list($user); +		$category = $request->variable('avatar_local_cat', key($avatar_list)); + +		foreach ($avatar_list as $cat => $null) +		{ +			if (!empty($avatar_list[$cat])) +			{ +				$template->assign_block_vars('avatar_local_cats', array( +					'NAME' => $cat, +					'SELECTED' => ($cat == $category), +				)); +			} + +			if ($cat != $category) +			{ +				unset($avatar_list[$cat]); +			} +		} + +		if (!empty($avatar_list[$category])) +		{ +			$template->assign_vars(array( +				'AVATAR_LOCAL_SHOW' => true, +			)); + +			$table_cols = isset($row['avatar_gallery_cols']) ? $row['avatar_gallery_cols'] : 4; +			$row_count = $col_count = $avatar_pos = 0; +			$avatar_count = sizeof($avatar_list[$category]); + +			reset($avatar_list[$category]); + +			while ($avatar_pos < $avatar_count) +			{ +				$img = current($avatar_list[$category]); +				next($avatar_list[$category]); + +				if ($col_count == 0) +				{ +					++$row_count; +					$template->assign_block_vars('avatar_local_row', array( +					)); +				} + +				$template->assign_block_vars('avatar_local_row.avatar_local_col', array( +					'AVATAR_IMAGE'  => $this->phpbb_root_path . $this->config['avatar_gallery_path'] . '/' . $img['file'], +					'AVATAR_NAME' 	=> $img['name'], +					'AVATAR_FILE' 	=> $img['filename'], +				)); + +				$template->assign_block_vars('avatar_local_row.avatar_local_option', array( +					'AVATAR_FILE' 		=> $img['filename'], +					'S_OPTIONS_AVATAR'	=> $img['filename'] +				)); + +				$col_count = ($col_count + 1) % $table_cols; + +				++$avatar_pos; +			} +		} + +		return true; +	} + +	/** +	* {@inheritdoc} +	*/ +	public function prepare_form_acp($user) +	{ +		return array( +			'avatar_gallery_path'	=> array('lang' => 'AVATAR_GALLERY_PATH',	'validate' => 'rpath',	'type' => 'text:20:255', 'explain' => true), +		); +	} + +	/** +	* {@inheritdoc} +	*/ +	public function process_form($request, $template, $user, $row, &$error) +	{ +		$avatar_list = $this->get_avatar_list($user); +		$category = $request->variable('avatar_local_cat', ''); + +		$file = $request->variable('avatar_local_file', ''); + +		if (empty($category) || empty($file)) +		{ +			return false; +		} + +		if (!isset($avatar_list[$category][urldecode($file)])) +		{ +			$error[] = 'AVATAR_URL_NOT_FOUND'; +			return false; +		} + +		return array( +			'avatar' => ($category != $user->lang['NO_AVATAR_CATEGORY']) ? $category . '/' . $file : $file, +			'avatar_width' => $avatar_list[$category][urldecode($file)]['width'], +			'avatar_height' => $avatar_list[$category][urldecode($file)]['height'], +		); +	} + +	/** +	* {@inheritdoc} +	*/ +	public function get_template_name() +	{ +		return 'ucp_avatar_options_local.html'; +	} + +	/** +	* Get a list of avatars that are locally available +	* Results get cached for 24 hours (86400 seconds) +	* +	* @param \phpbb\user $user User object +	* +	* @return array Array containing the locally available avatars +	*/ +	protected function get_avatar_list($user) +	{ +		$avatar_list = ($this->cache == null) ? false : $this->cache->get('_avatar_local_list'); + +		if ($avatar_list === false) +		{ +			$avatar_list = array(); +			$path = $this->phpbb_root_path . $this->config['avatar_gallery_path']; + +			$iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::UNIX_PATHS), \RecursiveIteratorIterator::SELF_FIRST); +			foreach ($iterator as $file_info) +			{ +				$file_path = $file_info->getPath(); +				$image = $file_info->getFilename(); + +				// Match all images in the gallery folder +				if (preg_match('#^[^&\'"<>]+\.(?:' . implode('|', $this->allowed_extensions) . ')$#i', $image) && is_file($file_path . '/' . $image)) +				{ +					if (function_exists('getimagesize')) +					{ +						$dims = getimagesize($file_path . '/' . $image); +					} +					else +					{ +						$dims = array(0, 0); +					} +					$cat = ($path == $file_path) ? $user->lang['NO_AVATAR_CATEGORY'] : str_replace("$path/", '', $file_path); +					$avatar_list[$cat][$image] = array( +						'file'      => ($cat != $user->lang['NO_AVATAR_CATEGORY']) ? rawurlencode($cat) . '/' . rawurlencode($image) : rawurlencode($image), +						'filename'  => rawurlencode($image), +						'name'      => ucfirst(str_replace('_', ' ', preg_replace('#^(.*)\..*$#', '\1', $image))), +						'width'     => $dims[0], +						'height'    => $dims[1], +					); +				} +			} +			ksort($avatar_list); + +			if ($this->cache != null) +			{ +				$this->cache->put('_avatar_local_list', $avatar_list, 86400); +			} +		} + +		return $avatar_list; +	} +} diff --git a/phpBB/phpbb/avatar/driver/remote.php b/phpBB/phpbb/avatar/driver/remote.php new file mode 100644 index 0000000000..4b0ee3f06f --- /dev/null +++ b/phpBB/phpbb/avatar/driver/remote.php @@ -0,0 +1,221 @@ +<?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\avatar\driver; + +/** +* Handles avatars hosted remotely +*/ +class remote extends \phpbb\avatar\driver\driver +{ +	/** +	* {@inheritdoc} +	*/ +	public function get_data($row) +	{ +		return array( +			'src' => $row['avatar'], +			'width' => $row['avatar_width'], +			'height' => $row['avatar_height'], +		); +	} + +	/** +	* {@inheritdoc} +	*/ +	public function prepare_form($request, $template, $user, $row, &$error) +	{ +		$template->assign_vars(array( +			'AVATAR_REMOTE_WIDTH' => ((in_array($row['avatar_type'], array(AVATAR_REMOTE, $this->get_name(), 'remote'))) && $row['avatar_width']) ? $row['avatar_width'] : $request->variable('avatar_remote_width', 0), +			'AVATAR_REMOTE_HEIGHT' => ((in_array($row['avatar_type'], array(AVATAR_REMOTE, $this->get_name(), 'remote'))) && $row['avatar_height']) ? $row['avatar_height'] : $request->variable('avatar_remote_width', 0), +			'AVATAR_REMOTE_URL' => ((in_array($row['avatar_type'], array(AVATAR_REMOTE, $this->get_name(), 'remote'))) && $row['avatar']) ? $row['avatar'] : '', +		)); + +		return true; +	} + +	/** +	* {@inheritdoc} +	*/ +	public function process_form($request, $template, $user, $row, &$error) +	{ +		$url = $request->variable('avatar_remote_url', ''); +		$width = $request->variable('avatar_remote_width', 0); +		$height = $request->variable('avatar_remote_height', 0); + +		if (empty($url)) +		{ +			return false; +		} + +		if (!preg_match('#^(http|https|ftp)://#i', $url)) +		{ +			$url = 'http://' . $url; +		} + +		if (!function_exists('validate_data')) +		{ +			require($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext); +		} + +		$validate_array = validate_data( +			array( +				'url' => $url, +			), +			array( +				'url' => array('string', true, 5, 255), +			) +		); + +		$error = array_merge($error, $validate_array); + +		if (!empty($error)) +		{ +			return false; +		} + +		// Check if this url looks alright +		// This isn't perfect, but it's what phpBB 3.0 did, and might as well make sure everything is compatible +		if (!preg_match('#^(http|https|ftp)://(?:(.*?\.)*?[a-z0-9\-]+?\.[a-z]{2,4}|(?:\d{1,3}\.){3,5}\d{1,3}):?([0-9]*?).*?\.('. implode('|', $this->allowed_extensions) . ')$#i', $url)) +		{ +			$error[] = 'AVATAR_URL_INVALID'; +			return false; +		} + +		// Make sure getimagesize works... +		if (function_exists('getimagesize')) +		{ +			if (($width <= 0 || $height <= 0) && (($image_data = @getimagesize($url)) === false)) +			{ +				$error[] = 'UNABLE_GET_IMAGE_SIZE'; +				return false; +			} + +			if (!empty($image_data) && ($image_data[0] <= 0 || $image_data[1] <= 0)) +			{ +				$error[] = 'AVATAR_NO_SIZE'; +				return false; +			} + +			$width = ($width && $height) ? $width : $image_data[0]; +			$height = ($width && $height) ? $height : $image_data[1]; +		} + +		if ($width <= 0 || $height <= 0) +		{ +			$error[] = 'AVATAR_NO_SIZE'; +			return false; +		} + +		if (!class_exists('fileupload')) +		{ +			include($this->phpbb_root_path . 'includes/functions_upload.' . $this->php_ext); +		} + +		$types = \fileupload::image_types(); +		$extension = strtolower(\filespec::get_extension($url)); + +		// Check if this is actually an image +		if ($file_stream = @fopen($url, 'r')) +		{ +			// Timeout after 1 second +			stream_set_timeout($file_stream, 1); +			// read some data to ensure headers are present +			fread($file_stream, 1024); +			$meta = stream_get_meta_data($file_stream); + +			if (isset($meta['wrapper_data']['headers']) && is_array($meta['wrapper_data']['headers'])) +			{ +				$headers = $meta['wrapper_data']['headers']; +			} +			else if (isset($meta['wrapper_data']) && is_array($meta['wrapper_data'])) +			{ +				$headers = $meta['wrapper_data']; +			} +			else +			{ +				$headers = array(); +			} + +			foreach ($headers as $header) +			{ +				$header = preg_split('/ /', $header, 2); +				if (strtr(strtolower(trim($header[0], ':')), '_', '-') === 'content-type') +				{ +					if (strpos($header[1], 'image/') !== 0) +					{ +						$error[] = 'AVATAR_URL_INVALID'; +						fclose($file_stream); +						return false; +					} +					else +					{ +						fclose($file_stream); +						break; +					} +				} +			} +		} +		else +		{ +			$error[] = 'AVATAR_URL_INVALID'; +			return false; +		} + +		if (!empty($image_data) && (!isset($types[$image_data[2]]) || !in_array($extension, $types[$image_data[2]]))) +		{ +			if (!isset($types[$image_data[2]])) +			{ +				$error[] = 'UNABLE_GET_IMAGE_SIZE'; +			} +			else +			{ +				$error[] = array('IMAGE_FILETYPE_MISMATCH', $types[$image_data[2]][0], $extension); +			} + +			return false; +		} + +		if ($this->config['avatar_max_width'] || $this->config['avatar_max_height']) +		{ +			if ($width > $this->config['avatar_max_width'] || $height > $this->config['avatar_max_height']) +			{ +				$error[] = array('AVATAR_WRONG_SIZE', $this->config['avatar_min_width'], $this->config['avatar_min_height'], $this->config['avatar_max_width'], $this->config['avatar_max_height'], $width, $height); +				return false; +			} +		} + +		if ($this->config['avatar_min_width'] || $this->config['avatar_min_height']) +		{ +			if ($width < $this->config['avatar_min_width'] || $height < $this->config['avatar_min_height']) +			{ +				$error[] = array('AVATAR_WRONG_SIZE', $this->config['avatar_min_width'], $this->config['avatar_min_height'], $this->config['avatar_max_width'], $this->config['avatar_max_height'], $width, $height); +				return false; +			} +		} + +		return array( +			'avatar' => $url, +			'avatar_width' => $width, +			'avatar_height' => $height, +		); +	} + +	/** +	* {@inheritdoc} +	*/ +	public function get_template_name() +	{ +		return 'ucp_avatar_options_remote.html'; +	} +} diff --git a/phpBB/phpbb/avatar/driver/upload.php b/phpBB/phpbb/avatar/driver/upload.php new file mode 100644 index 0000000000..003b23659f --- /dev/null +++ b/phpBB/phpbb/avatar/driver/upload.php @@ -0,0 +1,214 @@ +<?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\avatar\driver; + +/** +* Handles avatars uploaded to the board +*/ +class upload extends \phpbb\avatar\driver\driver +{ +	/** +	* @var \phpbb\mimetype\guesser +	*/ +	protected $mimetype_guesser; + +	/** +	* Construct a driver object +	* +	* @param \phpbb\config\config $config phpBB configuration +	* @param string $phpbb_root_path Path to the phpBB root +	* @param string $php_ext PHP file extension +	* @param \phpbb_path_helper $path_helper phpBB path helper +	* @param \phpbb\mimetype\guesser $mimetype_guesser Mimetype guesser +	* @param \phpbb\cache\driver\driver_interface $cache Cache driver +	*/ +	public function __construct(\phpbb\config\config $config, $phpbb_root_path, $php_ext, \phpbb\path_helper $path_helper, \phpbb\mimetype\guesser $mimetype_guesser, \phpbb\cache\driver\driver_interface $cache = null) +	{ +		$this->config = $config; +		$this->phpbb_root_path = $phpbb_root_path; +		$this->php_ext = $php_ext; +		$this->path_helper = $path_helper; +		$this->mimetype_guesser = $mimetype_guesser; +		$this->cache = $cache; +	} + +	/** +	* {@inheritdoc} +	*/ +	public function get_data($row, $ignore_config = false) +	{ +		return array( +			'src' => $this->path_helper->get_web_root_path() . 'download/file.' . $this->php_ext . '?avatar=' . $row['avatar'], +			'width' => $row['avatar_width'], +			'height' => $row['avatar_height'], +		); +	} + +	/** +	* {@inheritdoc} +	*/ +	public function prepare_form($request, $template, $user, $row, &$error) +	{ +		if (!$this->can_upload()) +		{ +			return false; +		} + +		$template->assign_vars(array( +			'S_UPLOAD_AVATAR_URL' => ($this->config['allow_avatar_remote_upload']) ? true : false, +			'AVATAR_UPLOAD_SIZE' => $this->config['avatar_filesize'], +		)); + +		return true; +	} + +	/** +	* {@inheritdoc} +	*/ +	public function process_form($request, $template, $user, $row, &$error) +	{ +		if (!$this->can_upload()) +		{ +			return false; +		} + +		if (!class_exists('fileupload')) +		{ +			include($this->phpbb_root_path . 'includes/functions_upload.' . $this->php_ext); +		} + +		$upload = new \fileupload('AVATAR_', $this->allowed_extensions, $this->config['avatar_filesize'], $this->config['avatar_min_width'], $this->config['avatar_min_height'], $this->config['avatar_max_width'], $this->config['avatar_max_height'], (isset($this->config['mime_triggers']) ? explode('|', $this->config['mime_triggers']) : false)); + +		$url = $request->variable('avatar_upload_url', ''); +		$upload_file = $request->file('avatar_upload_file'); + +		if (!empty($upload_file['name'])) +		{ +			$file = $upload->form_upload('avatar_upload_file', $this->mimetype_guesser); +		} +		else if (!empty($this->config['allow_avatar_remote_upload']) && !empty($url)) +		{ +			if (!preg_match('#^(http|https|ftp)://#i', $url)) +			{ +				$url = 'http://' . $url; +			} + +			if (!function_exists('validate_data')) +			{ +				require($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext); +			} + +			$validate_array = validate_data( +				array( +					'url' => $url, +				), +				array( +					'url' => array('string', true, 5, 255), +				) +			); + +			$error = array_merge($error, $validate_array); + +			if (!empty($error)) +			{ +				return false; +			} + +			$file = $upload->remote_upload($url, $this->mimetype_guesser); +		} +		else +		{ +			return false; +		} + +		$prefix = $this->config['avatar_salt'] . '_'; +		$file->clean_filename('avatar', $prefix, $row['id']); + +		$destination = $this->config['avatar_path']; + +		// Adjust destination path (no trailing slash) +		if (substr($destination, -1, 1) == '/' || substr($destination, -1, 1) == '\\') +		{ +			$destination = substr($destination, 0, -1); +		} + +		$destination = str_replace(array('../', '..\\', './', '.\\'), '', $destination); +		if ($destination && ($destination[0] == '/' || $destination[0] == "\\")) +		{ +			$destination = ''; +		} + +		// Move file and overwrite any existing image +		$file->move_file($destination, true); + +		if (sizeof($file->error)) +		{ +			$file->remove(); +			$error = array_merge($error, $file->error); +			return false; +		} + +		return array( +			'avatar' => $row['id'] . '_' . time() . '.' . $file->get('extension'), +			'avatar_width' => $file->get('width'), +			'avatar_height' => $file->get('height'), +		); +	} + +	/** +	* {@inheritdoc} +	*/ +	public function prepare_form_acp($user) +	{ +		return array( +			'allow_avatar_remote_upload'=> array('lang' => 'ALLOW_REMOTE_UPLOAD', 'validate' => 'bool',	'type' => 'radio:yes_no', 'explain' => true), +			'avatar_filesize'		=> array('lang' => 'MAX_FILESIZE',			'validate' => 'int:0',	'type' => 'number:0', 'explain' => true, 'append' => ' ' . $user->lang['BYTES']), +			'avatar_path'			=> array('lang' => 'AVATAR_STORAGE_PATH',	'validate' => 'rpath',	'type' => 'text:20:255', 'explain' => true), +		); +	} + +	/** +	* {@inheritdoc} +	*/ +	public function delete($row) +	{ +		$ext = substr(strrchr($row['avatar'], '.'), 1); +		$filename = $this->phpbb_root_path . $this->config['avatar_path'] . '/' . $this->config['avatar_salt'] . '_' . $row['id'] . '.' . $ext; + +		if (file_exists($filename)) +		{ +			@unlink($filename); +		} + +		return true; +	} + +	/** +	* {@inheritdoc} +	*/ +	public function get_template_name() +	{ +		return 'ucp_avatar_options_upload.html'; +	} + +	/** +	* Check if user is able to upload an avatar +	* +	* @return bool True if user can upload, false if not +	*/ +	protected function can_upload() +	{ +		return (file_exists($this->phpbb_root_path . $this->config['avatar_path']) && phpbb_is_writable($this->phpbb_root_path . $this->config['avatar_path']) && (@ini_get('file_uploads') || strtolower(@ini_get('file_uploads')) == 'on')); +	} +}  | 
