diff options
Diffstat (limited to 'phpBB/includes/avatar')
| -rw-r--r-- | phpBB/includes/avatar/driver/driver.php | 138 | ||||
| -rw-r--r-- | phpBB/includes/avatar/driver/gravatar.php | 172 | ||||
| -rw-r--r-- | phpBB/includes/avatar/driver/interface.php | 116 | ||||
| -rw-r--r-- | phpBB/includes/avatar/driver/local.php | 197 | ||||
| -rw-r--r-- | phpBB/includes/avatar/driver/remote.php | 164 | ||||
| -rw-r--r-- | phpBB/includes/avatar/driver/upload.php | 159 | ||||
| -rw-r--r-- | phpBB/includes/avatar/manager.php | 309 | 
7 files changed, 1255 insertions, 0 deletions
diff --git a/phpBB/includes/avatar/driver/driver.php b/phpBB/includes/avatar/driver/driver.php new file mode 100644 index 0000000000..29c58d4e62 --- /dev/null +++ b/phpBB/includes/avatar/driver/driver.php @@ -0,0 +1,138 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ +	exit; +} + +/** +* Base class for avatar drivers +* @package phpBB3 +*/ +abstract class phpbb_avatar_driver implements phpbb_avatar_driver_interface +{ +	/** +	* Avatar driver name +	* @var string +	*/ +	protected $name; + +	/** +	* Current board configuration +	* @var phpbb_config +	*/ +	protected $config; + +	/** +	* Current $phpbb_root_path +	* @var string +	*/ +	protected $phpbb_root_path; + +	/** +	* Current $php_ext +	* @var string +	*/ +	protected $php_ext; + +	/** +	* Cache driver +	* @var phpbb_cache_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 phpBB configuration +	* @param phpbb_request $request Request object +	* @param string $phpbb_root_path Path to the phpBB root +	* @param string $php_ext PHP file extension +	* @param phpbb_cache_driver_interface $cache Cache driver +	*/ +	public function __construct(phpbb_config $config, $phpbb_root_path, $php_ext, phpbb_cache_driver_interface $cache = null) +	{ +		$this->config = $config; +		$this->phpbb_root_path = $phpbb_root_path; +		$this->php_ext = $php_ext; +		$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_template_name() +	{ +		$driver = preg_replace('#^phpbb_avatar_driver_#', '', get_class($this)); +		$template = "ucp_avatar_options_$driver.html"; + +		return $template; +	} + +	/** +	* @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/includes/avatar/driver/gravatar.php b/phpBB/includes/avatar/driver/gravatar.php new file mode 100644 index 0000000000..d559da1c0d --- /dev/null +++ b/phpBB/includes/avatar/driver/gravatar.php @@ -0,0 +1,172 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ +	exit; +} + +/** +* Handles avatars hosted at gravatar.com +* @package phpBB3 +*/ +class phpbb_avatar_driver_gravatar extends phpbb_avatar_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 (!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'], +		); +	} + +	/** +	* Build gravatar URL for output on page +	* +	* @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/includes/avatar/driver/interface.php b/phpBB/includes/avatar/driver/interface.php new file mode 100644 index 0000000000..3d62969aef --- /dev/null +++ b/phpBB/includes/avatar/driver/interface.php @@ -0,0 +1,116 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ +	exit; +} + +/** +* Interface for avatar drivers +* @package phpBB3 +*/ +interface phpbb_avatar_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 object +	* @param phpbb_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 object +	* @param phpbb_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/includes/avatar/driver/local.php b/phpBB/includes/avatar/driver/local.php new file mode 100644 index 0000000000..f4bcd4ce74 --- /dev/null +++ b/phpBB/includes/avatar/driver/local.php @@ -0,0 +1,197 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ +	exit; +} + +/** +* Handles avatars selected from the board gallery +* @package phpBB3 +*/ +class phpbb_avatar_driver_local extends phpbb_avatar_driver +{ +	/** +	* @inheritdoc +	*/ +	public function get_data($row) +	{ +		return array( +			'src' => $this->phpbb_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', ''); + +		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)) +		{ +			$error[] = 'NO_AVATAR_SELECTED'; +			return false; +		} + +		if (!isset($avatar_list[$category][urldecode($file)])) +		{ +			$error[] = 'AVATAR_URL_NOT_FOUND'; +			return false; +		} + +		return array( +			'avatar' => ($category != $user->lang['MAIN']) ? $category . '/' . $file : $file, +			'avatar_width' => $avatar_list[$category][urldecode($file)]['width'], +			'avatar_height' => $avatar_list[$category][urldecode($file)]['height'], +		); +	} + +	/** +	* 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['MAIN'] : str_replace("$path/", '', $file_path); +					$avatar_list[$cat][$image] = array( +						'file'      => ($cat != $user->lang['MAIN']) ? 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/includes/avatar/driver/remote.php b/phpBB/includes/avatar/driver/remote.php new file mode 100644 index 0000000000..7da58107a1 --- /dev/null +++ b/phpBB/includes/avatar/driver/remote.php @@ -0,0 +1,164 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ +	exit; +} + +/** +* Handles avatars hosted remotely +* @package phpBB3 +*/ +class phpbb_avatar_driver_remote extends phpbb_avatar_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 (!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)); + +		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, +		); +	} +} diff --git a/phpBB/includes/avatar/driver/upload.php b/phpBB/includes/avatar/driver/upload.php new file mode 100644 index 0000000000..baf51f61c1 --- /dev/null +++ b/phpBB/includes/avatar/driver/upload.php @@ -0,0 +1,159 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ +	exit; +} + +/** +* Handles avatars uploaded to the board +* @package phpBB3 +*/ +class phpbb_avatar_driver_upload extends phpbb_avatar_driver +{ +	/** +	* @inheritdoc +	*/ +	public function get_data($row, $ignore_config = false) +	{ +		return array( +			'src' => $this->phpbb_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'); +		} +		elseif (!empty($this->config['allow_avatar_remote_upload']) && !empty($url)) +		{ +			$file = $upload->remote_upload($url); +		} +		else +		{ +			$error[] = 'NO_AVATAR_SELECTED'; +			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' => 'rwpath',	'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; +	} + +	/** +	* 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')); +	} +} diff --git a/phpBB/includes/avatar/manager.php b/phpBB/includes/avatar/manager.php new file mode 100644 index 0000000000..58d994c3c0 --- /dev/null +++ b/phpBB/includes/avatar/manager.php @@ -0,0 +1,309 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ +	exit; +} + +/** +* @package avatar +*/ +class phpbb_avatar_manager +{ +	/** +	* phpBB configuration +	* @var phpbb_config +	*/ +	protected $config; + +	/** +	* Array that contains a list of enabled drivers +	* @var array +	*/ +	static protected $enabled_drivers = false; + +	/** +	* Array that contains all available avatar drivers which are passed via the +	* service container +	* @var array +	*/ +	protected $avatar_drivers; + +	/** +	* Service container object +	* @var object +	*/ +	protected $container; + +	/** +	* Default avatar data row +	* @var array +	*/ +	static protected $default_row = array( +		'avatar'		=> '', +		'avatar_type'	=> '', +		'avatar_width'	=> '', +		'avatar_height'	=> '', +	); + +	/** +	* Construct an avatar manager object +	* +	* @param phpbb_config $config phpBB configuration +	* @param array $avatar_drivers Avatar drivers passed via the service container +	* @param object $container Container object +	*/ +	public function __construct(phpbb_config $config, $avatar_drivers, $container) +	{ +		$this->config = $config; +		$this->avatar_drivers = $avatar_drivers; +		$this->container = $container; +	} + +	/** +	* Get the driver object specified by the avatar type +	* +	* @param string $avatar_type Avatar type; by default an avatar's service container name +	* @param bool $load_enabled Load only enabled avatars +	* +	* @return object Avatar driver object +	*/ +	public function get_driver($avatar_type, $load_enabled = true) +	{ +		if (self::$enabled_drivers === false) +		{ +			$this->load_enabled_drivers(); +		} + +		$avatar_drivers = ($load_enabled) ? self::$enabled_drivers : $this->get_all_drivers(); + +		// Legacy stuff... +		switch ($avatar_type) +		{ +			case AVATAR_GALLERY: +				$avatar_type = 'avatar.driver.local'; +			break; +			case AVATAR_UPLOAD: +				$avatar_type = 'avatar.driver.upload'; +			break; +			case AVATAR_REMOTE: +				$avatar_type = 'avatar.driver.remote'; +			break; +		} + +		if (!isset($avatar_drivers[$avatar_type])) +		{ +			return null; +		} + +		/* +		* There is no need to handle invalid avatar types as the following code +		* will cause a ServiceNotFoundException if the type does not exist +		*/ +		$driver = $this->container->get($avatar_type); + +		return $driver; +	} + +	/** +	* Load the list of enabled drivers +	* This is executed once and fills self::$enabled_drivers +	*/ +	protected function load_enabled_drivers() +	{ +		if (!empty($this->avatar_drivers)) +		{ +			self::$enabled_drivers = array(); +			foreach ($this->avatar_drivers as $driver) +			{ +				if ($this->is_enabled($driver)) +				{ +					self::$enabled_drivers[$driver->get_name()] = $driver->get_name(); +				} +			} +			asort(self::$enabled_drivers); +		} +	} + +	/** +	* Get a list of all avatar drivers +	* +	* As this function will only be called in the ACP avatar settings page, it +	* doesn't make much sense to cache the list of all avatar drivers like the +	* list of the enabled drivers. +	* +	* @return array Array containing a list of all avatar drivers +	*/ +	public function get_all_drivers() +	{ +		$drivers = array(); + +		if (!empty($this->avatar_drivers)) +		{ +			foreach ($this->avatar_drivers as $driver) +			{ +				$drivers[$driver->get_name()] = $driver->get_name(); +			} +			asort($drivers); +		} + +		return $drivers; +	} + +	/** +	* Get a list of enabled avatar drivers +	* +	* @return array Array containing a list of the enabled avatar drivers +	*/ +	public function get_enabled_drivers() +	{ +		if (self::$enabled_drivers === false) +		{ +			$this->load_enabled_drivers(); +		} + +		return self::$enabled_drivers; +	} + +	/** +	* Strip out user_ and group_ prefixes from keys +	* +	* @param array	$row User data or group data +	* +	* @return array User data or group data with keys that have been +	*        stripped from the preceding "user_" or "group_" +	*/ +	static public function clean_row($row) +	{ +		// Upon creation of a user/group $row might be empty +		if (empty($row)) +		{ +			return self::$default_row; +		} + +		$keys = array_keys($row); +		$values = array_values($row); + +		$keys = array_map(array('phpbb_avatar_manager', 'strip_prefix'), $keys); + +		return array_combine($keys, $values); +	} + +	/** +	* Strip prepending user_ or group_ prefix from key +	* +	* @param string Array key +	* @return string Key that has been stripped from its prefix +	*/ +	static protected function strip_prefix($key) +	{ +		return preg_replace('#^(?:user_|group_)#', '', $key); +	} + +	/** +	* Clean driver names that are returned from template files +	* Underscores are replaced with dots +	* +	* @param string $name Driver name +	* +	* @return string Cleaned driver name +	*/ +	static public function clean_driver_name($name) +	{ +		return str_replace('_', '.', $name); +	} + +	/** +	* Prepare driver names for use in template files +	* Dots are replaced with underscores +	* +	* @param string $name Clean driver name +	* +	* @return string Prepared driver name +	*/ +	static public function prepare_driver_name($name) +	{ +		return str_replace('.', '_', $name); +	} + +	/** +	* Check if avatar is enabled +	* +	* @param object $driver Avatar driver object +	* +	* @return bool True if avatar is enabled, false if it's disabled +	*/ +	public function is_enabled($driver) +	{ +		$config_name = $this->get_driver_config_name($driver); + +		return $this->config["allow_avatar_{$config_name}"]; +	} + +	/** +	* Get the settings array for enabling/disabling an avatar driver +	* +	* @param object $driver Avatar driver object +	* +	* @return array Array of configuration options as consumed by acp_board +	*/ +	public function get_avatar_settings($driver) +	{ +		$config_name = $this->get_driver_config_name($driver); + +		return array( +			'allow_avatar_' . $config_name	=> array('lang' => 'ALLOW_' . strtoupper($config_name),		'validate' => 'bool',	'type' => 'radio:yes_no', 'explain' => false), +		); +	} + +	/** +	* Get the config name of an avatar driver +	* +	* @param object $driver Avatar driver object +	* +	* @return string Avatar driver config name +	*/ +	public function get_driver_config_name($driver) +	{ +		return preg_replace('#^phpbb_avatar_driver_#', '', get_class($driver)); +	} + +	/** +	* Replace "error" strings with their real, localized form +	* +	* @param phpbb_user phpBB User object +	* @param array	$error Array containing error strings +	*        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 localized error strings +	*/ +	public function localize_errors(phpbb_user $user, $error) +	{ +		foreach ($error as $key => $lang) +		{ +			if (is_array($lang)) +			{ +				$lang_key = array_shift($lang); +				$error[$key] = vsprintf($user->lang($lang_key), $lang); +			} +			else +			{ +				$error[$key] = $user->lang("$lang"); +			} +		} + +		return $error; +	} +}  | 
