1
0
mirror of https://github.com/phpbb/phpbb.git synced 2025-07-31 14:00:31 +02:00

[ticket/15699] Rewrite acp_storage

PHPBB3-15699
This commit is contained in:
Ruben Calvo
2023-09-22 16:52:22 +02:00
parent 4974f86059
commit 58ecd3b048
27 changed files with 954 additions and 621 deletions

View File

@@ -13,7 +13,7 @@
namespace phpbb\storage\adapter;
use phpbb\storage\exception\exception;
use phpbb\storage\exception\storage_exception;
interface adapter_interface
{
@@ -29,7 +29,7 @@ interface adapter_interface
*
* @param string $path
* @param string $content
* @throws exception When the file cannot be written
* @throws storage_exception When the file cannot be written
*/
public function put_contents(string $path, string $content): void;
@@ -39,7 +39,7 @@ interface adapter_interface
* @param string $path The file to read
*
* @return string Returns file contents
* @throws exception When cannot read file contents
* @throws storage_exception When cannot read file contents
*/
public function get_contents(string $path): string;
@@ -57,7 +57,7 @@ interface adapter_interface
*
* @param string $path file/directory to remove
*
* @throws exception When removal fails.
* @throws storage_exception When removal fails.
*/
public function delete(string $path): void;
@@ -67,7 +67,7 @@ interface adapter_interface
* @param string $path_orig The original file/direcotry
* @param string $path_dest The target file/directory
*
* @throws exception When file/directory cannot be renamed
* @throws storage_exception When file/directory cannot be renamed
*/
public function rename(string $path_orig, string $path_dest): void;
@@ -77,7 +77,7 @@ interface adapter_interface
* @param string $path_orig The original filename
* @param string $path_dest The target filename
*
* @throws exception When the file cannot be copied
* @throws storage_exception When the file cannot be copied
*/
public function copy(string $path_orig, string $path_dest): void;
@@ -94,7 +94,7 @@ interface adapter_interface
* Get space available in bytes
*
* @return float Returns available space
* @throws exception When unable to retrieve available storage space
* @throws storage_exception When unable to retrieve available storage space
*/
public function free_space(): float;
}

View File

