diff --git a/phpBB/config/default/container/services_attachment.yml b/phpBB/config/default/container/services_attachment.yml
index c56ced21f4..5b614d2f60 100644
--- a/phpBB/config/default/container/services_attachment.yml
+++ b/phpBB/config/default/container/services_attachment.yml
@@ -6,9 +6,8 @@ services:
- '@config'
- '@dbal.conn'
- '@dispatcher'
- - '@filesystem'
- '@attachment.resync'
- - '%core.root_path%'
+ - '@storage.attachment'
attachment.manager:
class: phpbb\attachment\manager
@@ -36,5 +35,5 @@ services:
- '@mimetype.guesser'
- '@dispatcher'
- '@plupload'
+ - '@storage.attachment'
- '@user'
- - '%core.root_path%'
diff --git a/phpBB/config/default/container/services_storage.yml b/phpBB/config/default/container/services_storage.yml
index 3593b8264a..f114dc1dfe 100644
--- a/phpBB/config/default/container/services_storage.yml
+++ b/phpBB/config/default/container/services_storage.yml
@@ -1,6 +1,14 @@
services:
# Storages
+ storage.attachment:
+ class: phpbb\storage\storage
+ arguments:
+ - '@storage.adapter.factory'
+ - 'attachment'
+ tags:
+ - { name: storage }
+
storage.avatar:
class: phpbb\storage\storage
arguments:
diff --git a/phpBB/docs/lighttpd.sample.conf b/phpBB/docs/lighttpd.sample.conf
index f5b509e002..e783c809fc 100644
--- a/phpBB/docs/lighttpd.sample.conf
+++ b/phpBB/docs/lighttpd.sample.conf
@@ -3,17 +3,8 @@
# from your system's lighttpd.conf.
# Tested with lighttpd 1.4.35
-# If you want to use the X-Sendfile feature,
-# uncomment the 'allow-x-send-file' for the fastcgi
-# server below and add the following to your config.php
-#
-# define('PHPBB_ENABLE_X_SENDFILE', true);
-#
-# See http://blog.lighttpd.net/articles/2006/07/02/x-sendfile
-# for the details on X-Sendfile.
-
# Load moules
-server.modules += (
+server.modules += (
"mod_access",
"mod_fastcgi",
"mod_rewrite",
@@ -32,11 +23,11 @@ $HTTP["host"] == "www.myforums.com" {
server.name = "www.myforums.com"
server.document-root = "/path/to/phpbb"
server.dir-listing = "disable"
-
+
index-file.names = ( "index.php", "index.htm", "index.html" )
accesslog.filename = "/var/log/lighttpd/access-www.myforums.com.log"
-
- # Deny access to internal phpbb files.
+
+ # Deny access to internal phpbb files.
$HTTP["url"] =~ "^/(config\.php|common\.php|cache|files|images/avatars/upload|includes|phpbb|store|vendor)" {
url.access-deny = ( "" )
}
@@ -45,12 +36,12 @@ $HTTP["host"] == "www.myforums.com" {
$HTTP["url"] =~ "/\.svn|/\.git" {
url.access-deny = ( "" )
}
-
+
# Deny access to apache configuration files.
$HTTP["url"] =~ "/\.htaccess|/\.htpasswd|/\.htgroups" {
url.access-deny = ( "" )
}
-
+
# The following 3 lines will rewrite URLs passed through the front controller
# to not require app.php in the actual URL. In other words, a controller is
# by default accessed at /app.php/my/controller, but can also be accessed at
@@ -58,14 +49,14 @@ $HTTP["host"] == "www.myforums.com" {
url.rewrite-if-not-file = (
"^/(.*)$" => "/app.php/$1"
)
-
- fastcgi.server = ( ".php" =>
+
+ fastcgi.server = ( ".php" =>
((
"bin-path" => "/usr/bin/php-cgi",
"socket" => "/tmp/php.socket",
"max-procs" => 4,
"idle-timeout" => 30,
- "bin-environment" => (
+ "bin-environment" => (
"PHP_FCGI_CHILDREN" => "10",
"PHP_FCGI_MAX_REQUESTS" => "10000"
),
diff --git a/phpBB/docs/nginx.sample.conf b/phpBB/docs/nginx.sample.conf
index 55c01a1fc9..4e40400b36 100644
--- a/phpBB/docs/nginx.sample.conf
+++ b/phpBB/docs/nginx.sample.conf
@@ -3,14 +3,6 @@
# from your system's nginx.conf.
# Tested with nginx 0.8.35.
-# If you want to use the X-Accel-Redirect feature,
-# add the following to your config.php.
-#
-# define('PHPBB_ENABLE_X_ACCEL_REDIRECT', true);
-#
-# See http://wiki.nginx.org/XSendfile for the details
-# on X-Accel-Redirect.
-
http {
# Compression - requires gzip and gzip static modules.
gzip on;
diff --git a/phpBB/download/file.php b/phpBB/download/file.php
index c7540c5380..e03a1bba35 100644
--- a/phpBB/download/file.php
+++ b/phpBB/download/file.php
@@ -254,7 +254,6 @@ else
}
}
- $download_mode = (int) $extensions[$attachment['extension']]['download_mode'];
$display_cat = $extensions[$attachment['extension']]['display_cat'];
if (($display_cat == ATTACHMENT_CATEGORY_IMAGE || $display_cat == ATTACHMENT_CATEGORY_THUMB) && !$user->optionget('viewimg'))
@@ -267,6 +266,8 @@ else
$display_cat = ATTACHMENT_CATEGORY_NONE;
}
+ $redirect = '';
+
/**
* Event to modify data before sending file to browser
*
@@ -274,21 +275,22 @@ else
* @var int attach_id The attachment ID
* @var array attachment Array with attachment data
* @var int display_cat Attachment category
- * @var int download_mode File extension specific download mode
* @var array extensions Array with file extensions data
* @var string mode Download mode
* @var bool thumbnail Flag indicating if the file is a thumbnail
+ * @var string redirect Do a redirection instead of reading the file
* @since 3.1.6-RC1
* @changed 3.1.7-RC1 Fixing wrong name of a variable (replacing "extension" by "extensions")
+ * @changed 3.3.0-a1 Add redirect variable
*/
$vars = array(
'attach_id',
'attachment',
'display_cat',
- 'download_mode',
'extensions',
'mode',
'thumbnail',
+ 'redirect',
);
extract($phpbb_dispatcher->trigger_event('core.download_file_send_to_browser_before', compact($vars)));
@@ -309,23 +311,15 @@ else
}
else
{
- // Determine the 'presenting'-method
- if ($download_mode == PHYSICAL_LINK)
+ if (!empty($redirect))
{
- // This presenting method should no longer be used
- if (!@is_dir($phpbb_root_path . $config['upload_path']))
- {
- send_status_line(500, 'Internal Server Error');
- trigger_error($user->lang['PHYSICAL_DOWNLOAD_NOT_POSSIBLE']);
- }
-
- redirect($phpbb_root_path . $config['upload_path'] . '/' . $attachment['physical_filename']);
- file_gc();
+ redirect($redirect, false, true);
}
else
{
- send_file_to_browser($attachment, $config['upload_path'], $display_cat);
- file_gc();
+ send_file_to_browser($attachment, $display_cat);
}
+
+ file_gc();
}
}
diff --git a/phpBB/includes/acp/acp_attachments.php b/phpBB/includes/acp/acp_attachments.php
index dc4eb66cf8..acb5d7d6e5 100644
--- a/phpBB/includes/acp/acp_attachments.php
+++ b/phpBB/includes/acp/acp_attachments.php
@@ -147,7 +147,6 @@ class acp_attachments
'allow_attachments' => array('lang' => 'ALLOW_ATTACHMENTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
'allow_pm_attach' => array('lang' => 'ALLOW_PM_ATTACHMENTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
- 'upload_path' => array('lang' => 'UPLOAD_DIR', 'validate' => 'wpath', 'type' => 'text:25:100', 'explain' => true),
'display_order' => array('lang' => 'DISPLAY_ORDER', 'validate' => 'bool', 'type' => 'custom', 'method' => 'display_order', 'explain' => true),
'attachment_quota' => array('lang' => 'ATTACH_QUOTA', 'validate' => 'string', 'type' => 'custom', 'method' => 'max_filesize', 'explain' => true),
'max_filesize' => array('lang' => 'ATTACH_MAX_FILESIZE', 'validate' => 'string', 'type' => 'custom', 'method' => 'max_filesize', 'explain' => true),
@@ -223,9 +222,6 @@ class acp_attachments
{
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_CONFIG_ATTACH');
- // Check Settings
- $this->test_upload($error, $this->new_config['upload_path'], false);
-
if (!count($error))
{
trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action));
@@ -590,11 +586,6 @@ class acp_attachments
'allow_in_pm' => ($allow_in_pm) ? 1 : 0,
);
- if ($action == 'add')
- {
- $group_ary['download_mode'] = INLINE_LINK;
- }
-
$sql = ($action == 'add') ? 'INSERT INTO ' . EXTENSION_GROUPS_TABLE . ' ' : 'UPDATE ' . EXTENSION_GROUPS_TABLE . ' SET ';
$sql .= $db->sql_build_array((($action == 'add') ? 'INSERT' : 'UPDATE'), $group_ary);
$sql .= ($action == 'edit') ? " WHERE group_id = $group_id" : '';
@@ -1536,50 +1527,6 @@ class acp_attachments
return $imagick;
}
- /**
- * Test Settings
- */
- function test_upload(&$error, $upload_dir, $create_directory = false)
- {
- global $user, $phpbb_root_path;
-
- // Does the target directory exist, is it a directory and writable.
- if ($create_directory)
- {
- if (!file_exists($phpbb_root_path . $upload_dir))
- {
- @mkdir($phpbb_root_path . $upload_dir, 0777);
-
- try
- {
- $this->filesystem->phpbb_chmod($phpbb_root_path . $upload_dir, CHMOD_READ | CHMOD_WRITE);
- }
- catch (\phpbb\filesystem\exception\filesystem_exception $e)
- {
- // Do nothing
- }
- }
- }
-
- if (!file_exists($phpbb_root_path . $upload_dir))
- {
- $error[] = sprintf($user->lang['NO_UPLOAD_DIR'], $upload_dir);
- return;
- }
-
- if (!is_dir($phpbb_root_path . $upload_dir))
- {
- $error[] = sprintf($user->lang['UPLOAD_NOT_DIR'], $upload_dir);
- return;
- }
-
- if (!$this->filesystem->is_writable($phpbb_root_path . $upload_dir))
- {
- $error[] = sprintf($user->lang['NO_WRITE_UPLOAD'], $upload_dir);
- return;
- }
- }
-
/**
* Perform operations on sites for external linking
*/
diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php
index 6460a1ae7c..2fa11e4d86 100644
--- a/phpBB/includes/constants.php
+++ b/phpBB/includes/constants.php
@@ -157,11 +157,6 @@ define('FULL_FOLDER_NONE', -3);
define('FULL_FOLDER_DELETE', -2);
define('FULL_FOLDER_HOLD', -1);
-// Download Modes - Attachments
-define('INLINE_LINK', 1);
-// This mode is only used internally to allow modders extending the attachment functionality
-define('PHYSICAL_LINK', 2);
-
// Confirm types
define('CONFIRM_REG', 1);
define('CONFIRM_LOGIN', 2);
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index d61f3bc653..2d3da96a4a 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -4438,7 +4438,6 @@ function page_header($page_title = '', $display_online_list = false, $item_id =
'T_AVATAR_GALLERY_PATH' => "{$web_path}{$config['avatar_gallery_path']}/",
'T_ICONS_PATH' => "{$web_path}{$config['icons_path']}/",
'T_RANKS_PATH' => "{$web_path}{$config['ranks_path']}/",
- 'T_UPLOAD_PATH' => "{$web_path}{$config['upload_path']}/",
'T_STYLESHEET_LINK' => "{$web_path}styles/" . rawurlencode($user->style['style_path']) . '/theme/stylesheet.css?assets_version=' . $config['assets_version'],
'T_STYLESHEET_LANG_LINK'=> "{$web_path}styles/" . rawurlencode($user->style['style_path']) . '/theme/' . $user->lang_name . '/stylesheet.css?assets_version=' . $config['assets_version'],
'T_FONT_AWESOME_LINK' => !empty($config['allow_cdn']) && !empty($config['load_font_awesome_url']) ? $config['load_font_awesome_url'] : "{$web_path}assets/css/font-awesome.min.css?assets_version=" . $config['assets_version'],
@@ -4455,7 +4454,6 @@ function page_header($page_title = '', $display_online_list = false, $item_id =
'T_AVATAR_GALLERY' => $config['avatar_gallery_path'],
'T_ICONS' => $config['icons_path'],
'T_RANKS' => $config['ranks_path'],
- 'T_UPLOAD' => $config['upload_path'],
'SITE_LOGO_IMG' => $user->img('site_logo'),
));
diff --git a/phpBB/includes/functions_acp.php b/phpBB/includes/functions_acp.php
index b3bde79339..3b4be2c344 100644
--- a/phpBB/includes/functions_acp.php
+++ b/phpBB/includes/functions_acp.php
@@ -91,7 +91,6 @@ function adm_page_header($page_title)
'T_AVATAR_GALLERY_PATH' => "{$phpbb_root_path}{$config['avatar_gallery_path']}/",
'T_ICONS_PATH' => "{$phpbb_root_path}{$config['icons_path']}/",
'T_RANKS_PATH' => "{$phpbb_root_path}{$config['ranks_path']}/",
- 'T_UPLOAD_PATH' => "{$phpbb_root_path}{$config['upload_path']}/",
'T_FONT_AWESOME_LINK' => !empty($config['allow_cdn']) && !empty($config['load_font_awesome_url']) ? $config['load_font_awesome_url'] : "{$phpbb_root_path}assets/css/font-awesome.min.css?assets_version=" . $config['assets_version'],
'T_ASSETS_VERSION' => $config['assets_version'],
diff --git a/phpBB/includes/functions_content.php b/phpBB/includes/functions_content.php
index 40d44cfe7b..97263af5f9 100644
--- a/phpBB/includes/functions_content.php
+++ b/phpBB/includes/functions_content.php
@@ -1086,6 +1086,9 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count_a
global $template, $cache, $user, $phpbb_dispatcher;
global $extensions, $config, $phpbb_root_path, $phpEx;
+ global $phpbb_container;
+
+ $attachment_storage = $phpbb_container->get('storage.attachment');
//
$compiled_attachments = array();
@@ -1163,7 +1166,7 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count_a
// Some basics...
$attachment['extension'] = strtolower(trim($attachment['extension']));
- $filename = $phpbb_root_path . $config['upload_path'] . '/' . utf8_basename($attachment['physical_filename']);
+ $filename = utf8_basename($attachment['physical_filename']);
$upload_icon = '';
@@ -1219,17 +1222,16 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count_a
{
if ($config['img_link_width'] || $config['img_link_height'])
{
- $dimension = @getimagesize($filename);
+ try
+ {
+ $file_info = $storage_attachment->file_info($filename);
- // If the dimensions could not be determined or the image being 0x0 we display it as a link for safety purposes
- if ($dimension === false || empty($dimension[0]) || empty($dimension[1]))
+ $display_cat = ($file_info->image_width <= $config['img_link_width'] && $file_info->image_height <= $config['img_link_height']) ? ATTACHMENT_CATEGORY_IMAGE : ATTACHMENT_CATEGORY_NONE;
+ }
+ catch (\Exception $e)
{
$display_cat = ATTACHMENT_CATEGORY_NONE;
}
- else
- {
- $display_cat = ($dimension[0] <= $config['img_link_width'] && $dimension[1] <= $config['img_link_height']) ? ATTACHMENT_CATEGORY_IMAGE : ATTACHMENT_CATEGORY_NONE;
- }
}
}
else
@@ -1283,7 +1285,18 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count_a
// Macromedia Flash Files
case ATTACHMENT_CATEGORY_FLASH:
- list($width, $height) = @getimagesize($filename);
+ try
+ {
+ $file_info = $storage_attachment->file_info($filename);
+
+ $width = $file_info->image_width;
+ $height = $file_info->image_height;
+ }
+ catch (\Exception $e)
+ {
+ $width = 0;
+ $height = 0;
+ }
$block_array += array(
'S_FLASH_FILE' => true,
diff --git a/phpBB/includes/functions_convert.php b/phpBB/includes/functions_convert.php
index 2cfbe9541d..7d0150fb5b 100644
--- a/phpBB/includes/functions_convert.php
+++ b/phpBB/includes/functions_convert.php
@@ -496,7 +496,7 @@ function import_attachment_files($category_name = '')
$sql = 'SELECT config_value AS upload_path
FROM ' . CONFIG_TABLE . "
- WHERE config_name = 'upload_path'";
+ WHERE config_name = 'storage\\attachment\\config\\path'";
$result = $db->sql_query($sql);
$config['upload_path'] = $db->sql_fetchfield('upload_path');
$db->sql_freeresult($result);
diff --git a/phpBB/includes/functions_download.php b/phpBB/includes/functions_download.php
index b6414c40dc..b74a386e3e 100644
--- a/phpBB/includes/functions_download.php
+++ b/phpBB/includes/functions_download.php
@@ -121,13 +121,15 @@ function wrap_img_in_html($src, $title)
/**
* Send file to browser
*/
-function send_file_to_browser($attachment, $upload_dir, $category)
+function send_file_to_browser($attachment, $category)
{
- global $user, $db, $phpbb_dispatcher, $phpbb_root_path, $request;
+ global $user, $db, $phpbb_dispatcher, $request, $phpbb_container;
- $filename = $phpbb_root_path . $upload_dir . '/' . $attachment['physical_filename'];
+ $storage = $phpbb_container->get('storage.attachment');
- if (!@file_exists($filename))
+ $filename = $attachment['physical_filename'];
+
+ if (!$storage->exists($filename))
{
send_status_line(404, 'Not Found');
trigger_error('ERROR_NO_ATTACHMENT');
@@ -146,14 +148,21 @@ function send_file_to_browser($attachment, $upload_dir, $category)
}
// Now send the File Contents to the Browser
- $size = @filesize($filename);
+ try
+ {
+ $file_info = $storage->file_info($filename);
+ $size = $file_info->size;
+ }
+ catch (\Exception $e)
+ {
+ $size = 0;
+ }
/**
* Event to alter attachment before it is sent to browser.
*
* @event core.send_file_to_browser_before
* @var array attachment Attachment data
- * @var string upload_dir Relative path of upload directory
* @var int category Attachment category
* @var string filename Path to file, including filename
* @var int size File size
@@ -161,7 +170,6 @@ function send_file_to_browser($attachment, $upload_dir, $category)
*/
$vars = array(
'attachment',
- 'upload_dir',
'category',
'filename',
'size',
@@ -171,15 +179,8 @@ function send_file_to_browser($attachment, $upload_dir, $category)
// To correctly display further errors we need to make sure we are using the correct headers for both (unsetting content-length may not work)
// Check if headers already sent or not able to get the file contents.
- if (headers_sent() || !@file_exists($filename) || !@is_readable($filename))
+ if (headers_sent())
{
- // PHP track_errors setting On?
- if (!empty($php_errormsg))
- {
- send_status_line(500, 'Internal Server Error');
- trigger_error($user->lang['UNABLE_TO_DELIVER_FILE'] . '
' . sprintf($user->lang['TRACKED_PHP_ERROR'], $php_errormsg));
- }
-
send_status_line(500, 'Internal Server Error');
trigger_error('UNABLE_TO_DELIVER_FILE');
}
@@ -235,24 +236,6 @@ function send_file_to_browser($attachment, $upload_dir, $category)
if (!set_modified_headers($attachment['filetime'], $user->browser))
{
- // We make sure those have to be enabled manually by defining a constant
- // because of the potential disclosure of full attachment path
- // in case support for features is absent in the webserver software.
- if (defined('PHPBB_ENABLE_X_ACCEL_REDIRECT') && PHPBB_ENABLE_X_ACCEL_REDIRECT)
- {
- // X-Accel-Redirect - http://wiki.nginx.org/XSendfile
- header('X-Accel-Redirect: ' . $user->page['root_script_path'] . $upload_dir . '/' . $attachment['physical_filename']);
- exit;
- }
- else if (defined('PHPBB_ENABLE_X_SENDFILE') && PHPBB_ENABLE_X_SENDFILE && !phpbb_http_byte_range($size))
- {
- // X-Sendfile - http://blog.lighttpd.net/articles/2006/07/02/x-sendfile
- // Lighttpd's X-Sendfile does not support range requests as of 1.4.26
- // and always requires an absolute path.
- header('X-Sendfile: ' . dirname(__FILE__) . "/../$upload_dir/{$attachment['physical_filename']}");
- exit;
- }
-
if ($size)
{
header("Content-Length: $size");
@@ -261,7 +244,7 @@ function send_file_to_browser($attachment, $upload_dir, $category)
// Try to deliver in chunks
@set_time_limit(0);
- $fp = @fopen($filename, 'rb');
+ $fp = $storage->read_stream($filename);
if ($fp !== false)
{
@@ -291,10 +274,6 @@ function send_file_to_browser($attachment, $upload_dir, $category)
}
fclose($fp);
}
- else
- {
- @readfile($filename);
- }
flush();
}
diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php
index b95926acb4..e6f328f102 100644
--- a/phpBB/includes/functions_posting.php
+++ b/phpBB/includes/functions_posting.php
@@ -1442,6 +1442,8 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll_ary, &$data
{
global $db, $auth, $user, $config, $phpEx, $phpbb_root_path, $phpbb_container, $phpbb_dispatcher, $phpbb_log, $request;
+ $attachment_storage = $phpbb_container->get('storage.attachment');
+
$poll = $poll_ary;
$data = $data_ary;
/**
@@ -2030,7 +2032,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll_ary, &$data
else
{
// insert attachment into db
- if (!@file_exists($phpbb_root_path . $config['upload_path'] . '/' . utf8_basename($orphan_rows[$attach_row['attach_id']]['physical_filename'])))
+ if (!$attachment_storage->exists(utf8_basename($orphan_rows[$attach_row['attach_id']]['physical_filename'])))
{
continue;
}
diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php
index 444bf2c7e0..7a56a67d74 100644
--- a/phpBB/includes/functions_privmsgs.php
+++ b/phpBB/includes/functions_privmsgs.php
@@ -1614,6 +1614,8 @@ function submit_pm($mode, $subject, &$data_ary, $put_in_outbox = true)
{
global $db, $auth, $config, $user, $phpbb_root_path, $phpbb_container, $phpbb_dispatcher, $request;
+ $attachment_storage = $phpbb_container->get('storage.attachment');
+
// We do not handle erasing pms here
if ($mode == 'delete')
{
@@ -1881,7 +1883,7 @@ function submit_pm($mode, $subject, &$data_ary, $put_in_outbox = true)
else
{
// insert attachment into db
- if (!@file_exists($phpbb_root_path . $config['upload_path'] . '/' . utf8_basename($orphan_rows[$attach_row['attach_id']]['physical_filename'])))
+ if (!$attachment_storage->exists(utf8_basename($orphan_rows[$attach_row['attach_id']]['physical_filename'])))
{
continue;
}
diff --git a/phpBB/install/convertors/convert_phpbb20.php b/phpBB/install/convertors/convert_phpbb20.php
index d0885dc620..60f3550651 100644
--- a/phpBB/install/convertors/convert_phpbb20.php
+++ b/phpBB/install/convertors/convert_phpbb20.php
@@ -439,7 +439,6 @@ if (!$get_info)
array('group_name', 'extension_groups.group_name', array('function1' => 'phpbb_set_encoding', 'function2' => 'utf8_htmlspecialchars')),
array('cat_id', 'extension_groups.cat_id', 'phpbb_attachment_category'),
array('allow_group', 'extension_groups.allow_group', ''),
- array('download_mode', 1, ''),
array('upload_icon', '', ''),
array('max_filesize', 'extension_groups.max_filesize', ''),
array('allowed_forums', 'extension_groups.forum_permissions', 'phpbb_attachment_forum_perms'),
diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql
index 58a7ff4f63..c6a60af67b 100644
--- a/phpBB/install/schemas/schema_data.sql
+++ b/phpBB/install/schemas/schema_data.sql
@@ -277,7 +277,6 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('teampage_forums',
INSERT INTO phpbb_config (config_name, config_value) VALUES ('topics_per_page', '25');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('tpl_allow_php', '0');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_icons_path', 'images/upload_icons');
-INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_path', 'files');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('use_system_cron', '0');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.3.0-a1-dev');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_expire_days', '90');
@@ -288,6 +287,8 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('exts_composer_json
INSERT INTO phpbb_config (config_name, config_value) VALUES ('exts_composer_vendor_dir', 'vendor-ext/');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('exts_composer_enable_on_install', '0');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('exts_composer_purge_on_remove', '1');
+INSERT INTO phpbb_config (config_name, config_value) VALUES ('storage\attachment\provider', 'phpbb\storage\provider\local');
+INSERT INTO phpbb_config (config_name, config_value) VALUES ('storage\attachment\config\path', 'files');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('storage\avatar\provider', 'phpbb\storage\provider\local');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('storage\avatar\config\path', 'images/avatars/upload');
@@ -729,12 +730,12 @@ INSERT INTO phpbb_reports_reasons (reason_title, reason_description, reason_orde
INSERT INTO phpbb_reports_reasons (reason_title, reason_description, reason_order) VALUES ('other', '{L_REPORT_OTHER}', 4);
# -- extension_groups
-INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, download_mode, upload_icon, max_filesize, allowed_forums) VALUES ('IMAGES', 1, 1, 1, '', 0, '');
-INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, download_mode, upload_icon, max_filesize, allowed_forums) VALUES ('ARCHIVES', 0, 1, 1, '', 0, '');
-INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, download_mode, upload_icon, max_filesize, allowed_forums) VALUES ('PLAIN_TEXT', 0, 0, 1, '', 0, '');
-INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, download_mode, upload_icon, max_filesize, allowed_forums) VALUES ('DOCUMENTS', 0, 0, 1, '', 0, '');
-INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, download_mode, upload_icon, max_filesize, allowed_forums) VALUES ('FLASH_FILES', 5, 0, 1, '', 0, '');
-INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, download_mode, upload_icon, max_filesize, allowed_forums) VALUES ('DOWNLOADABLE_FILES', 0, 0, 1, '', 0, '');
+INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, upload_icon, max_filesize, allowed_forums) VALUES ('IMAGES', 1, 1, '', 0, '');
+INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, upload_icon, max_filesize, allowed_forums) VALUES ('ARCHIVES', 0, 1, '', 0, '');
+INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, upload_icon, max_filesize, allowed_forums) VALUES ('PLAIN_TEXT', 0, 0, '', 0, '');
+INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, upload_icon, max_filesize, allowed_forums) VALUES ('DOCUMENTS', 0, 0, '', 0, '');
+INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, upload_icon, max_filesize, allowed_forums) VALUES ('FLASH_FILES', 5, 0, '', 0, '');
+INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, upload_icon, max_filesize, allowed_forums) VALUES ('DOWNLOADABLE_FILES', 0, 0, '', 0, '');
# -- extensions
INSERT INTO phpbb_extensions (group_id, extension) VALUES (1, 'gif');
diff --git a/phpBB/phpbb/attachment/delete.php b/phpBB/phpbb/attachment/delete.php
index 922f24b5dc..5dddb06310 100644
--- a/phpBB/phpbb/attachment/delete.php
+++ b/phpBB/phpbb/attachment/delete.php
@@ -16,7 +16,7 @@ namespace phpbb\attachment;
use \phpbb\config\config;
use \phpbb\db\driver\driver_interface;
use \phpbb\event\dispatcher;
-use \phpbb\filesystem\filesystem;
+use \phpbb\storage\storage;
/**
* Attachment delete class
@@ -32,14 +32,11 @@ class delete
/** @var dispatcher */
protected $dispatcher;
- /** @var filesystem */
- protected $filesystem;
-
/** @var resync */
protected $resync;
- /** @var string phpBB root path */
- protected $phpbb_root_path;
+ /** @var storage */
+ protected $storage;
/** @var array Attachement IDs */
protected $ids;
@@ -71,18 +68,16 @@ class delete
* @param config $config
* @param driver_interface $db
* @param dispatcher $dispatcher
- * @param filesystem $filesystem
* @param resync $resync
- * @param string $phpbb_root_path
+ * @param storage $storage
*/
- public function __construct(config $config, driver_interface $db, dispatcher $dispatcher, filesystem $filesystem, resync $resync, $phpbb_root_path)
+ public function __construct(config $config, driver_interface $db, dispatcher $dispatcher, resync $resync, storage $storage)
{
$this->config = $config;
$this->db = $db;
$this->dispatcher = $dispatcher;
- $this->filesystem = $filesystem;
$this->resync = $resync;
- $this->phpbb_root_path = $phpbb_root_path;
+ $this->storage = $storage;
}
/**
@@ -161,8 +156,8 @@ class delete
return 0;
}
- // Delete attachments from filesystem
- $this->remove_from_filesystem();
+ // Delete attachments from storage
+ $this->remove_from_storage();
// If we do not resync, we do not need to adjust any message, post, topic or user entries
if (!$resync)
@@ -327,9 +322,9 @@ class delete
}
/**
- * Delete attachments from filesystem
+ * Delete attachments from storage
*/
- protected function remove_from_filesystem()
+ protected function remove_from_storage()
{
$space_removed = $files_removed = 0;
@@ -388,7 +383,7 @@ class delete
}
/**
- * Delete attachment from filesystem
+ * Delete attachment from storage
*
* @param string $filename Filename of attachment
* @param string $mode Delete mode
@@ -412,17 +407,16 @@ class delete
}
$filename = ($mode == 'thumbnail') ? 'thumb_' . utf8_basename($filename) : utf8_basename($filename);
- $filepath = $this->phpbb_root_path . $this->config['upload_path'] . '/' . $filename;
try
{
- if ($this->filesystem->exists($filepath))
+ if ($this->storage->exists($filename))
{
- $this->filesystem->remove($this->phpbb_root_path . $this->config['upload_path'] . '/' . $filename);
+ $this->storage->delete($filename);
return true;
}
}
- catch (\phpbb\filesystem\exception\filesystem_exception $exception)
+ catch (\phpbb\storage\exception\exception $exception)
{
// Fail is covered by return statement below
}
diff --git a/phpBB/phpbb/attachment/upload.php b/phpBB/phpbb/attachment/upload.php
index b9d32058db..82a7578380 100644
--- a/phpBB/phpbb/attachment/upload.php
+++ b/phpBB/phpbb/attachment/upload.php
@@ -20,6 +20,7 @@ use \phpbb\event\dispatcher;
use \phpbb\language\language;
use \phpbb\mimetype\guesser;
use \phpbb\plupload\plupload;
+use \phpbb\storage\storage;
use \phpbb\user;
/**
@@ -51,6 +52,9 @@ class upload
/** @var plupload Plupload */
protected $plupload;
+ /** @var storage */
+ protected $storage;
+
/** @var user */
protected $user;
@@ -77,9 +81,8 @@ class upload
* @param dispatcher $phpbb_dispatcher
* @param plupload $plupload
* @param user $user
- * @param $phpbb_root_path
*/
- public function __construct(auth $auth, service $cache, config $config, \phpbb\files\upload $files_upload, language $language, guesser $mimetype_guesser, dispatcher $phpbb_dispatcher, plupload $plupload, user $user, $phpbb_root_path)
+ public function __construct(auth $auth, service $cache, config $config, \phpbb\files\upload $files_upload, language $language, guesser $mimetype_guesser, dispatcher $phpbb_dispatcher, plupload $plupload, storage $storage, user $user)
{
$this->auth = $auth;
$this->cache = $cache;
@@ -89,8 +92,8 @@ class upload
$this->mimetype_guesser = $mimetype_guesser;
$this->phpbb_dispatcher = $phpbb_dispatcher;
$this->plupload = $plupload;
+ $this->storage = $storage;
$this->user = $user;
- $this->phpbb_root_path = $phpbb_root_path;
}
/**
@@ -118,7 +121,7 @@ class upload
return $this->file_data;
}
- $this->file = ($local) ? $this->files_upload->handle_upload('files.types.local', $local_storage, $local_filedata) : $this->files_upload->handle_upload('files.types.form', $form_name);
+ $this->file = ($local) ? $this->files_upload->handle_upload('files.types.local_storage', $local_storage, $local_filedata) : $this->files_upload->handle_upload('files.types.form_storage', $form_name);
if ($this->file->init_error())
{
@@ -152,10 +155,6 @@ class upload
$this->file->clean_filename('unique', $this->user->data['user_id'] . '_');
- // Are we uploading an image *and* this image being within the image category?
- // Only then perform additional image checks.
- $this->file->move_file($this->config['upload_path'], false, !$is_image);
-
// Do we have to create a thumbnail?
$this->file_data['thumbnail'] = ($is_image && $this->config['img_create_thumbnail']) ? 1 : 0;
@@ -164,7 +163,7 @@ class upload
if (count($this->file->error))
{
- $this->file->remove();
+ $this->file->remove($this->storage);
$this->file_data['error'] = array_merge($this->file_data['error'], $this->file->error);
$this->file_data['post_attach'] = false;
@@ -200,6 +199,27 @@ class upload
// Create Thumbnail
$this->create_thumbnail();
+ // Are we uploading an image *and* this image being within the image category?
+ // Only then perform additional image checks.
+ $this->file->move_file($this->storage, false, !$is_image);
+
+ if (count($this->file->error))
+ {
+ $this->file->remove($this->storage);
+
+ // Remove thumbnail if exists
+ $thumbnail_file = 'thumb_' . $this->file->get('realname');
+ if ($this->storage->exists($thumbnail_file))
+ {
+ $this->storage->delete($thumbnail_file);
+ }
+
+ $this->file_data['error'] = array_merge($this->file_data['error'], $this->file->error);
+ $this->file_data['post_attach'] = false;
+
+ return $this->file_data;
+ }
+
return $this->file_data;
}
@@ -212,10 +232,18 @@ class upload
{
if ($this->file_data['thumbnail'])
{
- $source = $this->file->get('destination_file');
- $destination = $this->file->get('destination_path') . '/thumb_' . $this->file->get('realname');
+ $source = $this->file->get('filename');
+ $destination_name = 'thumb_' . $this->file->get('realname');
+ $destination = sys_get_temp_dir() . '/' . $destination_name;
- if (!create_thumbnail($source, $destination, $this->file->get('mimetype')))
+ if (create_thumbnail($source, $destination, $this->file->get('mimetype')))
+ {
+ // Move the thumbnail from temp folder to the storage
+ $fp = fopen($destination, 'rb');
+ $this->storage->write_stream($destination_name, $fp);
+ fclose($fp);
+ }
+ else
{
$this->file_data['thumbnail'] = 0;
}
@@ -253,7 +281,7 @@ class upload
// Make sure the image category only holds valid images...
if ($is_image && !$this->file->is_image())
{
- $this->file->remove();
+ $this->file->remove($this->storage);
if ($this->plupload && $this->plupload->is_active())
{
@@ -280,7 +308,7 @@ class upload
$this->file_data['error'][] = $this->language->lang('ATTACH_QUOTA_REACHED');
$this->file_data['post_attach'] = false;
- $this->file->remove();
+ $this->file->remove($this->storage);
return false;
}
@@ -296,26 +324,6 @@ class upload
*/
protected function check_disk_space()
{
- if ($free_space = @disk_free_space($this->phpbb_root_path . $this->config['upload_path']))
- {
- if ($free_space <= $this->file->get('filesize'))
- {
- if ($this->auth->acl_get('a_'))
- {
- $this->file_data['error'][] = $this->language->lang('ATTACH_DISK_FULL');
- }
- else
- {
- $this->file_data['error'][] = $this->language->lang('ATTACH_QUOTA_REACHED');
- }
- $this->file_data['post_attach'] = false;
-
- $this->file->remove();
-
- return false;
- }
- }
-
return true;
}
diff --git a/phpBB/phpbb/cache/service.php b/phpBB/phpbb/cache/service.php
index 502ae27625..2d4e55bfbb 100644
--- a/phpBB/phpbb/cache/service.php
+++ b/phpBB/phpbb/cache/service.php
@@ -214,7 +214,6 @@ class service
$extensions[$extension] = array(
'display_cat' => (int) $row['cat_id'],
- 'download_mode' => (int) $row['download_mode'],
'upload_icon' => trim($row['upload_icon']),
'max_filesize' => (int) $row['max_filesize'],
'allow_group' => $row['allow_group'],
diff --git a/phpBB/phpbb/db/migration/data/v330/remove_attachment_download_mode.php b/phpBB/phpbb/db/migration/data/v330/remove_attachment_download_mode.php
new file mode 100644
index 0000000000..f943d7fa25
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v330/remove_attachment_download_mode.php
@@ -0,0 +1,39 @@
+
+* @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\v330;
+
+class remove_attachment_download_mode extends \phpbb\db\migration\migration
+{
+ public function update_data()
+ {
+ return array(
+ 'drop_columns' => array(
+ $this->table_prefix . 'extension_groups' => array(
+ 'download_mode',
+ ),
+ ),
+ );
+ }
+
+ public function revert_schema()
+ {
+ return array(
+ 'add_columns' => array(
+ $this->table_prefix . 'extension_groups' => array(
+ 'download_mode' => array('BOOL', '1'),
+ ),
+ ),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v330/storage_attachment.php b/phpBB/phpbb/db/migration/data/v330/storage_attachment.php
new file mode 100644
index 0000000000..626bafed65
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v330/storage_attachment.php
@@ -0,0 +1,26 @@
+
+* @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\v330;
+
+class storage_attachment extends \phpbb\db\migration\migration
+{
+ public function update_data()
+ {
+ return array(
+ array('config.add', array('storage\\attachment\\provider', \phpbb\storage\provider\local::class)),
+ array('config.add', array('storage\\attachment\\config\\path', $this->config['upload_path'])),
+ array('config.remove', array('upload_path')),
+ );
+ }
+}
diff --git a/phpBB/phpbb/files/filespec_storage.php b/phpBB/phpbb/files/filespec_storage.php
index b370b66a4e..8b6194fe99 100644
--- a/phpBB/phpbb/files/filespec_storage.php
+++ b/phpBB/phpbb/files/filespec_storage.php
@@ -51,9 +51,6 @@ class filespec_storage
/** @var string Destination file name */
protected $destination_file = '';
- /** @var string Destination file path */
- protected $destination_path = '';
-
/** @var bool Whether file was moved */
protected $file_moved = false;
diff --git a/phpBB/phpbb/files/types/local_storage.php b/phpBB/phpbb/files/types/local_storage.php
new file mode 100644
index 0000000000..c3990fe389
--- /dev/null
+++ b/phpBB/phpbb/files/types/local_storage.php
@@ -0,0 +1,136 @@
+
+ * @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\files\types;
+
+use bantu\IniGetWrapper\IniGetWrapper;
+use phpbb\files\factory;
+use phpbb\files\filespec;
+use phpbb\language\language;
+use phpbb\request\request_interface;
+
+class local_storage extends base
+{
+ /** @var factory Files factory */
+ protected $factory;
+
+ /** @var language */
+ protected $language;
+
+ /** @var IniGetWrapper */
+ protected $php_ini;
+
+ /** @var request_interface */
+ protected $request;
+
+ /** @var \phpbb\files\upload */
+ protected $upload;
+
+ /**
+ * Construct a form upload type
+ *
+ * @param factory $factory Files factory
+ * @param language $language Language class
+ * @param IniGetWrapper $php_ini ini_get() wrapper
+ * @param request_interface $request Request object
+ */
+ public function __construct(factory $factory, language $language, IniGetWrapper $php_ini, request_interface $request)
+ {
+ $this->factory = $factory;
+ $this->language = $language;
+ $this->php_ini = $php_ini;
+ $this->request = $request;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function upload()
+ {
+ $args = func_get_args();
+ return $this->local_upload($args[0], isset($args[1]) ? $args[1] : false);
+ }
+
+ /**
+ * Move file from another location to phpBB
+ *
+ * @param string $source_file Filename of source file
+ * @param array|bool $filedata Array with filedata or false
+ *
+ * @return filespec Object "filespec" is returned, all further operations can be done with this object
+ */
+ protected function local_upload($source_file, $filedata = false)
+ {
+ $upload = $this->get_upload_ary($source_file, $filedata);
+
+ /** @var filespec $file */
+ $file = $this->factory->get('filespec_storage')
+ ->set_upload_ary($upload)
+ ->set_upload_namespace($this->upload);
+
+ if ($file->init_error())
+ {
+ $file->error[] = '';
+ return $file;
+ }
+
+ // PHP Upload file size check
+ $file = $this->check_upload_size($file);
+ if (count($file->error))
+ {
+ return $file;
+ }
+
+ // Not correctly uploaded
+ if (!$file->is_uploaded())
+ {
+ $file->error[] = $this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED');
+ return $file;
+ }
+
+ $this->upload->common_checks($file);
+ $this->request->overwrite('local', $upload, request_interface::FILES);
+
+ return $file;
+ }
+
+ /**
+ * Retrieve upload array
+ *
+ * @param string $source_file Source file name
+ * @param array $filedata File data array
+ *
+ * @return array Upload array
+ */
+ protected function get_upload_ary($source_file, $filedata)
+ {
+ $upload = array();
+
+ $upload['local_mode'] = true;
+ $upload['tmp_name'] = $source_file;
+
+ if ($filedata === false)
+ {
+ $upload['name'] = utf8_basename($source_file);
+ $upload['size'] = 0;
+ }
+ else
+ {
+ $upload['name'] = $filedata['realname'];
+ $upload['size'] = $filedata['size'];
+ $upload['type'] = $filedata['type'];
+ }
+
+ return $upload;
+ }
+}
diff --git a/tests/attachment/delete_test.php b/tests/attachment/delete_test.php
index 5ea9f26ea0..cefe076bbf 100644
--- a/tests/attachment/delete_test.php
+++ b/tests/attachment/delete_test.php
@@ -27,11 +27,12 @@ class phpbb_attachment_delete_test extends \phpbb_database_test_case
/** @var \phpbb\attachment\resync */
protected $resync;
+ /** @var \phpbb\storage\storage */
+ protected $storage;
+
/** @var \phpbb\attachment\delete */
protected $attachment_delete;
- protected $phpbb_root_path;
-
public function getDataSet()
{
return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/resync.xml');
@@ -54,9 +55,15 @@ class phpbb_attachment_delete_test extends \phpbb_database_test_case
$this->filesystem->expects($this->any())
->method('exists')
->willReturn(true);
- $this->phpbb_root_path = $phpbb_root_path;
+ $adapter = new \phpbb\storage\adapter\local($this->filesystem, new \FastImageSize\FastImageSize(), new \phpbb\mimetype\guesser(array(new \phpbb\mimetype\extension_guesser)), $phpbb_root_path);
+ $adapter->configure(['path' => 'files']);
+ $adapter_factory_mock = $this->createMock('\phpbb\storage\adapter_factory');
+ $adapter_factory_mock->expects($this->any())
+ ->method('get')
+ ->willReturn($adapter);
+ $this->storage = new \phpbb\storage\storage($adapter_factory_mock, '');
$this->dispatcher = new \phpbb_mock_event_dispatcher();
- $this->attachment_delete = new \phpbb\attachment\delete($this->config, $this->db, $this->dispatcher, $this->filesystem, $this->resync, $phpbb_root_path);
+ $this->attachment_delete = new \phpbb\attachment\delete($this->config, $this->db, $this->dispatcher, $this->resync, $this->storage);
}
public function data_attachment_delete()
@@ -103,25 +110,24 @@ class phpbb_attachment_delete_test extends \phpbb_database_test_case
*/
public function test_attachment_delete_success($remove_success, $exists_success, $expected, $throw_exception = false)
{
- $this->filesystem = $this->createMock('\phpbb\filesystem\filesystem', array('remove', 'exists'));
+ $this->storage = $this->createMock('\phpbb\storage\storage', array('delete', 'exists'));
if ($throw_exception)
{
- $this->filesystem->expects($this->any())
- ->method('remove')
- ->willThrowException(new \phpbb\filesystem\exception\filesystem_exception);;
+ $this->storage->expects($this->any())
+ ->method('delete')
+ ->willThrowException(new \phpbb\storage\exception\exception);
}
else
{
- $this->filesystem->expects($this->any())
- ->method('remove')
+ $this->storage->expects($this->any())
+ ->method('delete')
->willReturn($remove_success);
}
-
- $this->filesystem->expects($this->any())
+ $this->storage->expects($this->any())
->method('exists')
->willReturn($exists_success);
- $this->attachment_delete = new \phpbb\attachment\delete($this->config, $this->db, $this->dispatcher, $this->filesystem, $this->resync, $this->phpbb_root_path);
+ $this->attachment_delete = new \phpbb\attachment\delete($this->config, $this->db, $this->dispatcher, $this->resync, $this->storage);
$this->assertSame($expected, $this->attachment_delete->unlink_attachment('foobar'));
}
}
diff --git a/tests/attachment/fixtures/resync.xml b/tests/attachment/fixtures/resync.xml
index af04701b4a..b06d2db3e2 100644
--- a/tests/attachment/fixtures/resync.xml
+++ b/tests/attachment/fixtures/resync.xml
@@ -58,7 +58,6 @@