mirror of
https://github.com/phpbb/phpbb.git
synced 2025-06-05 22:14:59 +02:00
Merge pull request #3913 from marc1706/ticket/14168
[ticket/14168] Refactor attachment management functions into classes * marc1706/ticket/14168: (36 commits) [ticket/14168] Correctly state return type of upload and upload_attachment [ticket/14168] Use attachment manager instead of separate classes [ticket/14168] Fix docblock in manager [ticket/14168] Add more test cases for attachment manager [ticket/14168] Add new test method and more tests [ticket/14168] Fix tabs in manager and add test file [ticket/14168] Fix tests after rebase [ticket/14168] Add attachment manager service [ticket/14168] Use correct docblock [ticket/14168] Add services_attachment.yml to services.yml [ticket/14168] Minor coding style fixes [ticket/14168] Move attachment service definitions to services_attachment [ticket/14168] Improve code coverage in upload class [ticket/14168] Move image check and don't use trigger_error() [ticket/14168] Add tests for init_error() during upload [ticket/14168] Add basic test file for attachments upload [ticket/14168] Fix CS issue [ticket/14168] No longer use deprecated functions in core files [ticket/14168] Move phpbb_unlink() into attachment delete class [ticket/14168] Reset sequence before tests in delete tests ...
This commit is contained in:
commit
cac090b659
@ -1,4 +1,5 @@
|
||||
imports:
|
||||
- { resource: services_attachment.yml }
|
||||
- { resource: services_auth.yml }
|
||||
- { resource: services_avatar.yml }
|
||||
- { resource: services_captcha.yml }
|
||||
|
40
phpBB/config/default/container/services_attachment.yml
Normal file
40
phpBB/config/default/container/services_attachment.yml
Normal file
@ -0,0 +1,40 @@
|
||||
services:
|
||||
attachment.delete:
|
||||
class: phpbb\attachment\delete
|
||||
scope: prototype
|
||||
arguments:
|
||||
- @config
|
||||
- @dbal.conn
|
||||
- @dispatcher
|
||||
- @filesystem
|
||||
- @attachment.resync
|
||||
- %core.root_path%
|
||||
|
||||
attachment.manager:
|
||||
class: phpbb\attachment\manager
|
||||
scope: prototype
|
||||
arguments:
|
||||
- @attachment.delete
|
||||
- @attachment.resync
|
||||
- @attachment.upload
|
||||
|
||||
attachment.resync:
|
||||
class: phpbb\attachment\resync
|
||||
scope: prototype
|
||||
arguments:
|
||||
- @dbal.conn
|
||||
|
||||
attachment.upload:
|
||||
class: phpbb\attachment\upload
|
||||
scope: prototype
|
||||
arguments:
|
||||
- @auth
|
||||
- @cache
|
||||
- @config
|
||||
- @files.upload
|
||||
- @language
|
||||
- @mimetype.guesser
|
||||
- @dispatcher
|
||||
- @plupload
|
||||
- @user
|
||||
- %core.root_path%
|
@ -39,6 +39,9 @@ class acp_attachments
|
||||
/** @var \phpbb\filesystem\filesystem_interface */
|
||||
protected $filesystem;
|
||||
|
||||
/** @var \phpbb\attachment\manager */
|
||||
protected $attachment_manager;
|
||||
|
||||
public $id;
|
||||
public $u_action;
|
||||
protected $new_config;
|
||||
@ -55,6 +58,7 @@ class acp_attachments
|
||||
$this->user = $user;
|
||||
$this->phpbb_container = $phpbb_container;
|
||||
$this->filesystem = $phpbb_filesystem;
|
||||
$this->attachment_manager = $phpbb_container->get('attachment.manager');
|
||||
|
||||
$user->add_lang(array('posting', 'viewtopic', 'acp/attachments'));
|
||||
|
||||
@ -922,11 +926,11 @@ class acp_attachments
|
||||
$delete_files = array();
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
phpbb_unlink($row['physical_filename'], 'file');
|
||||
$this->attachment_manager->unlink($row['physical_filename'], 'file');
|
||||
|
||||
if ($row['thumbnail'])
|
||||
{
|
||||
phpbb_unlink($row['physical_filename'], 'thumbnail');
|
||||
$this->attachment_manager->unlink($row['physical_filename'], 'thumbnail');
|
||||
}
|
||||
|
||||
$delete_files[$row['attach_id']] = $row['real_filename'];
|
||||
@ -1091,7 +1095,7 @@ class acp_attachments
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if ($num_deleted = delete_attachments('attach', $delete_files))
|
||||
if ($num_deleted = $this->attachment_manager->delete('attach', $delete_files))
|
||||
{
|
||||
if (sizeof($delete_files) != $num_deleted)
|
||||
{
|
||||
|
@ -1788,7 +1788,7 @@ class acp_forums
|
||||
*/
|
||||
function delete_forum_content($forum_id)
|
||||
{
|
||||
global $db, $config, $phpbb_root_path, $phpEx, $phpbb_dispatcher;
|
||||
global $db, $config, $phpbb_root_path, $phpEx, $phpbb_container, $phpbb_dispatcher;
|
||||
|
||||
include_once($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
|
||||
|
||||
@ -1809,7 +1809,10 @@ class acp_forums
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
delete_attachments('topic', $topic_ids, false);
|
||||
/** @var \phpbb\attachment\manager $attachment_manager */
|
||||
$attachment_manager = $phpbb_container->get('attachment.manager');
|
||||
$attachment_manager->delete('topic', $topic_ids, false);
|
||||
unset($attachment_manager);
|
||||
|
||||
// Delete shadow topics pointing to topics in this forum
|
||||
delete_topic_shadows($forum_id);
|
||||
|
@ -543,7 +543,10 @@ class acp_users
|
||||
|
||||
if (confirm_box(true))
|
||||
{
|
||||
delete_attachments('user', $user_id);
|
||||
/** @var \phpbb\attachment\manager $attachment_manager */
|
||||
$attachment_manager = $phpbb_container->get('attachment.manager');
|
||||
$attachment_manager->delete('user', $user_id);
|
||||
unset($attachment_manager);
|
||||
|
||||
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_USER_DEL_ATTACH', false, array($user_row['username']));
|
||||
trigger_error($user->lang['USER_ATTACHMENTS_REMOVED'] . adm_back_link($this->u_action . '&u=' . $user_id));
|
||||
@ -2139,7 +2142,10 @@ class acp_users
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
delete_attachments('attach', $marked);
|
||||
/** @var \phpbb\attachment\manager $attachment_manager */
|
||||
$attachment_manager = $phpbb_container->get('attachment.manager');
|
||||
$attachment_manager->delete('attach', $marked);
|
||||
unset($attachment_manager);
|
||||
|
||||
$message = (sizeof($log_attachments) == 1) ? $user->lang['ATTACHMENT_DELETED'] : $user->lang['ATTACHMENTS_DELETED'];
|
||||
|
||||
|
@ -1024,7 +1024,10 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync =
|
||||
|
||||
$search->index_remove($post_ids, $poster_ids, $forum_ids);
|
||||
|
||||
delete_attachments('post', $post_ids, false);
|
||||
/** @var \phpbb\attachment\manager $attachment_manager */
|
||||
$attachment_manager = $phpbb_container->get('attachment.manager');
|
||||
$attachment_manager->delete('post', $post_ids, false);
|
||||
unset($attachment_manager);
|
||||
|
||||
/**
|
||||
* Perform additional actions during post(s) deletion
|
||||
@ -1111,329 +1114,21 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync =
|
||||
/**
|
||||
* Delete Attachments
|
||||
*
|
||||
* @deprecated 3.2.0-a1 (To be removed: 3.4.0)
|
||||
*
|
||||
* @param string $mode can be: post|message|topic|attach|user
|
||||
* @param mixed $ids can be: post_ids, message_ids, topic_ids, attach_ids, user_ids
|
||||
* @param bool $resync set this to false if you are deleting posts or topics
|
||||
*/
|
||||
function delete_attachments($mode, $ids, $resync = true)
|
||||
{
|
||||
global $db, $config, $phpbb_dispatcher;
|
||||
global $phpbb_container;
|
||||
|
||||
// 0 is as bad as an empty array
|
||||
if (empty($ids))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
/** @var \phpbb\attachment\manager $attachment_manager */
|
||||
$attachment_manager = $phpbb_container->get('attachment.manager');
|
||||
$num_deleted = $attachment_manager->delete($mode, $ids, $resync);
|
||||
|
||||
if (is_array($ids))
|
||||
{
|
||||
$ids = array_unique($ids);
|
||||
$ids = array_map('intval', $ids);
|
||||
}
|
||||
else
|
||||
{
|
||||
$ids = array((int) $ids);
|
||||
}
|
||||
|
||||
$sql_where = '';
|
||||
|
||||
switch ($mode)
|
||||
{
|
||||
case 'post':
|
||||
case 'message':
|
||||
$sql_id = 'post_msg_id';
|
||||
$sql_where = ' AND in_message = ' . ($mode == 'message' ? 1 : 0);
|
||||
break;
|
||||
|
||||
case 'topic':
|
||||
$sql_id = 'topic_id';
|
||||
break;
|
||||
|
||||
case 'user':
|
||||
$sql_id = 'poster_id';
|
||||
break;
|
||||
|
||||
case 'attach':
|
||||
default:
|
||||
$sql_id = 'attach_id';
|
||||
$mode = 'attach';
|
||||
break;
|
||||
}
|
||||
|
||||
$post_ids = $message_ids = $topic_ids = $physical = array();
|
||||
|
||||
/**
|
||||
* Perform additional actions before collecting data for attachment(s) deletion
|
||||
*
|
||||
* @event core.delete_attachments_collect_data_before
|
||||
* @var string mode Variable containing attachments deletion mode, can be: post|message|topic|attach|user
|
||||
* @var mixed ids Array or comma separated list of ids corresponding to the mode
|
||||
* @var bool resync Flag indicating if posts/messages/topics should be synchronized
|
||||
* @var string sql_id The field name to collect/delete data for depending on the mode
|
||||
* @since 3.1.7-RC1
|
||||
*/
|
||||
$vars = array(
|
||||
'mode',
|
||||
'ids',
|
||||
'resync',
|
||||
'sql_id',
|
||||
);
|
||||
extract($phpbb_dispatcher->trigger_event('core.delete_attachments_collect_data_before', compact($vars)));
|
||||
|
||||
// Collect post and topic ids for later use if we need to touch remaining entries (if resync is enabled)
|
||||
$sql = 'SELECT post_msg_id, topic_id, in_message, physical_filename, thumbnail, filesize, is_orphan
|
||||
FROM ' . ATTACHMENTS_TABLE . '
|
||||
WHERE ' . $db->sql_in_set($sql_id, $ids);
|
||||
|
||||
$sql .= $sql_where;
|
||||
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
// We only need to store post/message/topic ids if resync is enabled and the file is not orphaned
|
||||
if ($resync && !$row['is_orphan'])
|
||||
{
|
||||
if (!$row['in_message'])
|
||||
{
|
||||
$post_ids[] = $row['post_msg_id'];
|
||||
$topic_ids[] = $row['topic_id'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$message_ids[] = $row['post_msg_id'];
|
||||
}
|
||||
}
|
||||
|
||||
$physical[] = array('filename' => $row['physical_filename'], 'thumbnail' => $row['thumbnail'], 'filesize' => $row['filesize'], 'is_orphan' => $row['is_orphan']);
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
/**
|
||||
* Perform additional actions before attachment(s) deletion
|
||||
*
|
||||
* @event core.delete_attachments_before
|
||||
* @var string mode Variable containing attachments deletion mode, can be: post|message|topic|attach|user
|
||||
* @var mixed ids Array or comma separated list of ids corresponding to the mode
|
||||
* @var bool resync Flag indicating if posts/messages/topics should be synchronized
|
||||
* @var string sql_id The field name to collect/delete data for depending on the mode
|
||||
* @var array post_ids Array with post ids for deleted attachment(s)
|
||||
* @var array topic_ids Array with topic ids for deleted attachment(s)
|
||||
* @var array message_ids Array with private message ids for deleted attachment(s)
|
||||
* @var array physical Array with deleted attachment(s) physical file(s) data
|
||||
* @since 3.1.7-RC1
|
||||
*/
|
||||
$vars = array(
|
||||
'mode',
|
||||
'ids',
|
||||
'resync',
|
||||
'sql_id',
|
||||
'post_ids',
|
||||
'topic_ids',
|
||||
'message_ids',
|
||||
'physical',
|
||||
);
|
||||
extract($phpbb_dispatcher->trigger_event('core.delete_attachments_before', compact($vars)));
|
||||
|
||||
// Delete attachments
|
||||
$sql = 'DELETE FROM ' . ATTACHMENTS_TABLE . '
|
||||
WHERE ' . $db->sql_in_set($sql_id, $ids);
|
||||
|
||||
$sql .= $sql_where;
|
||||
|
||||
$db->sql_query($sql);
|
||||
$num_deleted = $db->sql_affectedrows();
|
||||
|
||||
/**
|
||||
* Perform additional actions after attachment(s) deletion from the database
|
||||
*
|
||||
* @event core.delete_attachments_from_database_after
|
||||
* @var string mode Variable containing attachments deletion mode, can be: post|message|topic|attach|user
|
||||
* @var mixed ids Array or comma separated list of ids corresponding to the mode
|
||||
* @var bool resync Flag indicating if posts/messages/topics should be synchronized
|
||||
* @var string sql_id The field name to collect/delete data for depending on the mode
|
||||
* @var array post_ids Array with post ids for deleted attachment(s)
|
||||
* @var array topic_ids Array with topic ids for deleted attachment(s)
|
||||
* @var array message_ids Array with private message ids for deleted attachment(s)
|
||||
* @var array physical Array with deleted attachment(s) physical file(s) data
|
||||
* @var int num_deleted The number of deleted attachment(s) from the database
|
||||
* @since 3.1.7-RC1
|
||||
*/
|
||||
$vars = array(
|
||||
'mode',
|
||||
'ids',
|
||||
'resync',
|
||||
'sql_id',
|
||||
'post_ids',
|
||||
'topic_ids',
|
||||
'message_ids',
|
||||
'physical',
|
||||
'num_deleted',
|
||||
);
|
||||
extract($phpbb_dispatcher->trigger_event('core.delete_attachments_from_database_after', compact($vars)));
|
||||
|
||||
if (!$num_deleted)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Delete attachments from filesystem
|
||||
$space_removed = $files_removed = 0;
|
||||
foreach ($physical as $file_ary)
|
||||
{
|
||||
if (phpbb_unlink($file_ary['filename'], 'file', true) && !$file_ary['is_orphan'])
|
||||
{
|
||||
// Only non-orphaned files count to the file size
|
||||
$space_removed += $file_ary['filesize'];
|
||||
$files_removed++;
|
||||
}
|
||||
|
||||
if ($file_ary['thumbnail'])
|
||||
{
|
||||
phpbb_unlink($file_ary['filename'], 'thumbnail', true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform additional actions after attachment(s) deletion from the filesystem
|
||||
*
|
||||
* @event core.delete_attachments_from_filesystem_after
|
||||
* @var string mode Variable containing attachments deletion mode, can be: post|message|topic|attach|user
|
||||
* @var mixed ids Array or comma separated list of ids corresponding to the mode
|
||||
* @var bool resync Flag indicating if posts/messages/topics should be synchronized
|
||||
* @var string sql_id The field name to collect/delete data for depending on the mode
|
||||
* @var array post_ids Array with post ids for deleted attachment(s)
|
||||
* @var array topic_ids Array with topic ids for deleted attachment(s)
|
||||
* @var array message_ids Array with private message ids for deleted attachment(s)
|
||||
* @var array physical Array with deleted attachment(s) physical file(s) data
|
||||
* @var int num_deleted The number of deleted attachment(s) from the database
|
||||
* @var int space_removed The size of deleted files(s) from the filesystem
|
||||
* @var int files_removed The number of deleted file(s) from the filesystem
|
||||
* @since 3.1.7-RC1
|
||||
*/
|
||||
$vars = array(
|
||||
'mode',
|
||||
'ids',
|
||||
'resync',
|
||||
'sql_id',
|
||||
'post_ids',
|
||||
'topic_ids',
|
||||
'message_ids',
|
||||
'physical',
|
||||
'num_deleted',
|
||||
'space_removed',
|
||||
'files_removed',
|
||||
);
|
||||
extract($phpbb_dispatcher->trigger_event('core.delete_attachments_from_filesystem_after', compact($vars)));
|
||||
|
||||
if ($space_removed || $files_removed)
|
||||
{
|
||||
$config->increment('upload_dir_size', $space_removed * (-1), false);
|
||||
$config->increment('num_files', $files_removed * (-1), false);
|
||||
}
|
||||
|
||||
// If we do not resync, we do not need to adjust any message, post, topic or user entries
|
||||
if (!$resync)
|
||||
{
|
||||
return $num_deleted;
|
||||
}
|
||||
|
||||
// No more use for the original ids
|
||||
unset($ids);
|
||||
|
||||
// Now, we need to resync posts, messages, topics. We go through every one of them
|
||||
$post_ids = array_unique($post_ids);
|
||||
$message_ids = array_unique($message_ids);
|
||||
$topic_ids = array_unique($topic_ids);
|
||||
|
||||
// Update post indicators for posts now no longer having attachments
|
||||
if (sizeof($post_ids))
|
||||
{
|
||||
// Just check which posts are still having an assigned attachment not orphaned by querying the attachments table
|
||||
$sql = 'SELECT post_msg_id
|
||||
FROM ' . ATTACHMENTS_TABLE . '
|
||||
WHERE ' . $db->sql_in_set('post_msg_id', $post_ids) . '
|
||||
AND in_message = 0
|
||||
AND is_orphan = 0';
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
$remaining_ids = array();
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$remaining_ids[] = $row['post_msg_id'];
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
// Now only unset those ids remaining
|
||||
$post_ids = array_diff($post_ids, $remaining_ids);
|
||||
|
||||
if (sizeof($post_ids))
|
||||
{
|
||||
$sql = 'UPDATE ' . POSTS_TABLE . '
|
||||
SET post_attachment = 0
|
||||
WHERE ' . $db->sql_in_set('post_id', $post_ids);
|
||||
$db->sql_query($sql);
|
||||
}
|
||||
}
|
||||
|
||||
// Update message table if messages are affected
|
||||
if (sizeof($message_ids))
|
||||
{
|
||||
// Just check which messages are still having an assigned attachment not orphaned by querying the attachments table
|
||||
$sql = 'SELECT post_msg_id
|
||||
FROM ' . ATTACHMENTS_TABLE . '
|
||||
WHERE ' . $db->sql_in_set('post_msg_id', $message_ids) . '
|
||||
AND in_message = 1
|
||||
AND is_orphan = 0';
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
$remaining_ids = array();
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$remaining_ids[] = $row['post_msg_id'];
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
// Now only unset those ids remaining
|
||||
$message_ids = array_diff($message_ids, $remaining_ids);
|
||||
|
||||
if (sizeof($message_ids))
|
||||
{
|
||||
$sql = 'UPDATE ' . PRIVMSGS_TABLE . '
|
||||
SET message_attachment = 0
|
||||
WHERE ' . $db->sql_in_set('msg_id', $message_ids);
|
||||
$db->sql_query($sql);
|
||||
}
|
||||
}
|
||||
|
||||
// Now update the topics. This is a bit trickier, because there could be posts still having attachments within the topic
|
||||
if (sizeof($topic_ids))
|
||||
{
|
||||
// Just check which topics are still having an assigned attachment not orphaned by querying the attachments table (much less entries expected)
|
||||
$sql = 'SELECT topic_id
|
||||
FROM ' . ATTACHMENTS_TABLE . '
|
||||
WHERE ' . $db->sql_in_set('topic_id', $topic_ids) . '
|
||||
AND is_orphan = 0';
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
$remaining_ids = array();
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$remaining_ids[] = $row['topic_id'];
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
// Now only unset those ids remaining
|
||||
$topic_ids = array_diff($topic_ids, $remaining_ids);
|
||||
|
||||
if (sizeof($topic_ids))
|
||||
{
|
||||
$sql = 'UPDATE ' . TOPICS_TABLE . '
|
||||
SET topic_attachment = 0
|
||||
WHERE ' . $db->sql_in_set('topic_id', $topic_ids);
|
||||
$db->sql_query($sql);
|
||||
}
|
||||
}
|
||||
unset($attachment_manager);
|
||||
|
||||
return $num_deleted;
|
||||
}
|
||||
@ -1551,27 +1246,19 @@ function update_posted_info(&$topic_ids)
|
||||
|
||||
/**
|
||||
* Delete attached file
|
||||
*
|
||||
* @deprecated 3.2.0-a1 (To be removed: 3.4.0)
|
||||
*/
|
||||
function phpbb_unlink($filename, $mode = 'file', $entry_removed = false)
|
||||
{
|
||||
global $db, $phpbb_root_path, $config;
|
||||
global $phpbb_container;
|
||||
|
||||
// Because of copying topics or modifications a physical filename could be assigned more than once. If so, do not remove the file itself.
|
||||
$sql = 'SELECT COUNT(attach_id) AS num_entries
|
||||
FROM ' . ATTACHMENTS_TABLE . "
|
||||
WHERE physical_filename = '" . $db->sql_escape(utf8_basename($filename)) . "'";
|
||||
$result = $db->sql_query($sql);
|
||||
$num_entries = (int) $db->sql_fetchfield('num_entries');
|
||||
$db->sql_freeresult($result);
|
||||
/** @var \phpbb\attachment\manager $attachment_manager */
|
||||
$attachment_manager = $phpbb_container->get('attachment.manager');
|
||||
$unlink = $attachment_manager->unlink($filename, $mode, $entry_removed);
|
||||
unset($attachment_manager);
|
||||
|
||||
// Do not remove file if at least one additional entry with the same name exist.
|
||||
if (($entry_removed && $num_entries > 0) || (!$entry_removed && $num_entries > 1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$filename = ($mode == 'thumbnail') ? 'thumb_' . utf8_basename($filename) : utf8_basename($filename);
|
||||
return @unlink($phpbb_root_path . $config['upload_path'] . '/' . $filename);
|
||||
return $unlink;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -391,183 +391,27 @@ function posting_gen_topic_types($forum_id, $cur_topic_type = POST_NORMAL)
|
||||
* Upload Attachment - filedata is generated here
|
||||
* Uses upload class
|
||||
*
|
||||
* @deprecated 3.2.0-a1 (To be removed: 3.4.0)
|
||||
*
|
||||
* @param string $form_name The form name of the file upload input
|
||||
* @param int $forum_id The id of the forum
|
||||
* @param bool $local Whether the file is local or not
|
||||
* @param string $local_storage The path to the local file
|
||||
* @param bool $is_message Whether it is a PM or not
|
||||
* @param \filespec $local_filedata A filespec object created for the local file
|
||||
* @param \phpbb\mimetype\guesser $mimetype_guesser The mimetype guesser object if used
|
||||
* @param \phpbb\plupload\plupload $plupload The plupload object if one is being used
|
||||
* @param array $local_filedata A filespec object created for the local file
|
||||
*
|
||||
* @return object filespec
|
||||
* @return array File data array
|
||||
*/
|
||||
function upload_attachment($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = false, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null)
|
||||
function upload_attachment($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = false)
|
||||
{
|
||||
global $auth, $user, $config, $db, $cache;
|
||||
global $phpbb_root_path, $phpEx, $phpbb_dispatcher, $phpbb_container;
|
||||
global $phpbb_container;
|
||||
|
||||
$filedata = array(
|
||||
'error' => array()
|
||||
);
|
||||
/** @var \phpbb\attachment\manager $attachment_manager */
|
||||
$attachment_manager = $phpbb_container->get('attachment.manager');
|
||||
$file = $attachment_manager->upload($form_name, $forum_id, $local, $local_storage, $is_message, $local_filedata);
|
||||
unset($attachment_manager);
|
||||
|
||||
$upload = $phpbb_container->get('files.upload');
|
||||
|
||||
if ($config['check_attachment_content'] && isset($config['mime_triggers']))
|
||||
{
|
||||
$upload->set_disallowed_content(explode('|', $config['mime_triggers']));
|
||||
}
|
||||
else if (!$config['check_attachment_content'])
|
||||
{
|
||||
$upload->set_disallowed_content(array());
|
||||
}
|
||||
|
||||
$filedata['post_attach'] = $local || $upload->is_valid($form_name);
|
||||
|
||||
if (!$filedata['post_attach'])
|
||||
{
|
||||
$filedata['error'][] = $user->lang['NO_UPLOAD_FORM_FOUND'];
|
||||
return $filedata;
|
||||
}
|
||||
|
||||
$extensions = $cache->obtain_attach_extensions((($is_message) ? false : (int) $forum_id));
|
||||
$upload->set_allowed_extensions(array_keys($extensions['_allowed_']));
|
||||
|
||||
/** @var \phpbb\files\filespec $file */
|
||||
$file = ($local) ? $upload->handle_upload('files.types.local', $local_storage, $local_filedata) : $upload->handle_upload('files.types.form', $form_name);
|
||||
|
||||
if ($file->init_error())
|
||||
{
|
||||
$filedata['post_attach'] = false;
|
||||
return $filedata;
|
||||
}
|
||||
|
||||
// Whether the uploaded file is in the image category
|
||||
$is_image = (isset($extensions[$file->get('extension')]['display_cat'])) ? $extensions[$file->get('extension')]['display_cat'] == ATTACHMENT_CATEGORY_IMAGE : false;
|
||||
|
||||
if (!$auth->acl_get('a_') && !$auth->acl_get('m_', $forum_id))
|
||||
{
|
||||
// Check Image Size, if it is an image
|
||||
if ($is_image)
|
||||
{
|
||||
$file->upload->set_allowed_dimensions(0, 0, $config['img_max_width'], $config['img_max_height']);
|
||||
}
|
||||
|
||||
// Admins and mods are allowed to exceed the allowed filesize
|
||||
if (!empty($extensions[$file->get('extension')]['max_filesize']))
|
||||
{
|
||||
$allowed_filesize = $extensions[$file->get('extension')]['max_filesize'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$allowed_filesize = ($is_message) ? $config['max_filesize_pm'] : $config['max_filesize'];
|
||||
}
|
||||
|
||||
$file->upload->set_max_filesize($allowed_filesize);
|
||||
}
|
||||
|
||||
$file->clean_filename('unique', $user->data['user_id'] . '_');
|
||||
|
||||
// Are we uploading an image *and* this image being within the image category?
|
||||
// Only then perform additional image checks.
|
||||
$file->move_file($config['upload_path'], false, !$is_image);
|
||||
|
||||
// Do we have to create a thumbnail?
|
||||
$filedata['thumbnail'] = ($is_image && $config['img_create_thumbnail']) ? 1 : 0;
|
||||
|
||||
if (sizeof($file->error))
|
||||
{
|
||||
$file->remove();
|
||||
$filedata['error'] = array_merge($filedata['error'], $file->error);
|
||||
$filedata['post_attach'] = false;
|
||||
|
||||
return $filedata;
|
||||
}
|
||||
|
||||
// Make sure the image category only holds valid images...
|
||||
if ($is_image && !$file->is_image())
|
||||
{
|
||||
$file->remove();
|
||||
|
||||
if ($plupload && $plupload->is_active())
|
||||
{
|
||||
$plupload->emit_error(104, 'ATTACHED_IMAGE_NOT_IMAGE');
|
||||
}
|
||||
|
||||
// If this error occurs a user tried to exploit an IE Bug by renaming extensions
|
||||
// Since the image category is displaying content inline we need to catch this.
|
||||
trigger_error($user->lang['ATTACHED_IMAGE_NOT_IMAGE']);
|
||||
}
|
||||
|
||||
$filedata['filesize'] = $file->get('filesize');
|
||||
$filedata['mimetype'] = $file->get('mimetype');
|
||||
$filedata['extension'] = $file->get('extension');
|
||||
$filedata['physical_filename'] = $file->get('realname');
|
||||
$filedata['real_filename'] = $file->get('uploadname');
|
||||
$filedata['filetime'] = time();
|
||||
|
||||
/**
|
||||
* Event to modify uploaded file before submit to the post
|
||||
*
|
||||
* @event core.modify_uploaded_file
|
||||
* @var array filedata Array containing uploaded file data
|
||||
* @var bool is_image Flag indicating if the file is an image
|
||||
* @since 3.1.0-RC3
|
||||
*/
|
||||
$vars = array(
|
||||
'filedata',
|
||||
'is_image',
|
||||
);
|
||||
extract($phpbb_dispatcher->trigger_event('core.modify_uploaded_file', compact($vars)));
|
||||
|
||||
// Check our complete quota
|
||||
if ($config['attachment_quota'])
|
||||
{
|
||||
if ($config['upload_dir_size'] + $file->get('filesize') > $config['attachment_quota'])
|
||||
{
|
||||
$filedata['error'][] = $user->lang['ATTACH_QUOTA_REACHED'];
|
||||
$filedata['post_attach'] = false;
|
||||
|
||||
$file->remove();
|
||||
|
||||
return $filedata;
|
||||
}
|
||||
}
|
||||
|
||||
// Check free disk space
|
||||
if ($free_space = @disk_free_space($phpbb_root_path . $config['upload_path']))
|
||||
{
|
||||
if ($free_space <= $file->get('filesize'))
|
||||
{
|
||||
if ($auth->acl_get('a_'))
|
||||
{
|
||||
$filedata['error'][] = $user->lang['ATTACH_DISK_FULL'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$filedata['error'][] = $user->lang['ATTACH_QUOTA_REACHED'];
|
||||
}
|
||||
$filedata['post_attach'] = false;
|
||||
|
||||
$file->remove();
|
||||
|
||||
return $filedata;
|
||||
}
|
||||
}
|
||||
|
||||
// Create Thumbnail
|
||||
if ($filedata['thumbnail'])
|
||||
{
|
||||
$source = $file->get('destination_file');
|
||||
$destination = $file->get('destination_path') . '/thumb_' . $file->get('realname');
|
||||
|
||||
if (!create_thumbnail($source, $destination, $file->get('mimetype')))
|
||||
{
|
||||
$filedata['thumbnail'] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return $filedata;
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1153,12 +1153,10 @@ function delete_pm($user_id, $msg_ids, $folder_id)
|
||||
if (sizeof($delete_ids))
|
||||
{
|
||||
// Check if there are any attachments we need to remove
|
||||
if (!function_exists('delete_attachments'))
|
||||
{
|
||||
include($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
|
||||
}
|
||||
|
||||
delete_attachments('message', $delete_ids, false);
|
||||
/** @var \phpbb\attachment\manager $attachment_manager */
|
||||
$attachment_manager = $phpbb_container->get('attachment.manager');
|
||||
$attachment_manager->delete('message', $delete_ids, false);
|
||||
unset($attachment_manager);
|
||||
|
||||
$sql = 'DELETE FROM ' . PRIVMSGS_TABLE . '
|
||||
WHERE ' . $db->sql_in_set('msg_id', $delete_ids);
|
||||
@ -1363,12 +1361,10 @@ function phpbb_delete_users_pms($user_ids)
|
||||
if (!empty($delete_ids))
|
||||
{
|
||||
// Check if there are any attachments we need to remove
|
||||
if (!function_exists('delete_attachments'))
|
||||
{
|
||||
include($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
|
||||
}
|
||||
|
||||
delete_attachments('message', $delete_ids, false);
|
||||
/** @var \phpbb\attachment\manager $attachment_manager */
|
||||
$attachment_manager = $phpbb_container->get('attachment.manager');
|
||||
$attachment_manager->delete('message', $delete_ids, false);
|
||||
unset($attachment_manager);
|
||||
|
||||
$sql = 'DELETE FROM ' . PRIVMSGS_TABLE . '
|
||||
WHERE ' . $db->sql_in_set('msg_id', $delete_ids);
|
||||
|
@ -1140,12 +1140,6 @@ class parse_message extends bbcode_firstpass
|
||||
*/
|
||||
protected $plupload;
|
||||
|
||||
/**
|
||||
* The mimetype guesser object used for attachment mimetypes
|
||||
* @var \phpbb\mimetype\guesser
|
||||
*/
|
||||
protected $mimetype_guesser;
|
||||
|
||||
/**
|
||||
* Init - give message here or manually
|
||||
*/
|
||||
@ -1541,6 +1535,7 @@ class parse_message extends bbcode_firstpass
|
||||
function parse_attachments($form_name, $mode, $forum_id, $submit, $preview, $refresh, $is_message = false)
|
||||
{
|
||||
global $config, $auth, $user, $phpbb_root_path, $phpEx, $db, $request;
|
||||
global $phpbb_container;
|
||||
|
||||
$error = array();
|
||||
|
||||
@ -1576,7 +1571,9 @@ class parse_message extends bbcode_firstpass
|
||||
{
|
||||
if ($num_attachments < $cfg['max_attachments'] || $auth->acl_get('a_') || $auth->acl_get('m_', $forum_id))
|
||||
{
|
||||
$filedata = upload_attachment($form_name, $forum_id, false, '', $is_message);
|
||||
/** @var \phpbb\attachment\manager $attachment_manager */
|
||||
$attachment_manager = $phpbb_container->get('attachment.manager');
|
||||
$filedata = $attachment_manager->upload($form_name, $forum_id, false, '', $is_message);
|
||||
$error = $filedata['error'];
|
||||
|
||||
if ($filedata['post_attach'] && !sizeof($error))
|
||||
@ -1646,6 +1643,9 @@ class parse_message extends bbcode_firstpass
|
||||
|
||||
if ($index !== false && !empty($this->attachment_data[$index]))
|
||||
{
|
||||
/** @var \phpbb\attachment\manager $attachment_manager */
|
||||
$attachment_manager = $phpbb_container->get('attachment.manager');
|
||||
|
||||
// delete selected attachment
|
||||
if ($this->attachment_data[$index]['is_orphan'])
|
||||
{
|
||||
@ -1660,11 +1660,11 @@ class parse_message extends bbcode_firstpass
|
||||
|
||||
if ($row)
|
||||
{
|
||||
phpbb_unlink($row['physical_filename'], 'file');
|
||||
$attachment_manager->unlink($row['physical_filename'], 'file');
|
||||
|
||||
if ($row['thumbnail'])
|
||||
{
|
||||
phpbb_unlink($row['physical_filename'], 'thumbnail');
|
||||
$attachment_manager->unlink($row['physical_filename'], 'thumbnail');
|
||||
}
|
||||
|
||||
$db->sql_query('DELETE FROM ' . ATTACHMENTS_TABLE . ' WHERE attach_id = ' . (int) $this->attachment_data[$index]['attach_id']);
|
||||
@ -1672,7 +1672,7 @@ class parse_message extends bbcode_firstpass
|
||||
}
|
||||
else
|
||||
{
|
||||
delete_attachments('attach', array(intval($this->attachment_data[$index]['attach_id'])));
|
||||
$attachment_manager->delete('attach', $this->attachment_data[$index]['attach_id']);
|
||||
}
|
||||
|
||||
unset($this->attachment_data[$index]);
|
||||
@ -1692,7 +1692,9 @@ class parse_message extends bbcode_firstpass
|
||||
{
|
||||
if ($num_attachments < $cfg['max_attachments'] || $auth->acl_gets('m_', 'a_', $forum_id))
|
||||
{
|
||||
$filedata = upload_attachment($form_name, $forum_id, false, '', $is_message, false, $this->mimetype_guesser, $this->plupload);
|
||||
/** @var \phpbb\attachment\manager $attachment_manager */
|
||||
$attachment_manager = $phpbb_container->get('attachment.manager');
|
||||
$filedata = $attachment_manager->upload($form_name, $forum_id, false, '', $is_message);
|
||||
$error = array_merge($error, $filedata['error']);
|
||||
|
||||
if (!sizeof($error))
|
||||
@ -1980,18 +1982,6 @@ class parse_message extends bbcode_firstpass
|
||||
$this->plupload = $plupload;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter function for passing the mimetype_guesser object
|
||||
*
|
||||
* @param \phpbb\mimetype\guesser $mimetype_guesser The mimetype_guesser object
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function set_mimetype_guesser(\phpbb\mimetype\guesser $mimetype_guesser)
|
||||
{
|
||||
$this->mimetype_guesser = $mimetype_guesser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to perform custom bbcode validation by extensions
|
||||
* can be used in bbcode_init() to assign regexp replacement
|
||||
|
@ -70,12 +70,10 @@ class ucp_attachments
|
||||
|
||||
if (confirm_box(true))
|
||||
{
|
||||
if (!function_exists('delete_attachments'))
|
||||
{
|
||||
include_once($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
|
||||
}
|
||||
|
||||
delete_attachments('attach', $delete_ids);
|
||||
/** @var \phpbb\attachment\manager $attachment_manager */
|
||||
$attachment_manager = $phpbb_container->get('attachment.manager');
|
||||
$attachment_manager->delete('attach', $delete_ids);
|
||||
unset($attachment_manager);
|
||||
|
||||
meta_refresh(3, $this->u_action);
|
||||
$message = ((sizeof($delete_ids) == 1) ? $user->lang['ATTACHMENT_DELETED'] : $user->lang['ATTACHMENTS_DELETED']) . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $this->u_action . '">', '</a>');
|
||||
|
432
phpBB/phpbb/attachment/delete.php
Normal file
432
phpBB/phpbb/attachment/delete.php
Normal file
@ -0,0 +1,432 @@
|
||||
<?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\attachment;
|
||||
|
||||
use \phpbb\config\config;
|
||||
use \phpbb\db\driver\driver_interface;
|
||||
use \phpbb\event\dispatcher;
|
||||
use \phpbb\filesystem\filesystem;
|
||||
|
||||
/**
|
||||
* Attachment delete class
|
||||
*/
|
||||
class delete
|
||||
{
|
||||
/** @var config */
|
||||
protected $config;
|
||||
|
||||
/** @var driver_interface */
|
||||
protected $db;
|
||||
|
||||
/** @var \phpbb\event\dispatcher */
|
||||
protected $dispatcher;
|
||||
|
||||
/** @var filesystem */
|
||||
protected $filesystem;
|
||||
|
||||
/** @var resync */
|
||||
protected $resync;
|
||||
|
||||
/** @var string phpBB root path */
|
||||
protected $phpbb_root_path;
|
||||
|
||||
/** @var array Attachement IDs */
|
||||
protected $ids;
|
||||
|
||||
/** @var string SQL ID string */
|
||||
private $sql_id;
|
||||
|
||||
/** @var string SQL where string */
|
||||
private $sql_where = '';
|
||||
|
||||
/** @var int Number of deleted items */
|
||||
private $num_deleted;
|
||||
|
||||
/** @var array Post IDs */
|
||||
private $post_ids = array();
|
||||
|
||||
/** @var array Message IDs */
|
||||
private $message_ids = array();
|
||||
|
||||
/** @var array Topic IDs */
|
||||
private $topic_ids = array();
|
||||
|
||||
/** @var array Info of physical file */
|
||||
private $physical = array();
|
||||
|
||||
/**
|
||||
* Attachment delete class constructor
|
||||
*
|
||||
* @param config $config
|
||||
* @param driver_interface $db
|
||||
* @param dispatcher $dispatcher
|
||||
* @param filesystem $filesystem
|
||||
* @param resync $resync
|
||||
* @param string $phpbb_root_path
|
||||
*/
|
||||
public function __construct(config $config, driver_interface $db, dispatcher $dispatcher, filesystem $filesystem, resync $resync, $phpbb_root_path)
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->db = $db;
|
||||
$this->dispatcher = $dispatcher;
|
||||
$this->filesystem = $filesystem;
|
||||
$this->resync = $resync;
|
||||
$this->phpbb_root_path = $phpbb_root_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete Attachments
|
||||
*
|
||||
* @param string $mode can be: post|message|topic|attach|user
|
||||
* @param mixed $ids can be: post_ids, message_ids, topic_ids, attach_ids, user_ids
|
||||
* @param bool $resync set this to false if you are deleting posts or topics
|
||||
*
|
||||
* @return int|bool Number of deleted attachments or false if something
|
||||
* went wrong during attachment deletion
|
||||
*/
|
||||
public function delete($mode, $ids, $resync = true)
|
||||
{
|
||||
if (!$this->set_attachment_ids($ids))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->set_sql_constraints($mode);
|
||||
|
||||
/**
|
||||
* Perform additional actions before collecting data for attachment(s) deletion
|
||||
*
|
||||
* @event core.delete_attachments_collect_data_before
|
||||
* @var string mode Variable containing attachments deletion mode, can be: post|message|topic|attach|user
|
||||
* @var mixed ids Array or comma separated list of ids corresponding to the mode
|
||||
* @var bool resync Flag indicating if posts/messages/topics should be synchronized
|
||||
* @var string sql_id The field name to collect/delete data for depending on the mode
|
||||
* @since 3.1.7-RC1
|
||||
*/
|
||||
$vars = array(
|
||||
'mode',
|
||||
'ids',
|
||||
'resync',
|
||||
'sql_id',
|
||||
);
|
||||
extract($this->dispatcher->trigger_event('core.delete_attachments_collect_data_before', compact($vars)));
|
||||
|
||||
// Collect post and topic ids for later use if we need to touch remaining entries (if resync is enabled)
|
||||
$this->collect_attachment_info($resync);
|
||||
|
||||
// Delete attachments from database
|
||||
$this->delete_attachments_from_db();
|
||||
|
||||
/**
|
||||
* Perform additional actions after attachment(s) deletion from the database
|
||||
*
|
||||
* @event core.delete_attachments_from_database_after
|
||||
* @var string mode Variable containing attachments deletion mode, can be: post|message|topic|attach|user
|
||||
* @var mixed ids Array or comma separated list of ids corresponding to the mode
|
||||
* @var bool resync Flag indicating if posts/messages/topics should be synchronized
|
||||
* @var string sql_id The field name to collect/delete data for depending on the mode
|
||||
* @var array post_ids Array with post ids for deleted attachment(s)
|
||||
* @var array topic_ids Array with topic ids for deleted attachment(s)
|
||||
* @var array message_ids Array with private message ids for deleted attachment(s)
|
||||
* @var array physical Array with deleted attachment(s) physical file(s) data
|
||||
* @var int num_deleted The number of deleted attachment(s) from the database
|
||||
* @since 3.1.7-RC1
|
||||
*/
|
||||
$vars = array(
|
||||
'mode',
|
||||
'ids',
|
||||
'resync',
|
||||
'sql_id',
|
||||
'post_ids',
|
||||
'topic_ids',
|
||||
'message_ids',
|
||||
'physical',
|
||||
'num_deleted',
|
||||
);
|
||||
extract($this->dispatcher->trigger_event('core.delete_attachments_from_database_after', compact($vars)));
|
||||
|
||||
if (!$this->num_deleted)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Delete attachments from filesystem
|
||||
$this->remove_from_filesystem();
|
||||
|
||||
// If we do not resync, we do not need to adjust any message, post, topic or user entries
|
||||
if (!$resync)
|
||||
{
|
||||
return $this->num_deleted;
|
||||
}
|
||||
|
||||
// No more use for the original ids
|
||||
unset($ids);
|
||||
|
||||
// Update post indicators for posts now no longer having attachments
|
||||
$this->resync->resync('post', $this->post_ids);
|
||||
|
||||
// Update message table if messages are affected
|
||||
$this->resync->resync('message', $this->message_ids);
|
||||
|
||||
// Now update the topics. This is a bit trickier, because there could be posts still having attachments within the topic
|
||||
$this->resync->resync('topic', $this->topic_ids);
|
||||
|
||||
return $this->num_deleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set attachment IDs
|
||||
*
|
||||
* @param mixed $ids ID or array of IDs
|
||||
*
|
||||
* @return bool True if attachment IDs were set, false if not
|
||||
*/
|
||||
protected function set_attachment_ids($ids)
|
||||
{
|
||||
// 0 is as bad as an empty array
|
||||
if (empty($ids))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_array($ids))
|
||||
{
|
||||
$ids = array_unique($ids);
|
||||
$this->ids = array_map('intval', $ids);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->ids = array((int) $ids);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set SQL constraints based on mode
|
||||
*
|
||||
* @param string $mode Delete mode; can be: post|message|topic|attach|user
|
||||
*/
|
||||
private function set_sql_constraints($mode)
|
||||
{
|
||||
switch ($mode)
|
||||
{
|
||||
case 'post':
|
||||
case 'message':
|
||||
$this->sql_id = 'post_msg_id';
|
||||
$this->sql_where = ' AND in_message = ' . ($mode == 'message' ? 1 : 0);
|
||||
break;
|
||||
|
||||
case 'topic':
|
||||
$this->sql_id = 'topic_id';
|
||||
break;
|
||||
|
||||
case 'user':
|
||||
$this->sql_id = 'poster_id';
|
||||
break;
|
||||
|
||||
case 'attach':
|
||||
default:
|
||||
$this->sql_id = 'attach_id';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect info about attachment IDs
|
||||
*
|
||||
* @param bool $resync Whether topics/posts should be resynced after delete
|
||||
*/
|
||||
protected function collect_attachment_info($resync)
|
||||
{
|
||||
// Collect post and topic ids for later use if we need to touch remaining entries (if resync is enabled)
|
||||
$sql = 'SELECT post_msg_id, topic_id, in_message, physical_filename, thumbnail, filesize, is_orphan
|
||||
FROM ' . ATTACHMENTS_TABLE . '
|
||||
WHERE ' . $this->db->sql_in_set($this->sql_id, $this->ids);
|
||||
|
||||
$sql .= $this->sql_where;
|
||||
|
||||
$result = $this->db->sql_query($sql);
|
||||
|
||||
while ($row = $this->db->sql_fetchrow($result))
|
||||
{
|
||||
// We only need to store post/message/topic ids if resync is enabled and the file is not orphaned
|
||||
if ($resync && !$row['is_orphan'])
|
||||
{
|
||||
if (!$row['in_message'])
|
||||
{
|
||||
$this->post_ids[] = $row['post_msg_id'];
|
||||
$this->topic_ids[] = $row['topic_id'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->message_ids[] = $row['post_msg_id'];
|
||||
}
|
||||
}
|
||||
|
||||
$this->physical[] = array('filename' => $row['physical_filename'], 'thumbnail' => $row['thumbnail'], 'filesize' => $row['filesize'], 'is_orphan' => $row['is_orphan']);
|
||||
}
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
// IDs should be unique
|
||||
$this->post_ids = array_unique($this->post_ids);
|
||||
$this->message_ids = array_unique($this->message_ids);
|
||||
$this->topic_ids = array_unique($this->topic_ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete attachments from database table
|
||||
*/
|
||||
protected function delete_attachments_from_db()
|
||||
{
|
||||
/**
|
||||
* Perform additional actions before attachment(s) deletion
|
||||
*
|
||||
* @event core.delete_attachments_before
|
||||
* @var string mode Variable containing attachments deletion mode, can be: post|message|topic|attach|user
|
||||
* @var mixed ids Array or comma separated list of ids corresponding to the mode
|
||||
* @var bool resync Flag indicating if posts/messages/topics should be synchronized
|
||||
* @var string sql_id The field name to collect/delete data for depending on the mode
|
||||
* @var array post_ids Array with post ids for deleted attachment(s)
|
||||
* @var array topic_ids Array with topic ids for deleted attachment(s)
|
||||
* @var array message_ids Array with private message ids for deleted attachment(s)
|
||||
* @var array physical Array with deleted attachment(s) physical file(s) data
|
||||
* @since 3.1.7-RC1
|
||||
*/
|
||||
$vars = array(
|
||||
'mode',
|
||||
'ids',
|
||||
'resync',
|
||||
'sql_id',
|
||||
'post_ids',
|
||||
'topic_ids',
|
||||
'message_ids',
|
||||
'physical',
|
||||
);
|
||||
extract($this->dispatcher->trigger_event('core.delete_attachments_before', compact($vars)));
|
||||
|
||||
// Delete attachments
|
||||
$sql = 'DELETE FROM ' . ATTACHMENTS_TABLE . '
|
||||
WHERE ' . $this->db->sql_in_set($this->sql_id, $this->ids);
|
||||
|
||||
$sql .= $this->sql_where;
|
||||
|
||||
$this->db->sql_query($sql);
|
||||
$this->num_deleted = $this->db->sql_affectedrows();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete attachments from filesystem
|
||||
*/
|
||||
protected function remove_from_filesystem()
|
||||
{
|
||||
$space_removed = $files_removed = 0;
|
||||
|
||||
foreach ($this->physical as $file_ary)
|
||||
{
|
||||
if ($this->unlink_attachment($file_ary['filename'], 'file', true) && !$file_ary['is_orphan'])
|
||||
{
|
||||
// Only non-orphaned files count to the file size
|
||||
$space_removed += $file_ary['filesize'];
|
||||
$files_removed++;
|
||||
}
|
||||
|
||||
if ($file_ary['thumbnail'])
|
||||
{
|
||||
$this->unlink_attachment($file_ary['filename'], 'thumbnail', true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform additional actions after attachment(s) deletion from the filesystem
|
||||
*
|
||||
* @event core.delete_attachments_from_filesystem_after
|
||||
* @var string mode Variable containing attachments deletion mode, can be: post|message|topic|attach|user
|
||||
* @var mixed ids Array or comma separated list of ids corresponding to the mode
|
||||
* @var bool resync Flag indicating if posts/messages/topics should be synchronized
|
||||
* @var string sql_id The field name to collect/delete data for depending on the mode
|
||||
* @var array post_ids Array with post ids for deleted attachment(s)
|
||||
* @var array topic_ids Array with topic ids for deleted attachment(s)
|
||||
* @var array message_ids Array with private message ids for deleted attachment(s)
|
||||
* @var array physical Array with deleted attachment(s) physical file(s) data
|
||||
* @var int num_deleted The number of deleted attachment(s) from the database
|
||||
* @var int space_removed The size of deleted files(s) from the filesystem
|
||||
* @var int files_removed The number of deleted file(s) from the filesystem
|
||||
* @since 3.1.7-RC1
|
||||
*/
|
||||
$vars = array(
|
||||
'mode',
|
||||
'ids',
|
||||
'resync',
|
||||
'sql_id',
|
||||
'post_ids',
|
||||
'topic_ids',
|
||||
'message_ids',
|
||||
'physical',
|
||||
'num_deleted',
|
||||
'space_removed',
|
||||
'files_removed',
|
||||
);
|
||||
extract($this->dispatcher->trigger_event('core.delete_attachments_from_filesystem_after', compact($vars)));
|
||||
|
||||
if ($space_removed || $files_removed)
|
||||
{
|
||||
$this->config->increment('upload_dir_size', $space_removed * (-1), false);
|
||||
$this->config->increment('num_files', $files_removed * (-1), false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete attachment from filesystem
|
||||
*
|
||||
* @param string $filename Filename of attachment
|
||||
* @param string $mode Delete mode
|
||||
* @param bool $entry_removed Whether entry was removed. Defaults to false
|
||||
* @return bool True if file was removed, false if not
|
||||
*/
|
||||
public function unlink_attachment($filename, $mode = 'file', $entry_removed = false)
|
||||
{
|
||||
// Because of copying topics or modifications a physical filename could be assigned more than once. If so, do not remove the file itself.
|
||||
$sql = 'SELECT COUNT(attach_id) AS num_entries
|
||||
FROM ' . ATTACHMENTS_TABLE . "
|
||||
WHERE physical_filename = '" . $this->db->sql_escape(utf8_basename($filename)) . "'";
|
||||
$result = $this->db->sql_query($sql);
|
||||
$num_entries = (int) $this->db->sql_fetchfield('num_entries');
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
// Do not remove file if at least one additional entry with the same name exist.
|
||||
if (($entry_removed && $num_entries > 0) || (!$entry_removed && $num_entries > 1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$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))
|
||||
{
|
||||
$this->filesystem->remove($this->phpbb_root_path . $this->config['upload_path'] . '/' . $filename);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (\phpbb\filesystem\exception\filesystem_exception $exception)
|
||||
{
|
||||
// Fail is covered by return statement below
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
99
phpBB/phpbb/attachment/manager.php
Normal file
99
phpBB/phpbb/attachment/manager.php
Normal file
@ -0,0 +1,99 @@
|
||||
<?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\attachment;
|
||||
|
||||
/**
|
||||
* Attachment manager
|
||||
*/
|
||||
class manager
|
||||
{
|
||||
/** @var delete Attachment delete class */
|
||||
protected $delete;
|
||||
|
||||
/** @var resync Attachment resync class */
|
||||
protected $resync;
|
||||
|
||||
/** @var upload Attachment upload class */
|
||||
protected $upload;
|
||||
|
||||
/**
|
||||
* Constructor for attachment manager
|
||||
*
|
||||
* @param delete $delete Attachment delete class
|
||||
* @param resync $resync Attachment resync class
|
||||
* @param upload $upload Attachment upload class
|
||||
*/
|
||||
public function __construct(delete $delete, resync $resync, upload $upload)
|
||||
{
|
||||
$this->delete = $delete;
|
||||
$this->resync = $resync;
|
||||
$this->upload = $upload;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper method for deleting attachments
|
||||
*
|
||||
* @param string $mode can be: post|message|topic|attach|user
|
||||
* @param mixed $ids can be: post_ids, message_ids, topic_ids, attach_ids, user_ids
|
||||
* @param bool $resync set this to false if you are deleting posts or topics
|
||||
*
|
||||
* @return int|bool Number of deleted attachments or false if something
|
||||
* went wrong during attachment deletion
|
||||
*/
|
||||
public function delete($mode, $ids, $resync = true)
|
||||
{
|
||||
return $this->delete->delete($mode, $ids, $resync);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper method for deleting attachments from filesystem
|
||||
*
|
||||
* @param string $filename Filename of attachment
|
||||
* @param string $mode Delete mode
|
||||
* @param bool $entry_removed Whether entry was removed. Defaults to false
|
||||
* @return bool True if file was removed, false if not
|
||||
*/
|
||||
public function unlink($filename, $mode = 'file', $entry_removed = false)
|
||||
{
|
||||
return $this->delete->unlink_attachment($filename, $mode, $entry_removed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper method for resyncing specified type
|
||||
*
|
||||
* @param string $type Type of resync
|
||||
* @param array $ids IDs to resync
|
||||
*/
|
||||
public function resync($type, $ids)
|
||||
{
|
||||
$this->resync->resync($type, $ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper method for uploading attachment
|
||||
*
|
||||
* @param string $form_name The form name of the file upload input
|
||||
* @param int $forum_id The id of the forum
|
||||
* @param bool $local Whether the file is local or not
|
||||
* @param string $local_storage The path to the local file
|
||||
* @param bool $is_message Whether it is a PM or not
|
||||
* @param array $local_filedata An file data object created for the local file
|
||||
*
|
||||
* @return array File data array
|
||||
*/
|
||||
public function upload($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = [])
|
||||
{
|
||||
return $this->upload->upload($form_name, $forum_id, $local, $local_storage, $is_message, $local_filedata);
|
||||
}
|
||||
}
|
124
phpBB/phpbb/attachment/resync.php
Normal file
124
phpBB/phpbb/attachment/resync.php
Normal file
@ -0,0 +1,124 @@
|
||||
<?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\attachment;
|
||||
|
||||
use \phpbb\db\driver\driver_interface;
|
||||
|
||||
/**
|
||||
* Attachment resync class
|
||||
*/
|
||||
class resync
|
||||
{
|
||||
/** @var driver_interface */
|
||||
protected $db;
|
||||
|
||||
/** @var string Attachment table SQL ID */
|
||||
private $attach_sql_id;
|
||||
|
||||
/** @var string Resync table SQL ID */
|
||||
private $resync_sql_id;
|
||||
|
||||
/** @var string Resync SQL table */
|
||||
private $resync_table;
|
||||
|
||||
/** @var string SQL where statement */
|
||||
private $sql_where;
|
||||
|
||||
/**
|
||||
* Constructor for attachment resync class
|
||||
*
|
||||
* @param driver_interface $db Database driver
|
||||
*/
|
||||
public function __construct(driver_interface $db)
|
||||
{
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set type constraints for attachment resync
|
||||
*
|
||||
* @param string $type Type of resync; can be: message|post|topic
|
||||
*/
|
||||
protected function set_type_constraints($type)
|
||||
{
|
||||
switch ($type)
|
||||
{
|
||||
case 'message':
|
||||
$this->attach_sql_id = 'post_msg_id';
|
||||
$this->sql_where = ' AND in_message = 1
|
||||
AND is_orphan = 0';
|
||||
$this->resync_table = PRIVMSGS_TABLE;
|
||||
$this->resync_sql_id = 'msg_id';
|
||||
break;
|
||||
|
||||
case 'post':
|
||||
$this->attach_sql_id = 'post_msg_id';
|
||||
$this->sql_where = ' AND in_message = 0
|
||||
AND is_orphan = 0';
|
||||
$this->resync_table = POSTS_TABLE;
|
||||
$this->resync_sql_id = 'post_id';
|
||||
break;
|
||||
|
||||
case 'topic':
|
||||
$this->attach_sql_id = 'topic_id';
|
||||
$this->sql_where = ' AND is_orphan = 0';
|
||||
$this->resync_table = TOPICS_TABLE;
|
||||
$this->resync_sql_id = 'topic_id';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resync specified type
|
||||
*
|
||||
* @param string $type Type of resync
|
||||
* @param array $ids IDs to resync
|
||||
*/
|
||||
public function resync($type, $ids)
|
||||
{
|
||||
if (empty($type) || !is_array($ids) || !sizeof($ids) || !in_array($type, array('post', 'topic', 'message')))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$this->set_type_constraints($type);
|
||||
|
||||
// Just check which elements are still having an assigned attachment
|
||||
// not orphaned by querying the attachments table
|
||||
$sql = 'SELECT ' . $this->attach_sql_id . '
|
||||
FROM ' . ATTACHMENTS_TABLE . '
|
||||
WHERE ' . $this->db->sql_in_set($this->attach_sql_id, $ids)
|
||||
. $this->sql_where;
|
||||
$result = $this->db->sql_query($sql);
|
||||
|
||||
$remaining_ids = array();
|
||||
while ($row = $this->db->sql_fetchrow($result))
|
||||
{
|
||||
$remaining_ids[] = $row[$this->attach_sql_id];
|
||||
}
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
// Now only unset those ids remaining
|
||||
$ids = array_diff($ids, $remaining_ids);
|
||||
|
||||
if (sizeof($ids))
|
||||
{
|
||||
$sql = 'UPDATE ' . $this->resync_table . '
|
||||
SET ' . $type . '_attachment = 0
|
||||
WHERE ' . $this->db->sql_in_set($this->resync_sql_id, $ids);
|
||||
$this->db->sql_query($sql);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
334
phpBB/phpbb/attachment/upload.php
Normal file
334
phpBB/phpbb/attachment/upload.php
Normal file
@ -0,0 +1,334 @@
|
||||
<?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\attachment;
|
||||
|
||||
use phpbb\auth\auth;
|
||||
use \phpbb\cache\service;
|
||||
use \phpbb\config\config;
|
||||
use \phpbb\event\dispatcher;
|
||||
use \phpbb\language\language;
|
||||
use \phpbb\mimetype\guesser;
|
||||
use \phpbb\plupload\plupload;
|
||||
use \phpbb\user;
|
||||
|
||||
/**
|
||||
* Attachment upload class
|
||||
*/
|
||||
class upload
|
||||
{
|
||||
/** @var auth */
|
||||
protected $auth;
|
||||
|
||||
/** @var service */
|
||||
protected $cache;
|
||||
|
||||
/** @var config */
|
||||
protected $config;
|
||||
|
||||
/** @var \phpbb\files\upload Upload class */
|
||||
protected $files_upload;
|
||||
|
||||
/** @var \phpbb\language\language */
|
||||
protected $language;
|
||||
|
||||
/** @var guesser Mimetype guesser */
|
||||
protected $mimetype_guesser;
|
||||
|
||||
/** @var dispatcher */
|
||||
protected $phpbb_dispatcher;
|
||||
|
||||
/** @var plupload Plupload */
|
||||
protected $plupload;
|
||||
|
||||
/** @var user */
|
||||
protected $user;
|
||||
|
||||
/** @var \phpbb\files\filespec Current filespec instance */
|
||||
private $file;
|
||||
|
||||
/** @var array File data */
|
||||
private $file_data = array(
|
||||
'error' => array()
|
||||
);
|
||||
|
||||
/** @var array Extensions array */
|
||||
private $extensions;
|
||||
|
||||
/**
|
||||
* Constructor for attachments upload class
|
||||
*
|
||||
* @param auth $auth
|
||||
* @param service $cache
|
||||
* @param config $config
|
||||
* @param \phpbb\files\upload $files_upload
|
||||
* @param language $language
|
||||
* @param guesser $mimetype_guesser
|
||||
* @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)
|
||||
{
|
||||
$this->auth = $auth;
|
||||
$this->cache = $cache;
|
||||
$this->config = $config;
|
||||
$this->files_upload = $files_upload;
|
||||
$this->language = $language;
|
||||
$this->mimetype_guesser = $mimetype_guesser;
|
||||
$this->phpbb_dispatcher = $phpbb_dispatcher;
|
||||
$this->plupload = $plupload;
|
||||
$this->user = $user;
|
||||
$this->phpbb_root_path = $phpbb_root_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload Attachment - filedata is generated here
|
||||
* Uses upload class
|
||||
*
|
||||
* @param string $form_name The form name of the file upload input
|
||||
* @param int $forum_id The id of the forum
|
||||
* @param bool $local Whether the file is local or not
|
||||
* @param string $local_storage The path to the local file
|
||||
* @param bool $is_message Whether it is a PM or not
|
||||
* @param array $local_filedata An file data object created for the local file
|
||||
*
|
||||
* @return array File data array
|
||||
*/
|
||||
public function upload($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = array())
|
||||
{
|
||||
$this->init_files_upload($forum_id, $is_message);
|
||||
|
||||
$this->file_data['post_attach'] = $local || $this->files_upload->is_valid($form_name);
|
||||
|
||||
if (!$this->file_data['post_attach'])
|
||||
{
|
||||
$this->file_data['error'][] = $this->language->lang('NO_UPLOAD_FORM_FOUND');
|
||||
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);
|
||||
|
||||
if ($this->file->init_error())
|
||||
{
|
||||
$this->file_data['post_attach'] = false;
|
||||
return $this->file_data;
|
||||
}
|
||||
|
||||
// Whether the uploaded file is in the image category
|
||||
$is_image = (isset($this->extensions[$this->file->get('extension')]['display_cat'])) ? $this->extensions[$this->file->get('extension')]['display_cat'] == ATTACHMENT_CATEGORY_IMAGE : false;
|
||||
|
||||
if (!$this->auth->acl_get('a_') && !$this->auth->acl_get('m_', $forum_id))
|
||||
{
|
||||
// Check Image Size, if it is an image
|
||||
if ($is_image)
|
||||
{
|
||||
$this->file->upload->set_allowed_dimensions(0, 0, $this->config['img_max_width'], $this->config['img_max_height']);
|
||||
}
|
||||
|
||||
// Admins and mods are allowed to exceed the allowed filesize
|
||||
if (!empty($this->extensions[$this->file->get('extension')]['max_filesize']))
|
||||
{
|
||||
$allowed_filesize = $this->extensions[$this->file->get('extension')]['max_filesize'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$allowed_filesize = ($is_message) ? $this->config['max_filesize_pm'] : $this->config['max_filesize'];
|
||||
}
|
||||
|
||||
$this->file->upload->set_max_filesize($allowed_filesize);
|
||||
}
|
||||
|
||||
$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;
|
||||
|
||||
// Make sure the image category only holds valid images...
|
||||
$this->check_image($is_image);
|
||||
|
||||
if (sizeof($this->file->error))
|
||||
{
|
||||
$this->file->remove();
|
||||
$this->file_data['error'] = array_merge($this->file_data['error'], $this->file->error);
|
||||
$this->file_data['post_attach'] = false;
|
||||
|
||||
return $this->file_data;
|
||||
}
|
||||
|
||||
$this->fill_file_data();
|
||||
|
||||
$filedata = $this->file_data;
|
||||
|
||||
/**
|
||||
* Event to modify uploaded file before submit to the post
|
||||
*
|
||||
* @event core.modify_uploaded_file
|
||||
* @var array filedata Array containing uploaded file data
|
||||
* @var bool is_image Flag indicating if the file is an image
|
||||
* @since 3.1.0-RC3
|
||||
*/
|
||||
$vars = array(
|
||||
'filedata',
|
||||
'is_image',
|
||||
);
|
||||
extract($this->phpbb_dispatcher->trigger_event('core.modify_uploaded_file', compact($vars)));
|
||||
$this->file_data = $filedata;
|
||||
unset($filedata);
|
||||
|
||||
// Check for attachment quota and free space
|
||||
if (!$this->check_attach_quota() || !$this->check_disk_space())
|
||||
{
|
||||
return $this->file_data;
|
||||
}
|
||||
|
||||
// Create Thumbnail
|
||||
$this->create_thumbnail();
|
||||
|
||||
return $this->file_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create thumbnail for file if necessary
|
||||
*
|
||||
* @return array Updated $filedata
|
||||
*/
|
||||
protected function create_thumbnail()
|
||||
{
|
||||
if ($this->file_data['thumbnail'])
|
||||
{
|
||||
$source = $this->file->get('destination_file');
|
||||
$destination = $this->file->get('destination_path') . '/thumb_' . $this->file->get('realname');
|
||||
|
||||
if (!create_thumbnail($source, $destination, $this->file->get('mimetype')))
|
||||
{
|
||||
$this->file_data['thumbnail'] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Init files upload class
|
||||
*
|
||||
* @param int $forum_id Forum ID
|
||||
* @param bool $is_message Whether attachment is inside PM or not
|
||||
*/
|
||||
protected function init_files_upload($forum_id, $is_message)
|
||||
{
|
||||
if ($this->config['check_attachment_content'] && isset($this->config['mime_triggers']))
|
||||
{
|
||||
$this->files_upload->set_disallowed_content(explode('|', $this->config['mime_triggers']));
|
||||
}
|
||||
else if (!$this->config['check_attachment_content'])
|
||||
{
|
||||
$this->files_upload->set_disallowed_content(array());
|
||||
}
|
||||
|
||||
$this->extensions = $this->cache->obtain_attach_extensions((($is_message) ? false : (int) $forum_id));
|
||||
$this->files_upload->set_allowed_extensions(array_keys($this->extensions['_allowed_']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if uploaded file is really an image
|
||||
*
|
||||
* @param bool $is_image Whether file is image
|
||||
*/
|
||||
protected function check_image($is_image)
|
||||
{
|
||||
// Make sure the image category only holds valid images...
|
||||
if ($is_image && !$this->file->is_image())
|
||||
{
|
||||
$this->file->remove();
|
||||
|
||||
if ($this->plupload && $this->plupload->is_active())
|
||||
{
|
||||
$this->plupload->emit_error(104, 'ATTACHED_IMAGE_NOT_IMAGE');
|
||||
}
|
||||
|
||||
// If this error occurs a user tried to exploit an IE Bug by renaming extensions
|
||||
// Since the image category is displaying content inline we need to catch this.
|
||||
$this->file->set_error($this->language->lang('ATTACHED_IMAGE_NOT_IMAGE'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if attachment quota was reached
|
||||
*
|
||||
* @return bool False if attachment quota was reached, true if not
|
||||
*/
|
||||
protected function check_attach_quota()
|
||||
{
|
||||
if ($this->config['attachment_quota'])
|
||||
{
|
||||
if (intval($this->config['upload_dir_size']) + $this->file->get('filesize') > $this->config['attachment_quota'])
|
||||
{
|
||||
$this->file_data['error'][] = $this->language->lang('ATTACH_QUOTA_REACHED');
|
||||
$this->file_data['post_attach'] = false;
|
||||
|
||||
$this->file->remove();
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there is enough free space available on disk
|
||||
*
|
||||
* @return bool True if disk space is available, false if not
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills file data with file information and current time as filetime
|
||||
*/
|
||||
protected function fill_file_data()
|
||||
{
|
||||
$this->file_data['filesize'] = $this->file->get('filesize');
|
||||
$this->file_data['mimetype'] = $this->file->get('mimetype');
|
||||
$this->file_data['extension'] = $this->file->get('extension');
|
||||
$this->file_data['physical_filename'] = $this->file->get('realname');
|
||||
$this->file_data['real_filename'] = $this->file->get('uploadname');
|
||||
$this->file_data['filetime'] = time();
|
||||
}
|
||||
}
|
@ -571,7 +571,6 @@ $plupload = $phpbb_container->get('plupload');
|
||||
/* @var $mimetype_guesser \phpbb\mimetype\guesser */
|
||||
$mimetype_guesser = $phpbb_container->get('mimetype.guesser');
|
||||
$message_parser->set_plupload($plupload);
|
||||
$message_parser->set_mimetype_guesser($mimetype_guesser);
|
||||
|
||||
if (isset($post_data['post_text']))
|
||||
{
|
||||
|
127
tests/attachment/delete_test.php
Normal file
127
tests/attachment/delete_test.php
Normal file
@ -0,0 +1,127 @@
|
||||
<?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.
|
||||
*
|
||||
*/
|
||||
|
||||
require_once(dirname(__FILE__) . '/../../phpBB/includes/functions_admin.php');
|
||||
|
||||
class phpbb_attachment_delete_test extends \phpbb_database_test_case
|
||||
{
|
||||
/** @var \phpbb\config\config */
|
||||
protected $config;
|
||||
|
||||
/** @var \phpbb\db\driver\driver_interface */
|
||||
protected $db;
|
||||
|
||||
/** @var \phpbb\filesystem\filesystem */
|
||||
protected $filesystem;
|
||||
|
||||
/** @var \phpbb\attachment\resync */
|
||||
protected $resync;
|
||||
|
||||
/** @var \phpbb\attachment\delete */
|
||||
protected $attachment_delete;
|
||||
|
||||
protected $phpbb_root_path;
|
||||
|
||||
public function getDataSet()
|
||||
{
|
||||
return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/resync.xml');
|
||||
}
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
global $db, $phpbb_root_path;
|
||||
|
||||
parent::setUp();
|
||||
|
||||
$this->config = new \phpbb\config\config(array());
|
||||
$this->db = $this->new_dbal();
|
||||
$db = $this->db;
|
||||
$this->resync = new \phpbb\attachment\resync($this->db);
|
||||
$this->filesystem = $this->getMock('\phpbb\filesystem\filesystem', array('remove', 'exists'));
|
||||
$this->filesystem->expects($this->any())
|
||||
->method('remove')
|
||||
->willReturn(false);
|
||||
$this->filesystem->expects($this->any())
|
||||
->method('exists')
|
||||
->willReturn(true);
|
||||
$this->phpbb_root_path = $phpbb_root_path;
|
||||
$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);
|
||||
}
|
||||
|
||||
public function data_attachment_delete()
|
||||
{
|
||||
return array(
|
||||
array('attach', '', false, false),
|
||||
array('meh', 5, false, 0),
|
||||
array('attach', array(5), false, 0),
|
||||
array('attach', array(1,2), false, 2),
|
||||
array('attach', array(1,2), true, 2),
|
||||
array('post', 5, false, 0),
|
||||
array('topic', 5, false, 0),
|
||||
array('topic', 1, true, 3),
|
||||
array('user', 1, false, 0),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider data_attachment_delete
|
||||
*/
|
||||
public function test_attachment_delete($mode, $ids, $resync, $expected)
|
||||
{
|
||||
// We need to reset the attachment ID sequence to properly test this
|
||||
if ($this->db->get_sql_layer() === 'postgres')
|
||||
{
|
||||
$sql = 'ALTER SEQUENCE phpbb_attachments_seq RESTART WITH 1';
|
||||
$this->db->sql_query($sql);
|
||||
}
|
||||
|
||||
$this->assertSame($expected, $this->attachment_delete->delete($mode, $ids, $resync));
|
||||
}
|
||||
|
||||
public function data_attachment_unlink()
|
||||
{
|
||||
return array(
|
||||
array(true, true, true),
|
||||
array(true, false, false),
|
||||
array(true, true, false, true),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider data_attachment_unlink
|
||||
*/
|
||||
public function test_attachment_delete_success($remove_success, $exists_success, $expected, $throw_exception = false)
|
||||
{
|
||||
$this->filesystem = $this->getMock('\phpbb\filesystem\filesystem', array('remove', 'exists'));
|
||||
if ($throw_exception)
|
||||
{
|
||||
$this->filesystem->expects($this->any())
|
||||
->method('remove')
|
||||
->willThrowException(new \phpbb\filesystem\exception\filesystem_exception);;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->filesystem->expects($this->any())
|
||||
->method('remove')
|
||||
->willReturn($remove_success);
|
||||
}
|
||||
|
||||
$this->filesystem->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->assertSame($expected, $this->attachment_delete->unlink_attachment('foobar'));
|
||||
}
|
||||
}
|
130
tests/attachment/fixtures/resync.xml
Normal file
130
tests/attachment/fixtures/resync.xml
Normal file
@ -0,0 +1,130 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<dataset>
|
||||
<table name="phpbb_attachments">
|
||||
<column>post_msg_id</column>
|
||||
<column>topic_id</column>
|
||||
<column>in_message</column>
|
||||
<column>is_orphan</column>
|
||||
<column>attach_comment</column>
|
||||
<column>physical_filename</column>
|
||||
<column>thumbnail</column>
|
||||
<row>
|
||||
<value>1</value>
|
||||
<value>1</value>
|
||||
<value>0</value>
|
||||
<value>0</value>
|
||||
<value>foo</value>
|
||||
<value>foo</value>
|
||||
<value>0</value>
|
||||
</row>
|
||||
<row>
|
||||
<value>1</value>
|
||||
<value>1</value>
|
||||
<value>1</value>
|
||||
<value>0</value>
|
||||
<value>foo2</value>
|
||||
<value>foo2</value>
|
||||
<value>0</value>
|
||||
</row>
|
||||
<row>
|
||||
<value>1</value>
|
||||
<value>1</value>
|
||||
<value>1</value>
|
||||
<value>0</value>
|
||||
<value>foo2</value>
|
||||
<value>foo2</value>
|
||||
<value>1</value>
|
||||
</row>
|
||||
</table>
|
||||
<table name="phpbb_extensions">
|
||||
<column>extension</column>
|
||||
<column>group_id</column>
|
||||
<row>
|
||||
<value>jpg</value>
|
||||
<value>1</value>
|
||||
</row>
|
||||
<row>
|
||||
<value>png</value>
|
||||
<value>1</value>
|
||||
</row>
|
||||
</table>
|
||||
<table name="phpbb_extension_groups">
|
||||
<column>cat_id</column>
|
||||
<column>group_id</column>
|
||||
<column>download_mode</column>
|
||||
<column>upload_icon</column>
|
||||
<column>max_filesize</column>
|
||||
<column>allow_group</column>
|
||||
<column>allow_in_pm</column>
|
||||
<column>allowed_forums</column>
|
||||
<column>group_name</column>
|
||||
<row>
|
||||
<value>1</value>
|
||||
<value>1</value>
|
||||
<value>1</value>
|
||||
<value> </value>
|
||||
<value>1000</value>
|
||||
<value>1</value>
|
||||
<value>1</value>
|
||||
<value>a:1:{i:0;i:1;}</value>
|
||||
<value>Images</value>
|
||||
</row>
|
||||
</table>
|
||||
<table name="phpbb_posts">
|
||||
<column>post_id</column>
|
||||
<column>post_text</column>
|
||||
<column>poster_id</column>
|
||||
<column>post_attachment</column>
|
||||
<row>
|
||||
<value>1</value>
|
||||
<value>foo</value>
|
||||
<value>1</value>
|
||||
<value>1</value>
|
||||
</row>
|
||||
<row>
|
||||
<value>2</value>
|
||||
<value>foo</value>
|
||||
<value>1</value>
|
||||
<value>1</value>
|
||||
</row>
|
||||
</table>
|
||||
<table name="phpbb_privmsgs">
|
||||
<column>msg_id</column>
|
||||
<column>message_text</column>
|
||||
<column>message_attachment</column>
|
||||
<column>to_address</column>
|
||||
<column>bcc_address</column>
|
||||
<row>
|
||||
<value>1</value>
|
||||
<value>foo</value>
|
||||
<value>1</value>
|
||||
<value>2</value>
|
||||
<value>2</value>
|
||||
</row>
|
||||
<row>
|
||||
<value>2</value>
|
||||
<value>foo</value>
|
||||
<value>1</value>
|
||||
<value>2</value>
|
||||
<value>2</value>
|
||||
</row>
|
||||
</table>
|
||||
<table name="phpbb_topics">
|
||||
<column>topic_id</column>
|
||||
<column>forum_id</column>
|
||||
<column>topic_title</column>
|
||||
<column>topic_attachment</column>
|
||||
<row>
|
||||
<value>1</value>
|
||||
<value>1</value>
|
||||
<value>foo</value>
|
||||
<value>1</value>
|
||||
</row>
|
||||
<row>
|
||||
<value>2</value>
|
||||
<value>1</value>
|
||||
<value>bar</value>
|
||||
<value>1</value>
|
||||
</row>
|
||||
</table>
|
||||
</dataset>
|
131
tests/attachment/manager_test.php
Normal file
131
tests/attachment/manager_test.php
Normal file
@ -0,0 +1,131 @@
|
||||
<?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.
|
||||
*
|
||||
*/
|
||||
|
||||
class phpbb_attachment_manager_test extends \phpbb_test_case
|
||||
{
|
||||
protected $delete;
|
||||
protected $resync;
|
||||
protected $upload;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->delete = $this->getMockBuilder('\phpbb\attachment\delete')
|
||||
->disableOriginalConstructor()
|
||||
->setMethods(['delete', 'unlink_attachment'])
|
||||
->getMock();
|
||||
$this->resync = $this->getMockBuilder('\phpbb\attachment\resync')
|
||||
->disableOriginalConstructor()
|
||||
->setMethods(['resync'])
|
||||
->getMock();
|
||||
$this->upload = $this->getMockBuilder('\phpbb\attachment\upload')
|
||||
->disableOriginalConstructor()
|
||||
->setMethods(['upload'])
|
||||
->getMock();
|
||||
}
|
||||
|
||||
protected function get_manager()
|
||||
{
|
||||
return new \phpbb\attachment\manager($this->delete, $this->resync, $this->upload);
|
||||
}
|
||||
|
||||
public function data_manager()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
'delete',
|
||||
'unlink_attachment',
|
||||
'unlink',
|
||||
['foo'],
|
||||
['foo', 'file', false],
|
||||
true,
|
||||
true,
|
||||
),
|
||||
array(
|
||||
'delete',
|
||||
'unlink_attachment',
|
||||
'unlink',
|
||||
['foo', 'bar'],
|
||||
['foo', 'bar', false],
|
||||
true,
|
||||
true,
|
||||
),
|
||||
array(
|
||||
'delete',
|
||||
'unlink_attachment',
|
||||
'unlink',
|
||||
['foo', 'bar', true],
|
||||
['foo', 'bar', true],
|
||||
true,
|
||||
true,
|
||||
),
|
||||
array(
|
||||
'delete',
|
||||
'delete',
|
||||
'delete',
|
||||
['foo', [1, 2, 3]],
|
||||
['foo', [1, 2, 3], true],
|
||||
5,
|
||||
5,
|
||||
),
|
||||
array(
|
||||
'delete',
|
||||
'delete',
|
||||
'delete',
|
||||
['foo', [1, 2, 3], false],
|
||||
['foo', [1, 2, 3], false],
|
||||
2,
|
||||
2,
|
||||
),
|
||||
array(
|
||||
'resync',
|
||||
'resync',
|
||||
'resync',
|
||||
['foo', [1, 2, 3]],
|
||||
['foo', [1, 2, 3]],
|
||||
true,
|
||||
null,
|
||||
),
|
||||
array(
|
||||
'upload',
|
||||
'upload',
|
||||
'upload',
|
||||
['foo', 1],
|
||||
['foo', 1, false, '', false, []],
|
||||
true,
|
||||
true,
|
||||
),
|
||||
array(
|
||||
'upload',
|
||||
'upload',
|
||||
'upload',
|
||||
['foo', 1, true, 'bar', true, ['filename' => 'foobar']],
|
||||
['foo', 1, true, 'bar', true, ['filename' => 'foobar']],
|
||||
true,
|
||||
true,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider data_manager
|
||||
*/
|
||||
public function test_manager($class, $method_class, $method_manager, $input_manager, $input_method, $return, $output)
|
||||
{
|
||||
$mock = call_user_func_array([$this->{$class}, 'expects'], [$this->atLeastOnce()]);
|
||||
$mock = $mock->method($method_class);
|
||||
$mock = call_user_func_array([$mock, 'with'], $input_method);
|
||||
$mock->willReturn($return);
|
||||
$manager = $this->get_manager();
|
||||
$this->assertSame($output, call_user_func_array([$manager, $method_manager], $input_manager));
|
||||
}
|
||||
}
|
74
tests/attachment/resync_test.php
Normal file
74
tests/attachment/resync_test.php
Normal file
@ -0,0 +1,74 @@
|
||||
<?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.
|
||||
*
|
||||
*/
|
||||
|
||||
class phpbb_attachment_resync_test extends \phpbb_database_test_case
|
||||
{
|
||||
/** @var \phpbb\db\driver\driver_interface */
|
||||
protected $db;
|
||||
|
||||
/** @var \phpbb\attachment\resync */
|
||||
protected $resync;
|
||||
|
||||
public function getDataSet()
|
||||
{
|
||||
return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/resync.xml');
|
||||
}
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->db = $this->new_dbal();
|
||||
$this->resync = new \phpbb\attachment\resync($this->db);
|
||||
}
|
||||
|
||||
public function data_resync()
|
||||
{
|
||||
return array(
|
||||
array('', array(1), 'post_id', POSTS_TABLE, array('post_attachment' => '1'), array('post_attachment' => '1')),
|
||||
array('post', array(1), 'post_id', POSTS_TABLE, array('post_attachment' => '1'), array('post_attachment' => '1')),
|
||||
array('post', array(2), 'post_id', POSTS_TABLE, array('post_attachment' => '1'), array('post_attachment' => '0')),
|
||||
array('topic', array(1), 'topic_id', TOPICS_TABLE, array('topic_attachment' => '1'), array('topic_attachment' => '1')),
|
||||
array('topic', array(2), 'topic_id', TOPICS_TABLE, array('topic_attachment' => '1'), array('topic_attachment' => '0')),
|
||||
array('message', array(1), 'msg_id', PRIVMSGS_TABLE, array('message_attachment' => '1'), array('message_attachment' => '1')),
|
||||
array('message', array(2), 'msg_id', PRIVMSGS_TABLE, array('message_attachment' => '1'), array('message_attachment' => '0')),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider data_resync
|
||||
*/
|
||||
public function test_resync($type, $ids, $sql_id, $exist_table, $exist_data, $resync_data)
|
||||
{
|
||||
$sql_prefix = ($type) ?: 'post';
|
||||
$sql = 'SELECT ' . $sql_prefix . '_attachment
|
||||
FROM ' . $exist_table . '
|
||||
WHERE ' . $sql_id . ' = ' . $ids[0];
|
||||
$result = $this->db->sql_query($sql);
|
||||
$data = $this->db->sql_fetchrow($result);
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
$this->assertEquals($exist_data, $data);
|
||||
|
||||
$this->resync->resync($type, $ids);
|
||||
|
||||
$sql = 'SELECT ' . $sql_prefix . '_attachment
|
||||
FROM ' . $exist_table . '
|
||||
WHERE ' . $sql_id . ' = ' . $ids[0];
|
||||
$result = $this->db->sql_query($sql);
|
||||
$data = $this->db->sql_fetchrow($result);
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
$this->assertEquals($resync_data, $data);
|
||||
}
|
||||
}
|
430
tests/attachment/upload_test.php
Normal file
430
tests/attachment/upload_test.php
Normal file
@ -0,0 +1,430 @@
|
||||
<?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.
|
||||
*
|
||||
*/
|
||||
|
||||
require_once(dirname(__FILE__) . '/../../phpBB/includes/functions.php');
|
||||
require_once(dirname(__FILE__) . '/../../phpBB/includes/functions_posting.php');
|
||||
|
||||
class phpbb_attachment_upload_test extends \phpbb_database_test_case
|
||||
{
|
||||
/** @var \phpbb\auth\auth */
|
||||
protected $auth;
|
||||
|
||||
/** @var \phpbb\cache\service */
|
||||
protected $cache;
|
||||
|
||||
/** @var \phpbb\config\config */
|
||||
protected $config;
|
||||
|
||||
/** @var \phpbb\files\upload */
|
||||
protected $files_upload;
|
||||
|
||||
/** @var \phpbb\language\language */
|
||||
protected $language;
|
||||
|
||||
/** @var \phpbb\mimetype\guesser */
|
||||
protected $mimetype_guesser;
|
||||
|
||||
/** @var \phpbb\event\dispatcher */
|
||||
protected $phpbb_dispatcher;
|
||||
|
||||
/** @var \phpbb\plupload\plupload */
|
||||
protected $plupload;
|
||||
|
||||
/** @var \phpbb\user */
|
||||
protected $user;
|
||||
|
||||
/** @var string phpBB root path */
|
||||
protected $phpbb_root_path;
|
||||
|
||||
/** @var \phpbb\db\driver\driver_interface */
|
||||
protected $db;
|
||||
|
||||
/** @var \phpbb\attachment\upload */
|
||||
protected $upload;
|
||||
|
||||
private $filesystem;
|
||||
|
||||
/** @var \Symfony\Component\DependencyInjection\ContainerInterface */
|
||||
protected $container;
|
||||
|
||||
/** @var \phpbb\files\factory */
|
||||
protected $factory;
|
||||
|
||||
/** @var \bantu\IniGetWrapper\IniGetWrapper */
|
||||
protected $php_ini;
|
||||
|
||||
public function getDataSet()
|
||||
{
|
||||
return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/resync.xml');
|
||||
}
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
global $config, $phpbb_root_path, $phpEx;
|
||||
|
||||
parent::setUp();
|
||||
|
||||
$this->auth = new \phpbb\auth\auth();
|
||||
$this->config = new \phpbb\config\config(array(
|
||||
'upload_path' => '',
|
||||
'img_create_thumbnail' => true,
|
||||
));
|
||||
$config = $this->config;
|
||||
$this->db = $this->new_dbal();
|
||||
$this->cache = new \phpbb\cache\service(new \phpbb\cache\driver\dummy(), $this->config, $this->db, $phpbb_root_path, $phpEx);
|
||||
$this->request = $this->getMock('\phpbb\request\request');
|
||||
|
||||
$this->filesystem = new \phpbb\filesystem\filesystem();
|
||||
$this->language = new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx));
|
||||
$this->php_ini = new \bantu\IniGetWrapper\IniGetWrapper;
|
||||
$guessers = array(
|
||||
new \Symfony\Component\HttpFoundation\File\MimeType\FileinfoMimeTypeGuesser(),
|
||||
new \Symfony\Component\HttpFoundation\File\MimeType\FileBinaryMimeTypeGuesser(),
|
||||
new \phpbb\mimetype\content_guesser(),
|
||||
new \phpbb\mimetype\extension_guesser(),
|
||||
);
|
||||
$guessers[2]->set_priority(-2);
|
||||
$guessers[3]->set_priority(-2);
|
||||
$this->mimetype_guesser = new \phpbb\mimetype\guesser($guessers);
|
||||
$this->plupload = new \phpbb\plupload\plupload($phpbb_root_path, $this->config, $this->request, new \phpbb\user($this->language, '\phpbb\datetime'), $this->php_ini, $this->mimetype_guesser);
|
||||
$factory_mock = $this->getMockBuilder('\phpbb\files\factory')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$factory_mock->expects($this->any())
|
||||
->method('get')
|
||||
->willReturn(new \phpbb\files\filespec(
|
||||
$this->filesystem,
|
||||
$this->language,
|
||||
$this->php_ini,
|
||||
new \FastImageSize\FastImageSize(),
|
||||
$this->phpbb_root_path,
|
||||
$this->mimetype_guesser
|
||||
));
|
||||
|
||||
$this->container = new phpbb_mock_container_builder($phpbb_root_path, $phpEx);
|
||||
$this->container->set('files.filespec', new \phpbb\files\filespec(
|
||||
$this->filesystem,
|
||||
$this->language,
|
||||
$this->php_ini,
|
||||
new \FastImageSize\FastImageSize(),
|
||||
$phpbb_root_path,
|
||||
new \phpbb\mimetype\guesser(array(
|
||||
'mimetype.extension_guesser' => new \phpbb\mimetype\extension_guesser(),
|
||||
))));
|
||||
$this->container->set('files.types.form', new \phpbb\files\types\form(
|
||||
$factory_mock,
|
||||
$this->language,
|
||||
$this->php_ini,
|
||||
$this->plupload,
|
||||
$this->request
|
||||
));
|
||||
$this->container->set('files.types.local', new \phpbb\files\types\local(
|
||||
$factory_mock,
|
||||
$this->language,
|
||||
$this->php_ini,
|
||||
$this->request
|
||||
));
|
||||
$this->factory = new \phpbb\files\factory($this->container);
|
||||
$this->files_upload = new \phpbb\files\upload($this->filesystem, $this->factory, $this->language, $this->php_ini, $this->request, $this->phpbb_root_path);
|
||||
$this->phpbb_dispatcher = new phpbb_mock_event_dispatcher();
|
||||
$this->user = new \phpbb\user($this->language, '\phpbb\datetime');
|
||||
|
||||
|
||||
$this->upload = new \phpbb\attachment\upload(
|
||||
$this->auth,
|
||||
$this->cache,
|
||||
$this->config,
|
||||
$this->files_upload,
|
||||
$this->language,
|
||||
$this->mimetype_guesser,
|
||||
$this->phpbb_dispatcher,
|
||||
$this->plupload,
|
||||
$this->user,
|
||||
$this->phpbb_root_path
|
||||
);
|
||||
}
|
||||
|
||||
public function data_upload()
|
||||
{
|
||||
return array(
|
||||
array('foobar', 1, false,
|
||||
array(),
|
||||
array(
|
||||
'error' => array(
|
||||
'Upload initiated but no valid file upload form found.',
|
||||
),
|
||||
'post_attach' => false,
|
||||
)
|
||||
),
|
||||
array('foobar', 1, true,
|
||||
array(
|
||||
'realname' => 'foobar.jpg',
|
||||
'type' => 'jpg',
|
||||
'size' => 100,
|
||||
),
|
||||
array(
|
||||
'error' => array(
|
||||
'NOT_UPLOADED',
|
||||
'The image file you tried to attach is invalid.',
|
||||
),
|
||||
'post_attach' => false,
|
||||
'thumbnail' => 1,
|
||||
)
|
||||
),
|
||||
array('foobar', 1, true,
|
||||
array(),
|
||||
array(
|
||||
'error' => array(
|
||||
'NOT_UPLOADED',
|
||||
),
|
||||
'post_attach' => false,
|
||||
'thumbnail' => 0,
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider data_upload
|
||||
*/
|
||||
public function test_upload($form_name, $forum_id, $local, $filedata, $expected)
|
||||
{
|
||||
$filedata = $this->upload->upload($form_name, $forum_id, $local, '', false, $filedata);
|
||||
|
||||
$this->assertSame($expected, $filedata);
|
||||
}
|
||||
|
||||
public function test_init_error()
|
||||
{
|
||||
$filespec = $this->getMockBuilder('\phpbb\files\filespec')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$filespec->expects($this->any())
|
||||
->method('init_error')
|
||||
->willReturn(true);
|
||||
$filespec->expects($this->any())
|
||||
->method('set_upload_namespace')
|
||||
->willReturnSelf();
|
||||
$filespec->expects($this->any())
|
||||
->method('set_upload_ary')
|
||||
->willReturnSelf();
|
||||
$this->container->set('files.filespec', $filespec);
|
||||
$factory_mock = $this->getMockBuilder('\phpbb\files\factory')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$factory_mock->expects($this->any())
|
||||
->method('get')
|
||||
->willReturn($filespec);
|
||||
$this->container->set('files.types.local', new \phpbb\files\types\local(
|
||||
$factory_mock,
|
||||
$this->language,
|
||||
$this->php_ini,
|
||||
$this->request
|
||||
));
|
||||
|
||||
$this->upload = new \phpbb\attachment\upload(
|
||||
$this->auth,
|
||||
$this->cache,
|
||||
$this->config,
|
||||
$this->files_upload,
|
||||
$this->language,
|
||||
$this->mimetype_guesser,
|
||||
$this->phpbb_dispatcher,
|
||||
$this->plupload,
|
||||
$this->user,
|
||||
$this->phpbb_root_path
|
||||
);
|
||||
|
||||
$filedata = $this->upload->upload('foobar', 1, true);
|
||||
|
||||
$this->assertSame(array(
|
||||
'error' => array(),
|
||||
'post_attach' => false,
|
||||
), $filedata);
|
||||
}
|
||||
|
||||
public function data_image_upload()
|
||||
{
|
||||
return array(
|
||||
array(false, false, array(),
|
||||
array(
|
||||
'error' => array('The image file you tried to attach is invalid.'),
|
||||
'post_attach' => false,
|
||||
'thumbnail' => 1,
|
||||
)
|
||||
),
|
||||
array(false, true, array(),
|
||||
array(
|
||||
'error' => array('The image file you tried to attach is invalid.'),
|
||||
'post_attach' => false,
|
||||
'thumbnail' => 1,
|
||||
)
|
||||
),
|
||||
array(true, false, array(),
|
||||
array(
|
||||
'error' => array(),
|
||||
'post_attach' => true,
|
||||
// thumbnail gets reset to 0 as creation was not possible
|
||||
'thumbnail' => 0,
|
||||
'filesize' => 100,
|
||||
'mimetype' => 'jpg',
|
||||
'extension' => 'jpg',
|
||||
'real_filename' => 'foobar.jpg',
|
||||
)
|
||||
),
|
||||
array(true, false,
|
||||
array(
|
||||
'check_attachment_content' => true,
|
||||
'mime_triggers' => '',
|
||||
),
|
||||
array(
|
||||
'error' => array(),
|
||||
'post_attach' => true,
|
||||
// thumbnail gets reset to 0 as creation was not possible
|
||||
'thumbnail' => 0,
|
||||
'filesize' => 100,
|
||||
'mimetype' => 'jpg',
|
||||
'extension' => 'jpg',
|
||||
'real_filename' => 'foobar.jpg',
|
||||
)
|
||||
),
|
||||
array(true, false,
|
||||
array(
|
||||
'attachment_quota' => 150,
|
||||
),
|
||||
array(
|
||||
'error' => array(),
|
||||
'post_attach' => true,
|
||||
// thumbnail gets reset to 0 as creation was not possible
|
||||
'thumbnail' => 0,
|
||||
'filesize' => 100,
|
||||
'mimetype' => 'jpg',
|
||||
'extension' => 'jpg',
|
||||
'real_filename' => 'foobar.jpg',
|
||||
)
|
||||
),
|
||||
array(true, false,
|
||||
array(
|
||||
'attachment_quota' => 50,
|
||||
),
|
||||
array(
|
||||
'error' => array(
|
||||
'ATTACH_QUOTA_REACHED',
|
||||
),
|
||||
'post_attach' => false,
|
||||
'thumbnail' => 1,
|
||||
'filesize' => 100,
|
||||
'mimetype' => 'jpg',
|
||||
'extension' => 'jpg',
|
||||
'real_filename' => 'foobar.jpg',
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider data_image_upload
|
||||
*/
|
||||
public function test_image_upload($is_image, $plupload_active, $config_data, $expected)
|
||||
{
|
||||
$filespec = $this->getMock('\phpbb\files\filespec',
|
||||
array(
|
||||
'init_error',
|
||||
'is_image',
|
||||
'move_file',
|
||||
'is_uploaded',
|
||||
),
|
||||
array(
|
||||
$this->filesystem,
|
||||
$this->language,
|
||||
$this->php_ini,
|
||||
new \FastImageSize\FastImageSize(),
|
||||
$this->phpbb_root_path,
|
||||
$this->mimetype_guesser,
|
||||
$this->plupload
|
||||
));
|
||||
foreach ($config_data as $key => $value)
|
||||
{
|
||||
$this->config[$key] = $value;
|
||||
}
|
||||
$filespec->set_upload_namespace($this->files_upload);
|
||||
$filespec->expects($this->any())
|
||||
->method('init_error')
|
||||
->willReturn(false);
|
||||
$filespec->expects($this->any())
|
||||
->method('is_image')
|
||||
->willReturn($is_image);
|
||||
$filespec->expects($this->any())
|
||||
->method('is_uploaded')
|
||||
->willReturn(true);
|
||||
$filespec->expects($this->any())
|
||||
->method('move_file')
|
||||
->willReturn(false);
|
||||
$this->container->set('files.filespec', $filespec);
|
||||
$factory_mock = $this->getMockBuilder('\phpbb\files\factory')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$factory_mock->expects($this->any())
|
||||
->method('get')
|
||||
->willReturn($filespec);
|
||||
$this->container->set('files.types.local', new \phpbb\files\types\local(
|
||||
$factory_mock,
|
||||
$this->language,
|
||||
$this->php_ini,
|
||||
$this->request
|
||||
));
|
||||
|
||||
$plupload = $this->getMockBuilder('\phpbb\plupload\plupload')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$plupload->expects($this->any())
|
||||
->method('is_active')
|
||||
->willReturn($plupload_active);
|
||||
if ($plupload_active)
|
||||
{
|
||||
$plupload->expects($this->once())
|
||||
->method('emit_error')
|
||||
->with(104, 'ATTACHED_IMAGE_NOT_IMAGE')
|
||||
->willReturn(false);
|
||||
}
|
||||
$this->upload = new \phpbb\attachment\upload(
|
||||
$this->auth,
|
||||
$this->cache,
|
||||
$this->config,
|
||||
$this->files_upload,
|
||||
$this->language,
|
||||
$this->mimetype_guesser,
|
||||
$this->phpbb_dispatcher,
|
||||
$plupload,
|
||||
$this->user,
|
||||
$this->phpbb_root_path
|
||||
);
|
||||
|
||||
$filedata = $this->upload->upload('foobar', 1, true, '', false, array(
|
||||
'realname' => 'foobar.jpg',
|
||||
'type' => 'jpg',
|
||||
'size' => 100,
|
||||
));
|
||||
|
||||
foreach ($expected as $key => $entry)
|
||||
{
|
||||
$this->assertEquals($entry, $filedata[$key]);
|
||||
}
|
||||
|
||||
// Reset config data
|
||||
foreach ($config_data as $key => $value)
|
||||
{
|
||||
$this->config->delete($key);
|
||||
}
|
||||
}
|
||||
}
|
@ -312,12 +312,15 @@ class phpbb_content_visibility_delete_post_test extends phpbb_database_test_case
|
||||
$lang_loader = new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx);
|
||||
$lang = new \phpbb\language\language($lang_loader);
|
||||
$user = new \phpbb\user($lang, '\phpbb\datetime');
|
||||
$attachment_delete = new \phpbb\attachment\delete($config, $db, new \phpbb_mock_event_dispatcher(), new \phpbb\filesystem\filesystem(), new \phpbb\attachment\resync($db), $phpbb_root_path);
|
||||
|
||||
$phpbb_dispatcher = new phpbb_mock_event_dispatcher();
|
||||
|
||||
$phpbb_container = new phpbb_mock_container_builder();
|
||||
$phpbb_container->set('notification_manager', new phpbb_mock_notification_manager());
|
||||
$phpbb_container->set('content.visibility', new \phpbb\content_visibility($auth, $config, $phpbb_dispatcher, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE));
|
||||
// Works as a workaround for tests
|
||||
$phpbb_container->set('attachment.manager', $attachment_delete);
|
||||
|
||||
delete_post($forum_id, $topic_id, $post_id, $data, $is_soft, $reason);
|
||||
|
||||
|
@ -25,7 +25,7 @@ class phpbb_functions_user_delete_user_test extends phpbb_database_test_case
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
global $cache, $config, $db, $phpbb_dispatcher, $phpbb_container;
|
||||
global $cache, $config, $db, $phpbb_dispatcher, $phpbb_container, $phpbb_root_path;
|
||||
|
||||
$db = $this->db = $this->new_dbal();
|
||||
$config = new \phpbb\config\config(array(
|
||||
@ -36,6 +36,8 @@ class phpbb_functions_user_delete_user_test extends phpbb_database_test_case
|
||||
$phpbb_dispatcher = new phpbb_mock_event_dispatcher();
|
||||
$phpbb_container = new phpbb_mock_container_builder();
|
||||
$phpbb_container->set('notification_manager', new phpbb_mock_notification_manager());
|
||||
// Works as a workaround for tests
|
||||
$phpbb_container->set('attachment.manager', new \phpbb\attachment\delete($config, $db, new \phpbb_mock_event_dispatcher(), new \phpbb\filesystem\filesystem(), new \phpbb\attachment\resync($db), $phpbb_root_path));
|
||||
$phpbb_container->set(
|
||||
'auth.provider.db',
|
||||
new phpbb_mock_auth_provider()
|
||||
|
@ -85,12 +85,14 @@ class phpbb_privmsgs_delete_user_pms_test extends phpbb_database_test_case
|
||||
*/
|
||||
public function test_delete_user_pms($delete_user, $remaining_privmsgs, $remaining_privmsgs_to)
|
||||
{
|
||||
global $db, $phpbb_container;
|
||||
global $db, $phpbb_container, $phpbb_root_path;
|
||||
|
||||
$db = $this->new_dbal();
|
||||
|
||||
$phpbb_container = new phpbb_mock_container_builder();
|
||||
$phpbb_container->set('notification_manager', new phpbb_mock_notification_manager());
|
||||
// Works as a workaround for tests
|
||||
$phpbb_container->set('attachment.manager', new \phpbb\attachment\delete(new \phpbb\config\config(array()), $db, new \phpbb_mock_event_dispatcher(), new \phpbb\filesystem\filesystem(), new \phpbb\attachment\resync($db), $phpbb_root_path));
|
||||
|
||||
phpbb_delete_user_pms($delete_user);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user