['7z', 'ace', 'bz2', 'gtar', 'gz', 'rar', 'tar', 'tgz', 'torrent', 'zip'],
'images' => ['gif', 'jpeg', 'jpg', 'png', 'tga', 'tif', 'tiff'],
'documents' => ['ai', 'doc', 'docm', 'docx', 'dot', 'dotm', 'dotx', 'odg', 'odp', 'ods', 'odt', 'pdf', 'ppt', 'pptm', 'pptx', 'ps', 'rtf', 'xls', 'xlsb', 'xlsm', 'xlsx'],
'text' => ['c', 'cpp', 'csv', 'diz', 'h', 'hpp', 'ini', 'js', 'log', 'txt', 'xml'],
'other' => ['mp3', 'mpeg', 'mpg', 'ogg', 'ogm'],
];
/** @var array File extensions specific icons */
protected $specific_icons = [
'powerpoint-o' => ['ppt', 'pptm', 'pptx'],
'excel-o' => ['csv', 'xls', 'xlsb', 'xlsm', 'xlsx'],
'pdf-o' => ['pdf'],
'audio-o' => ['mp3'],
'movie-o' => ['mpeg', 'mpg', 'ogg', 'ogm'],
'code-o' => ['c', 'cpp', 'h', 'hpp', 'ini', 'js'],
];
/** @var array File extensions icons */
protected $icons = [
'archives' => 'file-archive-o',
'images' => 'file-image-o',
'documents' => 'file-word-o',
'text' => 'file-text-o',
'other' => 'file-o',
];
/**
* Constructor.
*
* @param \phpbb\cache\service $cache Cache object
* @param \phpbb\files\factory $factory Files factory object
* @param \phpbb\filesystem\filesystem $filesystem Filesystem object
* @param string $root_path phpBB root path
* @return void
* @access public
*/
public function __construct(
\phpbb\cache\service $cache,
\phpbb\files\factory $factory,
\phpbb\filesystem\filesystem $filesystem,
$root_path
)
{
$this->cache = $cache;
$this->factory = $factory;
$this->filesystem = $filesystem;
$this->root_path = $root_path;
}
/**
* Get the shop files modes.
*
* @return array The shop files modes
* @access public
*/
public function get_modes()
{
return (array) $this->modes;
}
/**
* Set the shop files mode.
*
* @param string $mode The shop files mode
* @return self $this This object for chaining calls
* @access public
*/
public function set_mode($mode)
{
$this->mode = $mode;
return $this;
}
/**
* Set the finder instance.
*
* @return void
* @access public
*/
public function set_finder()
{
if ($this->finder === null)
{
$this->finder = new finder($this->filesystem, $this->root_path, $this->cache);
}
}
/**
* Get the file size of a shop file.
*
* @param string $directory The shop file directory
* @param string $file The shop file
* @return int
* @access public
*/
public function get_file_size($directory, $file)
{
$path = $this->get_path($directory, true, $file);
return $this->filesystem->exists($path) ? filesize($path) : 0;
}
/**
* Get the file modification time of a shop file.
*
* @param string $directory The shop file directory
* @param string $file The shop file
* @return int
* @access public
*/
public function get_file_time($directory, $file)
{
$path = $this->get_path($directory, true, $file);
return $this->filesystem->exists($path) ? filemtime($path) : 0;
}
/**
* Get the file icon of a shop file.
*
* @param string $file The shop file
* @return string
* @access public
*/
public function get_file_icon($file)
{
$extension = pathinfo($file, PATHINFO_EXTENSION);
foreach ($this->specific_icons as $icon => $extensions)
{
if (in_array($extension, $extensions))
{
return $icon;
}
}
foreach ($this->extensions as $type => $extensions)
{
if (in_array($extension, $extensions))
{
return $this->icons[$type];
}
}
return $this->icons['other'];
}
/**
* View a shop file directory.
*
* @param string $directory The shop file directory
* @return array The files and folders in the shop file directory
* @access public
*/
public function view($directory = '')
{
$files = [];
$folders = [];
$needle = $this->get_path($directory);
$target = $this->get_path($directory, false);
$this->set_finder();
foreach ($this->finder->core_path($target)->get_files() as $path)
{
$file = $this->clean_path($path, $needle);
if ($this->is_htaccess($file))
{
continue;
}
if ($this->is_not_nested($file))
{
$files[] = $file;
}
}
foreach ($this->finder->core_path($target)->get_directories() as $path)
{
$folder = $this->clean_path($path, $needle);
if ($this->is_not_nested($folder))
{
$folders[] = $folder;
}
}
if ($this->mode === 'files')
{
$this->create_htaccess();
}
return [
'files' => $files,
'folders' => $folders,
];
}
/**
* Select a shop file.
*
* @param string $directory The shop file directory
* @param string $image The shop file image
* @return array
* @access public
*/
public function select($directory, $image = '')
{
$files = [];
$needle = $this->get_path($directory);
$target = $this->get_path($directory, false);
$this->set_finder();
foreach ($this->finder->core_path($target)->get_files() as $path)
{
$file = $this->clean_path($path, $needle);
if ($this->is_not_nested($path))
{
$files[] = [
'NAME' => $file,
'S_SELECTED' => $path === $image,
];
}
}
return $files;
}
/**
* Add a shop file.
*
* @param string $directory The shop file directory
* @param string $folder The shop file folder
* @return void
* @access public
*/
public function add($directory, $folder)
{
if ($folder === '')
{
throw new runtime_exception('ASS_ERROR_TOO_SHORT', [0, 0]);
}
if (!preg_match('/^[^!"#$%&*\'()+,.\/\\\\:;<=>?@\\[\\]^`{|}~ ]*$/', $folder))
{
throw new runtime_exception('ASS_ERROR_ILLEGAL_CHARS');
}
$target = $this->get_path($directory, true, $folder);
if ($this->filesystem->exists($target))
{
throw new runtime_exception('ASS_ERROR_NOT_UNIQUE', [$folder]);
}
$this->filesystem->mkdir($target);
}
/**
* Upload a shop file from an element.
*
* @param string $directory The shop file directory
* @param string $input_name The name of the element
* @return void
* @access public
*/
public function upload($directory, $input_name)
{
/** @var \phpbb\files\upload $upload */
$upload = $this->factory->get('files.upload');
if (!$upload->is_valid($input_name))
{
throw new runtime_exception('FORM_INVALID');
}
$file = $upload
->set_allowed_extensions($this->get_extensions())
->handle_upload('files.types.form', $input_name);
$upload->common_checks($file);
if ($file->error)
{
throw new runtime_exception(implode('
', array_unique($file->error)));
}
if ($this->exists($directory, $file->get('realname')))
{
throw new runtime_exception('ASS_ERROR_NOT_UNIQUE', [$file->get('realname')]);
}
$file->move_file($this->get_path($directory, false));
}
/**
* Check if a shop file exists.
*
* @param string $directory The shop file directory
* @param string $file The shop file
* @return bool Whether or not the file exists
* @access public
*/
public function exists($directory, $file = '')
{
return (bool) $this->filesystem->exists($this->get_path($directory, true, $file));
}
/**
* Delete a shop file from a given path.
*
* @param string $path Path to a shop file
* @return void
* @access public
*/
public function delete($path)
{
$this->filesystem->remove($this->get_path($path));
}
/**
* Get a path to a shop file.
*
* @param string $directory The shop file directory
* @param bool $root Whether or not to include the phpBB root path
* @param string $file The shop file
* @return string The shop file path
* @access public
*/
public function get_path($directory, $root = true, $file = '')
{
$root_path = $root ? $this->root_path : '';
$directory = $directory ? "/{$directory}" : '';
$file = $file ? "/{$file}" : '';
return "{$root_path}{$this->mode}/aps{$directory}{$file}";
}
/**
* Get the file extensions for a mode.
*
* @return array The file extensions
* @access public
*/
public function get_extensions()
{
if ($this->mode === 'images')
{
return (array) $this->extensions[$this->mode];
}
else
{
$extensions = [];
foreach ($this->extensions as $array)
{
$extensions = array_merge($extensions, $array);
}
return (array) $extensions;
}
}
/**
* Clean the needle from a path.
*
* @param string $path The path
* @param string $needle The needle
* @return string
* @access protected
*/
protected function clean_path($path, $needle)
{
return trim(str_replace($needle, '', $path), '/');
}
/**
* Check if a path is nested.
*
* @param string $path The path
* @return bool Whether or not the path is nested
* @access protected
*/
protected function is_not_nested($path)
{
return strpos($path, '/') === false;
}
/**
* Check if a file is the ".htaccess" file.
*
* @param string $file The file
* @return bool
* @access public
*/
protected function is_htaccess($file)
{
return $this->mode === 'files' && $file === '.htaccess';
}
/**
* Create a ".htaccess" file.
*
* @return void
* @access protected
*/
protected function create_htaccess()
{
$htaccess = $this->root_path . $this->mode . '/aps/.htaccess';
if (!$this->filesystem->exists($htaccess))
{
$this->filesystem->dump_file($htaccess,
"
Order Allow,Deny
Deny from All
");
}
}
}