@@ -14,7 +14,7 @@
namespace phpbb\storage\adapter;
use phpbb\storage\stream_interface;
use phpbb\storage\exception\exception;
use phpbb\storage\exception\storage_exception;
use phpbb\filesystem\exception\filesystem_exception;
use phpbb\filesystem\filesystem;
use phpbb\filesystem\helper as filesystem_helper;
@@ -117,7 +117,7 @@ class local implements adapter_interface, stream_interface
}
catch (filesystem_exception $e)
{
throw new exception('STORAGE_CANNOT_WRITE_FILE', $path, array(), $e);
throw new storage_exception('STORAGE_CANNOT_WRITE_FILE', $path, array(), $e);
}
}
@@ -130,7 +130,7 @@ class local implements adapter_interface, stream_interface
if ($content === false)
{
throw new exception('STORAGE_CANNOT_READ_FILE', $path);
throw new storage_exception('STORAGE_CANNOT_READ_FILE', $path);
}
return $content;
@@ -155,7 +155,7 @@ class local implements adapter_interface, stream_interface
}
catch (filesystem_exception $e)
{
throw new exception('STORAGE_CANNOT_DELETE', $path, array(), $e);
throw new storage_exception('STORAGE_CANNOT_DELETE', $path, array(), $e);
}
}
@@ -172,7 +172,7 @@ class local implements adapter_interface, stream_interface
}
catch (filesystem_exception $e)
{
throw new exception('STORAGE_CANNOT_RENAME', $path_orig, array(), $e);
throw new storage_exception('STORAGE_CANNOT_RENAME', $path_orig, array(), $e);
}
}
@@ -189,7 +189,7 @@ class local implements adapter_interface, stream_interface
}
catch (filesystem_exception $e)
{
throw new exception('STORAGE_CANNOT_COPY', $path_orig, array(), $e);
throw new storage_exception('STORAGE_CANNOT_COPY', $path_orig, array(), $e);
}
}
@@ -198,7 +198,7 @@ class local implements adapter_interface, stream_interface
*
* @param string $path The directory path
*
* @throws exception On any directory creation failure
* @throws storage_exception On any directory creation failure
*/
protected function create_dir(string $path): void
{
@@ -208,7 +208,7 @@ class local implements adapter_interface, stream_interface
}
catch (filesystem_exception $e)
{
throw new exception('STORAGE_CANNOT_CREATE_DIR', $path, array(), $e);
throw new storage_exception('STORAGE_CANNOT_CREATE_DIR', $path, array(), $e);
}
}
@@ -217,7 +217,7 @@ class local implements adapter_interface, stream_interface
*
* @param string $path The file path
*
* @throws exception On any directory creation failure
* @throws storage_exception On any directory creation failure
*/
protected function ensure_directory_exists(string $path): void
{
@@ -264,7 +264,7 @@ class local implements adapter_interface, stream_interface
if (!$stream)
{
throw new exception('STORAGE_CANNOT_OPEN_FILE', $path);
throw new storage_exception('STORAGE_CANNOT_OPEN_FILE', $path);
}
return $stream;
@@ -281,13 +281,13 @@ class local implements adapter_interface, stream_interface
if (!$stream)
{
throw new exception('STORAGE_CANNOT_CREATE_FILE', $path);
throw new storage_exception('STORAGE_CANNOT_CREATE_FILE', $path);
}
if (stream_copy_to_stream($resource, $stream) === false)
{
fclose($stream);
throw new exception('STORAGE_CANNOT_COPY_RESOURCE');
throw new storage_exception('STORAGE_CANNOT_COPY_RESOURCE');
}
fclose($stream);
@@ -298,10 +298,10 @@ class local implements adapter_interface, stream_interface
*
* @param string $path The file
*
* @throws exception When cannot get size
*
* @return array Properties
* @throws exception When cannot get size
* @throws storage_exception When cannot get size
*
* @throws storage_exception When cannot get size
*
*/
public function file_size(string $path): array
@@ -310,7 +310,7 @@ class local implements adapter_interface, stream_interface
if ($size === null)
{
throw new exception('STORAGE_CANNOT_GET_FILESIZE');
throw new storage_exception('STORAGE_CANNOT_GET_FILESIZE');
}
return ['size' => $size];
@@ -392,12 +392,12 @@ class local implements adapter_interface, stream_interface
if ($free_space === false)
{
throw new exception('STORAGE_CANNOT_GET_FREE_SPACE');
throw new storage_exception('STORAGE_CANNOT_GET_FREE_SPACE');
}
}
else
{
throw new exception('STORAGE_CANNOT_GET_FREE_SPACE');
throw new storage_exception('STORAGE_CANNOT_GET_FREE_SPACE');
}
return $free_space;

View File

