diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql index 3fd9d5888b..7746c9567c 100644 --- a/phpBB/install/schemas/schema_data.sql +++ b/phpBB/install/schemas/schema_data.sql @@ -321,13 +321,10 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('exts_composer_purg INSERT INTO phpbb_config (config_name, config_value) VALUES ('exts_composer_minimum_stability', 'stable'); 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\attachment\config\subfolders', '0'); 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'); -INSERT INTO phpbb_config (config_name, config_value) VALUES ('storage\avatar\config\subfolders', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('storage\backup\provider', 'phpbb\storage\provider\local'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('storage\backup\config\path', 'store'); -INSERT INTO phpbb_config (config_name, config_value) VALUES ('storage\backup\config\subfolders', '0'); INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('cache_last_gc', '0', 1); INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('cron_lock', '0', 1); diff --git a/phpBB/language/en/acp/storage.php b/phpBB/language/en/acp/storage.php index f0da8b3d2f..98ad84df53 100644 --- a/phpBB/language/en/acp/storage.php +++ b/phpBB/language/en/acp/storage.php @@ -57,8 +57,6 @@ $lang = array_merge($lang, array( // Local adapter 'STORAGE_ADAPTER_LOCAL_NAME' => 'Local', 'STORAGE_ADAPTER_LOCAL_OPTION_PATH' => 'Path', - 'STORAGE_ADAPTER_LOCAL_OPTION_SUBFOLDERS' => 'Organize in subfolders', - 'STORAGE_ADAPTER_LOCAL_OPTION_SUBFOLDERS_EXPLAIN' => 'Some web servers may have problems storing large number of files in a single directory. Enable this option to distribute files in different directories.', // Form validation 'STORAGE_UPDATE_SUCCESSFUL' => 'All storage types were successfully updated.', diff --git a/phpBB/phpbb/db/migration/data/v400/storage_adapter_local_subfolders_remove.php b/phpBB/phpbb/db/migration/data/v400/storage_adapter_local_subfolders_remove.php new file mode 100644 index 0000000000..63accdb21c --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v400/storage_adapter_local_subfolders_remove.php @@ -0,0 +1,42 @@ + +* @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\v400; + +use phpbb\db\migration\migration; + +class storage_adapter_local_subfolders_remove extends migration +{ + public function effectively_installed() + { + return !$this->config->offsetExists('storage\\attachment\\config\\subfolders') && + !$this->config->offsetExists('storage\\avatar\\config\\subfolders') && + !$this->config->offsetExists('storage\\backup\\config\\subfolders'); + } + + public static function depends_on() + { + return [ + '\phpbb\db\migration\data\v400\storage_adapter_local_subfolders', + ]; + } + + public function update_data() + { + return [ + ['config.remove', ['storage\\attachment\\config\\subfolders']], + ['config.remove', ['storage\\avatar\\config\\subfolders']], + ['config.remove', ['storage\\backup\\config\\subfolders']], + ]; + } +} diff --git a/phpBB/phpbb/storage/adapter/local.php b/phpBB/phpbb/storage/adapter/local.php index 750dcec6c1..be4b3399d6 100644 --- a/phpBB/phpbb/storage/adapter/local.php +++ b/phpBB/phpbb/storage/adapter/local.php @@ -73,29 +73,6 @@ class local implements adapter_interface, stream_interface */ protected $path; - /* - * Subdirectories depth - * - * Instead of storing all folders in the same directory, they can be divided - * into smaller directories. The variable describes the number of subdirectories - * to be used for storing the files. For example: - * depth = 0 -> /images/avatars/upload/my_avatar.jpg - * depth = 2 -> /images/avatars/upload/d9/8c/my_avatar.jpg - * This is for those who have problems storing a large number of files in - * a single directory. - * More info: https://tracker.phpbb.com/browse/PHPBB3-15371 - */ - - /* - * @var bool subfolders - */ - protected $subfolders; - - /* - * @var int dir_depth - */ - protected $dir_depth = 2; - /** * Constructor * @@ -125,7 +102,6 @@ class local implements adapter_interface, stream_interface } $this->root_path = filesystem_helper::realpath($this->phpbb_root_path . $options['path']) . DIRECTORY_SEPARATOR; - $this->subfolders = (bool) $options['subfolders']; } /** @@ -181,8 +157,6 @@ class local implements adapter_interface, stream_interface { throw new exception('STORAGE_CANNOT_DELETE', $path, array(), $e); } - - $this->remove_empty_dirs($path); } /** @@ -200,8 +174,6 @@ class local implements adapter_interface, stream_interface { throw new exception('STORAGE_CANNOT_RENAME', $path_orig, array(), $e); } - - $this->remove_empty_dirs($path_orig); } /** @@ -259,31 +231,7 @@ class local implements adapter_interface, stream_interface } /** - * Removes the directory tree ascending until it finds a non empty directory. - * - * @param string $path The file path - */ - protected function remove_empty_dirs(string $path): void - { - if ($this->subfolders) - { - $dirpath = dirname($this->root_path . $path); - $filepath = dirname($this->root_path . $this->get_path($path) . $this->get_filename($path)); - $path = filesystem_helper::make_path_relative($filepath, $dirpath); - - do - { - $parts = explode('/', $path); - $parts = array_slice($parts, 0, -1); - $path = implode('/', $parts); - } - while ($path && @rmdir($dirpath . '/' . $path)); - } - } - - /** - * Get the path to the file, appending subdirectories for directory depth - * if $dir_depth > 0. + * Get the path to the file * * @param string $path The file path * @return string @@ -293,19 +241,6 @@ class local implements adapter_interface, stream_interface $dirname = dirname($path); $dirname = ($dirname != '.') ? $dirname . DIRECTORY_SEPARATOR : ''; - if ($this->subfolders) - { - $hash = md5(basename($path)); - - $parts = str_split($hash, 2); - $parts = array_slice($parts, 0, $this->dir_depth); - - if (!empty($parts)) - { - $dirname .= implode(DIRECTORY_SEPARATOR, $parts) . DIRECTORY_SEPARATOR; - } - } - return $dirname; } diff --git a/phpBB/phpbb/storage/provider/local.php b/phpBB/phpbb/storage/provider/local.php index 93d3c7a6d0..3bec0c5ce5 100644 --- a/phpBB/phpbb/storage/provider/local.php +++ b/phpBB/phpbb/storage/provider/local.php @@ -38,13 +38,6 @@ class local implements provider_interface { return [ 'path' => ['type' => 'text'], - 'subfolders' => [ - 'type' => 'radio', - 'options' => [ - 'ENABLE' => '1', - 'DISABLE' => '0', - ], - ], ]; } diff --git a/tests/storage/adapter/local_subfolders_test.php b/tests/storage/adapter/local_subfolders_test.php deleted file mode 100644 index 33b232a131..0000000000 --- a/tests/storage/adapter/local_subfolders_test.php +++ /dev/null @@ -1,176 +0,0 @@ - - * @license GNU General Public License, version 2 (GPL-2.0) - * - * For full copyright and license information, please see - * the docs/CREDITS.txt file. - * - */ - -require_once __DIR__ . '/local_test_case.php'; - -class phpbb_storage_adapter_local_subfolders_test extends phpbb_local_test_case -{ - protected function setUp(): void - { - parent::setUp(); - - $this->adapter->configure(['path' => 'test_path', 'subfolders' => true]); - } - - public function test_put_contents(): void - { - // When - $this->adapter->put_contents('file.txt', 'abc'); - - // Then - $this->assertFileExists($this->path . '3d/8e/file.txt'); - $this->assertFileContains($this->path . '3d/8e/file.txt', 'abc'); - - // Clean test - unlink($this->path . '3d/8e/file.txt'); - rmdir($this->path . '3d/8e'); - rmdir($this->path . '3d'); - } - - public function test_get_contents(): void - { - // Given - mkdir($this->path . '3d/8e', 0777, true); - file_put_contents($this->path . '3d/8e/file.txt', 'abc'); - - // When - $content = $this->adapter->get_contents('file.txt'); - - // Then - $this->assertEquals('abc', $content); - - // Clean test - unlink($this->path . '3d/8e/file.txt'); - rmdir($this->path . '3d/8e'); - rmdir($this->path . '3d'); - } - - public function test_exists(): void - { - // Given - mkdir($this->path . '3d/8e', 0777, true); - touch($this->path . '3d/8e/file.txt'); - - // When - $existent_file = $this->adapter->exists('file.txt'); - $non_existent_file = $this->adapter->exists('noexist.txt'); - $non_existent_file2 = $this->adapter->exists('3d/8e/file.txt'); - - // Then - $this->assertTrue($existent_file); - $this->assertFalse($non_existent_file); - $this->assertFalse($non_existent_file2); - - // Clean test - unlink($this->path . '3d/8e/file.txt'); - rmdir($this->path . '3d/8e'); - rmdir($this->path . '3d'); - } - - public function test_delete_file(): void - { - // Given - mkdir($this->path . '3d/8e', 0777, true); - touch($this->path . '3d/8e/file.txt'); - $this->assertFileExists($this->path . '3d/8e/file.txt'); - - // When - $this->adapter->delete('file.txt'); - - // Then - $this->assertFileDoesNotExist($this->path . '3d/8e/file.txt'); - $this->assertFileDoesNotExist($this->path . '3d'); - } - - public function test_rename(): void - { - // Given - mkdir($this->path . '3d/8e', 0777, true); - touch($this->path . '3d/8e/file.txt'); - - // When - $this->adapter->rename('file.txt', 'file2.txt'); - - // Then - $this->assertFileDoesNotExist($this->path . '3d/8e/file.txt'); - $this->assertFileExists($this->path . '27/36/file2.txt'); - $this->assertFileDoesNotExist($this->path . '3d'); - - // Clean test - unlink($this->path . '27/36/file2.txt'); - rmdir($this->path . '27/36'); - rmdir($this->path . '27'); - } - - public function test_copy(): void - { - // Given - mkdir($this->path . '3d/8e', 0777, true); - file_put_contents($this->path . '3d/8e/file.txt', 'abc'); - - // When - $this->adapter->copy('file.txt', 'file2.txt'); - - // Then - $this->assertFileContains($this->path . '3d/8e/file.txt', 'abc'); - $this->assertFileContains($this->path . '27/36/file2.txt', 'abc'); - - // Clean test - unlink($this->path . '3d/8e/file.txt'); - rmdir($this->path . '3d/8e'); - rmdir($this->path . '3d'); - unlink($this->path . '27/36/file2.txt'); - rmdir($this->path . '27/36'); - rmdir($this->path . '27'); - } - - public function test_read_stream(): void - { - // Given - mkdir($this->path . '3d/8e', 0777, true); - file_put_contents($this->path . '3d/8e/file.txt', 'abc'); - - // When - $stream = $this->adapter->read_stream('file.txt'); - - // Then - $this->assertIsResource($stream); - $this->assertEquals('abc', stream_get_contents($stream)); - - // Clean test - fclose($stream); - unlink($this->path . '3d/8e/file.txt'); - rmdir($this->path . '3d/8e'); - rmdir($this->path . '3d'); - } - - public function test_write_stream(): void - { - // Given - file_put_contents($this->path . 'file.txt', 'abc'); - $stream = fopen($this->path . 'file.txt', 'rb'); - - // When - $this->adapter->write_stream('file2.txt', $stream); - fclose($stream); - - // Then - $this->assertFileContains($this->path . '27/36/file2.txt', 'abc'); - - // Clean test - unlink($this->path . 'file.txt'); - unlink($this->path . '27/36/file2.txt'); - rmdir($this->path . '27/36'); - rmdir($this->path . '27'); - } -} diff --git a/tests/storage/adapter/local_test.php b/tests/storage/adapter/local_test.php index 61d2e1d0c1..2fee54b2f5 100644 --- a/tests/storage/adapter/local_test.php +++ b/tests/storage/adapter/local_test.php @@ -19,7 +19,7 @@ class phpbb_storage_adapter_local_test extends phpbb_local_test_case { parent::setUp(); - $this->adapter->configure(['path' => 'test_path', 'subfolders' => false]); + $this->adapter->configure(['path' => 'test_path']); } public function test_put_contents(): void