@@ -15,7 +15,7 @@ namespace phpbb\storage;
use phpbb\config\config;
use phpbb\di\service_collection;
use phpbb\storage\exception\exception;
use phpbb\storage\exception\storage_exception;
class adapter_factory
{
@@ -62,7 +62,7 @@ class adapter_factory
if (!$provider->is_available())
{
throw new exception('STORAGE_ADAPTER_NOT_AVAILABLE');
throw new storage_exception('STORAGE_ADAPTER_NOT_AVAILABLE');
}
$adapter = $this->adapters->get_by_class($provider->get_adapter_class());

View File

@@ -16,7 +16,7 @@ namespace phpbb\storage\controller;
use phpbb\cache\service;
use phpbb\db\driver\driver_interface;
use phpbb\exception\http_exception;
use phpbb\storage\exception\exception;
use phpbb\storage\exception\storage_exception;
use phpbb\storage\storage;
use Symfony\Component\HttpFoundation\Request as symfony_request;
use Symfony\Component\HttpFoundation\Response;
@@ -63,7 +63,7 @@ class controller
* @return Response a Symfony response object
*
* @throws http_exception when can't access $file
* @throws exception when there is an error reading the file
* @throws storage_exception when there is an error reading the file
*/
public function handle(string $file): Response
{
@@ -120,7 +120,7 @@ class controller
* @param string $file File path
*
* @return void
* @throws exception when there is an error reading the file
* @throws storage_exception when there is an error reading the file
*/
protected function prepare(StreamedResponse $response, string $file): void
{
@@ -133,7 +133,7 @@ class controller
{
$content_type = $file_info->get('mimetype');
}
catch (exception $e)
catch (storage_exception $e)
{
$content_type = 'application/octet-stream';
}
@@ -148,7 +148,7 @@ class controller
{
$response->headers->set('Content-Length', $file_info->get('size'));
}
catch (exception $e)
catch (storage_exception $e)
{
// Just don't send this header
}

View File

@@ -0,0 +1,18 @@
<?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\storage\exception;
class action_in_progress_exception extends storage_exception
{
}

View File

@@ -0,0 +1,18 @@
<?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\storage\exception;
class no_action_in_progress_exception extends storage_exception
{
}

View File

@@ -15,7 +15,7 @@ namespace phpbb\storage\exception;
use phpbb\exception\runtime_exception;
class exception extends runtime_exception
class storage_exception extends runtime_exception
{
/**
* Constructor

View File

@@ -13,7 +13,7 @@
namespace phpbb\storage;
use phpbb\storage\exception\exception;
use phpbb\storage\exception\storage_exception;
use phpbb\storage\adapter\adapter_interface;
class file_info
@@ -66,7 +66,7 @@ class file_info
{
if (!method_exists($this->adapter, 'file_' . $name))
{
throw new exception('STORAGE_METHOD_NOT_IMPLEMENTED');
throw new storage_exception('STORAGE_METHOD_NOT_IMPLEMENTED');
}
$this->properties = array_merge($this->properties, call_user_func([$this->adapter, 'file_' . $name], $this->path));

View File

@@ -0,0 +1,192 @@
<?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\storage;
use phpbb\config\config;
use phpbb\di\service_collection;
class helper
{
/** @var config */
protected $config;
/** @var service_collection */
protected $provider_collection;
/** @var service_collection */
protected $adapter_collection;
/** @var adapter_factory */
protected $adapter_factory;
/** @var state_helper */
protected $state_helper;
public function __construct(config $config, service_collection $provider_collection, service_collection $adapter_collection, adapter_factory $adapter_factory, state_helper $state_helper)
{
$this->config = $config;
$this->provider_collection = $provider_collection;
$this->adapter_collection = $adapter_collection;
$this->adapter_factory = $adapter_factory;
$this->state_helper = $state_helper;
}
/**
* Get adapter definitions from a provider
*
* @param string $provider Provider class
* @return array Adapter definitions
*/
public function get_provider_options(string $provider) : array
{
return $this->provider_collection->get_by_class($provider)->get_options();
}
/**
* Get the current provider from config
*
* @param string $storage_name Storage name
* @return string The current provider
*/
public function get_current_provider(string $storage_name) : string
{
return (string) $this->config['storage\\' . $storage_name . '\\provider'];
}
/**
* Get the current value of the definition of a storage from config
*
* @param string $storage_name Storage name
* @param string $definition Definition
* @return string Definition value
*/
public function get_current_definition(string $storage_name, string $definition) : string
{
return (string) $this->config['storage\\' . $storage_name . '\\config\\' . $definition];
}
/**
* Get current storage adapter
*
* @param string $storage_name Storage adapter name
*
* @return object Storage adapter instance
*/
public function get_current_adapter(string $storage_name): object
{
static $adapters = [];
if (!isset($adapters[$storage_name]))
{
$adapters[$storage_name] = $this->adapter_factory->get($storage_name);
}
return $adapters[$storage_name];
}
/**
* Get new storage adapter
*
* @param string $storage_name
*
* @return mixed Storage adapter instance
*/
public function get_new_adapter(string $storage_name)
{
static $adapters = [];
if (!isset($adapters[$storage_name]))
{
$provider = $this->state_helper->new_provider($storage_name);
$provider_class = $this->provider_collection->get_by_class($provider);
$adapter = $this->adapter_collection->get_by_class($provider_class->get_adapter_class());
$definitions = $this->get_provider_options($provider);
$options = [];
foreach (array_keys($definitions) as $definition)
{
$options[$definition] = $this->state_helper->new_definition_value($storage_name, $definition);
}
$adapter->configure($options);
$adapters[$storage_name] = $adapter;
}
return $adapters[$storage_name];
}
public function delete_storage_options(string $storage_name): void
{
$provider = $this->get_current_provider($storage_name);
$options = $this->get_provider_options($provider);
foreach (array_keys($options) as $definition)
{
$this->config->delete('storage\\' . $storage_name . '\\config\\' . $definition);
}
}
public function set_storage_provider(string $storage_name, string $provider): void
{
$this->config->set('storage\\' . $storage_name . '\\provider', $provider);
}
public function set_storage_definition(string $storage_name, string $definition, string $value): void
{
$this->config->set('storage\\' . $storage_name . '\\config\\' . $definition, $value);
}
public function copy_file_to_new_adapter($storage_name, $file): void
{
$current_adapter = $this->get_current_adapter($storage_name);
$new_adapter = $this->get_new_adapter($storage_name);
$stream = $current_adapter->read_stream($file);
$new_adapter->write_stream($file, $stream);
if (is_resource($stream))
{
fclose($stream);
}
}
/**
* Updates a storage with the info provided in the form (that is stored in the state at this point)
*
* @param string $storage_name Storage name
*/
public function update_storage_config(string $storage_name) : void
{
// Remove old storage config
$this->delete_storage_options($storage_name);
// Update provider
$new_provider = $this->state_helper->new_provider($storage_name);
$this->set_storage_provider($storage_name, $new_provider);
// Set new storage config
$new_options = $this->get_provider_options($new_provider);
foreach (array_keys($new_options) as $definition)
{
$new_definition_value = $this->state_helper->new_definition_value($storage_name, $definition);
$this->set_storage_definition($storage_name, $definition, $new_definition_value);
}
}
}

View File

@@ -0,0 +1,215 @@
<?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\storage;
use phpbb\config\config;
use phpbb\config\db_text;
use phpbb\di\service_collection;
use phpbb\request\request;
use phpbb\storage\exception\action_in_progress_exception;
use phpbb\storage\exception\no_action_in_progress_exception;
class state_helper
{
/** @var config */
protected $config;
/** @var db_text $config_text */
protected $config_text;
/** @var service_collection */
protected $provider_collection;
public function __construct(config $config, db_text $config_text, service_collection $provider_collection)
{
$this->config = $config;
$this->config_text = $config_text;
$this->provider_collection = $provider_collection;
}
/**
* Returns if there is an action in progress
*
* @return bool
*/
public function is_action_in_progress(): bool
{
return !empty(json_decode($this->config_text->get('storage_update_state'), true));
}
public function new_provider(string $storage_name): string
{
$state = $this->load_state();
return $state['storages'][$storage_name]['provider'];
}
public function new_definition_value(string $storage_name, string $definition): string
{
$state = $this->load_state();
return $state['storages'][$storage_name]['config'][$definition];
}
public function update_type(): update_type
{
$state = $this->load_state();
return update_type::from($state['update_type']);
}
public function storage_index(): int
{
$state = $this->load_state();
return $state['storage_index'];
}
public function set_storage_index(int $storage_index): void
{
$state = $this->load_state();
$state['storage_index'] = $storage_index;
$this->save_state($state);
}
public function remove_storage_index(): int
{
$state = $this->load_state();
return $state['remove_storage_index'];
}
public function set_remove_storage_index(int $storage_index): void
{
$state = $this->load_state();
$state['remove_storage_index'] = $storage_index;
$this->save_state($state);
}
public function file_index(): int
{
$state = $this->load_state();
return $state['file_index'];
}
public function set_file_index(int $file_index): void
{
$state = $this->load_state();
$state['file_index'] = $file_index;
$this->save_state($state);
}
public function storages(): array
{
$state = $this->load_state();
return array_keys($state['storages']);
}
/**
* Start a indexing or delete process.
*
* @param update_type $update_type
* @param array $modified_storages
* @param request $request
*
* @throws action_in_progress_exception If there is an action in progress
* @throws \JsonException
*/
public function init(update_type $update_type, array $modified_storages, request $request): void
{
// Is not possible to start a new process when there is one already running
if ($this->is_action_in_progress())
{
throw new action_in_progress_exception();
}
$state = [
// Save the value of the checkbox, to remove all files from the
// old storage once they have been successfully moved
'update_type' => $update_type->value,
'storages' => [],
'storage_index' => 0,
'file_index' => 0,
'remove_storage_index' => 0,
];
// Save in the state the selected storages and their new configuration
foreach ($modified_storages as $storage_name)
{
$state['storages'][$storage_name] = [];
$state['storages'][$storage_name]['provider'] = $request->variable([$storage_name, 'provider'], '');
$options = $this->provider_collection->get_by_class($request->variable([$storage_name, 'provider'], ''))->get_options();
foreach (array_keys($options) as $definition)
{
$state['storages'][$storage_name]['config'][$definition] = $request->variable([$storage_name, $definition], '');
}
}
$this->save_state($state);
}
/**
* Clear the state
*
* @throws \JsonException
*/
public function clear_state(): void
{
$this->save_state([]);
}
/**
* Load the state from the database
*
* @return array
*
* @throws no_action_in_progress_exception If there is no action in progress
*/
private function load_state(): array
{
// Is not possible to execute an action over state if is empty
if (!$this->is_action_in_progress())
{
throw new no_action_in_progress_exception();
}
return json_decode($this->config_text->get('storage_update_state'), true) ?? [];
}
/**
* Save the specified state in the database
*
* @param array $state
*
* @throws \JsonException
*/
private function save_state(array $state = []): void
{
$this->config_text->set('storage_update_state', json_encode($state, JSON_THROW_ON_ERROR));
}
}

View File

@@ -15,7 +15,7 @@ namespace phpbb\storage;
use phpbb\cache\driver\driver_interface as cache;
use phpbb\db\driver\driver_interface as db;
use phpbb\storage\exception\exception;
use phpbb\storage\exception\storage_exception;
/**
* Experimental
@@ -102,14 +102,14 @@ class storage
* @param string $path The file to be written to.
* @param string $content The data to write into the file.
*
* @throws exception When the file already exists
* @throws storage_exception When the file already exists
* When the file cannot be written
*/
public function put_contents($path, $content)
{
if ($this->exists($path))
{
throw new exception('STORAGE_FILE_EXISTS', $path);
throw new storage_exception('STORAGE_FILE_EXISTS', $path);
}
$this->get_adapter()->put_contents($path, $content);
@@ -121,17 +121,17 @@ class storage
*
* @param string $path The file to read
*
* @throws exception When the file doesn't exist
* When cannot read file contents
* @return string Returns file contents
*
* @return string Returns file contents
*@throws storage_exception When the file doesn't exist
* When cannot read file contents
*
*/
public function get_contents($path)
{
if (!$this->exists($path))
{
throw new exception('STORAGE_FILE_NO_EXIST', $path);
throw new storage_exception('STORAGE_FILE_NO_EXIST', $path);
}
return $this->get_adapter()->get_contents($path);
@@ -155,14 +155,14 @@ class storage
*
* @param string $path file/directory to remove
*
* @throws exception When removal fails
* @throws storage_exception When removal fails
* When the file doesn't exist
*/
public function delete($path)
{
if (!$this->exists($path))
{
throw new exception('STORAGE_FILE_NO_EXIST', $path);
throw new storage_exception('STORAGE_FILE_NO_EXIST', $path);
}
$this->get_adapter()->delete($path);
@@ -175,7 +175,7 @@ class storage
* @param string $path_orig The original file/direcotry
* @param string $path_dest The target file/directory
*
* @throws exception When the file doesn't exist
* @throws storage_exception When the file doesn't exist
* When target exists
* When file/directory cannot be renamed
*/
@@ -183,12 +183,12 @@ class storage
{
if (!$this->exists($path_orig))
{
throw new exception('STORAGE_FILE_NO_EXIST', $path_orig);
throw new storage_exception('STORAGE_FILE_NO_EXIST', $path_orig);
}
if ($this->exists($path_dest))
{
throw new exception('STORAGE_FILE_EXISTS', $path_dest);
throw new storage_exception('STORAGE_FILE_EXISTS', $path_dest);
}
$this->get_adapter()->rename($path_orig, $path_dest);
@@ -201,7 +201,7 @@ class storage
* @param string $path_orig The original filename
* @param string $path_dest The target filename
*
* @throws exception When the file doesn't exist
* @throws storage_exception When the file doesn't exist
* When target exists
* When the file cannot be copied
*/
@@ -209,12 +209,12 @@ class storage
{
if (!$this->exists($path_orig))
{
throw new exception('STORAGE_FILE_NO_EXIST', $path_orig);
throw new storage_exception('STORAGE_FILE_NO_EXIST', $path_orig);
}
if ($this->exists($path_dest))
{
throw new exception('STORAGE_FILE_EXISTS', $path_dest);
throw new storage_exception('STORAGE_FILE_EXISTS', $path_dest);
}
$this->get_adapter()->copy($path_orig, $path_dest);
@@ -226,16 +226,16 @@ class storage
*
* @param string $path File to read
*
* @throws exception When the file doesn't exist
* @return resource Returns a file pointer
*@throws storage_exception When the file doesn't exist
* When unable to open file
*
* @return resource Returns a file pointer
*/
public function read_stream($path)
{
if (!$this->exists($path))
{
throw new exception('STORAGE_FILE_NO_EXIST', $path);
throw new storage_exception('STORAGE_FILE_NO_EXIST', $path);
}
$stream = null;
@@ -262,19 +262,19 @@ class storage
* @param string $path The target file
* @param resource $resource The resource
*
* @throws exception When the file exist
* @throws storage_exception When the file exist
* When target file cannot be created
*/
public function write_stream($path, $resource)
{
if ($this->exists($path))
{
throw new exception('STORAGE_FILE_EXISTS', $path);
throw new storage_exception('STORAGE_FILE_EXISTS', $path);
}
if (!is_resource($resource))
{
throw new exception('STORAGE_INVALID_RESOURCE');
throw new storage_exception('STORAGE_INVALID_RESOURCE');
}
$adapter = $this->get_adapter();
@@ -301,7 +301,7 @@ class storage
{
if (!$this->get_adapter()->exists($path))
{
throw new exception('STORAGE_FILE_NO_EXIST', $path);
throw new storage_exception('STORAGE_FILE_NO_EXIST', $path);
}
$sql_ary = array(
@@ -403,16 +403,16 @@ class storage
*
* @param string $path The file
*
* @throws exception When the adapter doesn't implement the method
* @return \phpbb\storage\file_info Returns file_info object
*@throws storage_exception When the adapter doesn't implement the method
* When the file doesn't exist
*
* @return \phpbb\storage\file_info Returns file_info object
*/
public function file_info($path)
{
if (!$this->exists($path))
{
throw new exception('STORAGE_FILE_NO_EXIST', $path);
throw new storage_exception('STORAGE_FILE_NO_EXIST', $path);
}
return new file_info($this->get_adapter(), $path);
@@ -484,9 +484,9 @@ class storage
/**
* Get space available in bytes
*
* @throws exception When unable to retrieve available storage space
* @return float Returns available space
*@throws storage_exception When unable to retrieve available storage space
*
* @return float Returns available space
*/
public function free_space()
{

View File

@@ -13,7 +13,7 @@
namespace phpbb\storage;
use phpbb\storage\exception\exception;
use phpbb\storage\exception\storage_exception;
interface stream_interface
{
@@ -23,7 +23,7 @@ interface stream_interface
* @param string $path File to read
*
* @return resource Returns a file pointer
* @throws exception When unable to open file
* @throws storage_exception When unable to open file
*/
public function read_stream(string $path);
@@ -34,7 +34,7 @@ interface stream_interface
* @param resource $resource The resource
*
* @return void
* @throws exception When target file exists
* @throws storage_exception When target file exists
* When target file cannot be created
*/
public function write_stream(string $path, $resource): void;

View File

@@ -0,0 +1,21 @@
<?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\storage;
enum update_type: int
{
case CONFIG = 0;
case COPY = 1;
case MOVE = 2;
}