25.01.2018 10:45:08 am
Движок имеет несколько модулей, которые позволяют загружать файлы на сервер, один из таких: Attachment. Данный модуль работает у меня везде, где можно оставить текстовую заметку. Модуль имеет очень большой недостаток - это он не удаляет мусор. То есть изначально модуль имеет функцию, которая удаляет файлы с сервера и записи из БД, но у него не доведена до ума "связь" с другими модулями. Например, я пишу сообщение на форуме и загружаю в свой пост несколько фотографий (через форму загрузки картинок), через какое то время я или модератор удаляет мой пост, сообщение удаляется с форума, а фотографии остаются храниться на сервере, и хранятся они, как мусор, то есть ни где не используются.
Как я понял идею разработчиков: при загрузке вложения, его id должно добавляться в отведенное для этого поле, через запятую (пример:
Надеюсь понятно объяснил.
Если загружать файл через форму загрузки фала (не картинки), то id будет изменено, но при удалении сообщения с форума, вложение все ровно останется, как на сервере, так и в БД.
Постараюсь исправить этот баг.
Как я понял идею разработчиков: при загрузке вложения, его id должно добавляться в отведенное для этого поле, через запятую (пример:
23,24,25
), после отправки записи (например: сообщения на форуме), сценарий получает id добавленного сообщения и изменяет значение поля item_id на id сообщения, всех перечисленных id вложений через запятую, в таблице phpfox_attachment. В таблицу phpfox_forum_post, поле total_attachment записывается количество вложений. При удалении сообщения, проверяется количество вложений (поле: total_attachment), если значение больше ноля, то выполняется сценарий удаления всех вложений, что принадлежат удаляемому сообщению. Для форума выборка для удаления выглядит примерно так:attachment_id = 238 // ID вложения
user_id = 1 // И используется id пользователя, который имеет право на удаление вложений
Надеюсь понятно объяснил.
Если загружать файл через форму загрузки фала (не картинки), то id будет изменено, но при удалении сообщения с форума, вложение все ровно останется, как на сервере, так и в БД.
Постараюсь исправить этот баг.
- Жалоба
26.01.2018 10:25:23 am
Как то писал метод удаления вложений, при проверке их в тексте удаляемой записи.
Код метода:
Далее, при удалении, например, сообщения с форума, выполняю код выше, используя (Для все остальных модификаций, делается по аналогии):
Тут принцип удаления не продуман. На данный момент, я убираю у себя этот код.
Код метода:
// Удаление вложений
public function deleteAttachment($text, $item = null, $id = null)
{
$url = Phpfox::getParam('core.url_attachment');
if (preg_match('|' . $url . '|isu', $text))
{
preg_match_all('|' . $url . '(.*?)\[\/img\]|isu', $text, $matches);
foreach ($matches[0] as $match)
{
$match = str_replace('[/img]', '', $match);
$url_arr = explode('attachment/', $match);
$img = end($url_arr);
$img = str_replace('_thumb', '', $img);
$img = str_replace('_view', '', $img);
$img = str_replace('.', '%s.', $img);
$at = $this->database()
->select('attachment_id, user_id')
->from(Phpfox::getT('attachment'))
->where('destination = \'' . $img . '\'')
->execute('getRow');
if (!empty($at['attachment_id']))
{
$this->delete($at['user_id'], $at['attachment_id']);
}
}
}
if (!empty($item) && !empty($id))
{
$atts = $this->database()
->select('attachment_id, user_id')
->from(Phpfox::getT('attachment'))
->where('category_id = \'' . $item . '\' AND item_id = ' . (int) $id)
->execute('getRows');
if (!empty($atts))
{
foreach ($atts as $at)
{
$this->delete($at['user_id'], $at['attachment_id']);
}
}
}
} // Удаление вложений END
Далее, при удалении, например, сообщения с форума, выполняю код выше, используя (Для все остальных модификаций, делается по аналогии):
Phpfox::getService('attachment.process')->deleteAttachment($post['text'], 'forum', $id);
Тут принцип удаления не продуман. На данный момент, я убираю у себя этот код.
26.01.2018 07:57:55 pm
Покопался в коде и нашел, где добавляется тот самый id вложения, попробовал, id для вложенных картинок добавляется и обновляется в БД. Но, есть один косяк. Обо всем по порядку.
Значит, открываем: module/attachment/include/component/controller/frame.class.php, находим:
Меняем на:
Теперь, id вложенных картинок (через загрузчик фотографий) будут добавляться!
И собственно о косяке, теперь все вложения, не важно загружены они для фотографий или для всех разрешенных файлов, определяются, как вложения загруженные через форму загрузки всех разрешенных файлов и кроме того, что фотография будет вставлена в bbcode
Я уже подумываю об отказе формы загрузки для картинок, все ровно есть форма, которая позволяет загружать любые файлы. Еще вариант: добавить поле в таблицу phpfox_attachment для проверки, через какую форму был загружен файл, но отказ от формы для загрузки фото мне кажется лучшем решением. Еще думаю, стоит рассмотреть вставку фото (через загрузчик фото) в bbcode
Значит, открываем: module/attachment/include/component/controller/frame.class.php, находим:
echo '
<script type="text/javascript">
window.parent.Editor.insert({is_image: true, name: \'\', id: \'' . $iId . ':view\', type: \'image\', path: \'' . $sImagePath . '\'});
</script>
';
Меняем на:
echo '
<script type="text/javascript">
var $parent = window.parent.$(\'#' . $this->request()->get('attachment_obj_id') . '\');
$parent.find(\'.js_attachment:first\').val($parent.find(\'.js_attachment:first\').val() + \'' . $sIds . '\');
window.parent.Editor.insert({is_image: true, name: \'\', id: \'' . $iId . ':view\', type: \'image\', path: \'' . $sImagePath . '\'});
</script>
';
Теперь, id вложенных картинок (через загрузчик фотографий) будут добавляться!
И собственно о косяке, теперь все вложения, не важно загружены они для фотографий или для всех разрешенных файлов, определяются, как вложения загруженные через форму загрузки всех разрешенных файлов и кроме того, что фотография будет вставлена в bbcode
[img][/img]
, так она еще будет подгружаться под постом... Неразумно...Я уже подумываю об отказе формы загрузки для картинок, все ровно есть форма, которая позволяет загружать любые файлы. Еще вариант: добавить поле в таблицу phpfox_attachment для проверки, через какую форму был загружен файл, но отказ от формы для загрузки фото мне кажется лучшем решением. Еще думаю, стоит рассмотреть вставку фото (через загрузчик фото) в bbcode
[attachment][/attachment]
, а не [img][/img]
. В общем, пока думаю, как лучше поступить...
27.01.2018 11:09:38 am
И так, что у меня получилось: я убрал форму загрузки картинок, тут еще подумал - зачем несколько загрузчиков, если есть один для всех файлов. В файле: module/attachment/include/service/process.class.php, дописал метод:
В файле: module/forum/include/service/post/process.class.php, в метод delete добавил:
Так же добавил (в этом же методе) в первом запросе, на выборку поле total_attachment.
Пример приведен для форума, для остальных модификаций делается по аналогии.
public function deleteMass($itemId, $categoryId)
{
$rows = $this->database()
->select('attachment_id, user_id')
->from($this->table)
->where('item_id = ' . (int) $itemId . ' AND category_id = \'' . $categoryId . '\'')
->execute('getRows');
foreach ($rows as $row)
{
$this->delete($row['user_id'], $row['attachment_id']);
}
}
В файле: module/forum/include/service/post/process.class.php, в метод delete добавил:
// Удаление вложений
if ($post['total_attachment'])
{
Phpfox::getService('attachment.process')->deleteMass($post['post_id'], 'forum');
} // Удаление вложений End
Так же добавил (в этом же методе) в первом запросе, на выборку поле total_attachment.
Пример приведен для форума, для остальных модификаций делается по аналогии.
05.02.2018 09:58:00 am
Продолжаю работу. Добавил код для удаления вложений в модуль mail. Письма в данном модуле физически можно удалить только из Админ панели, пользователи могут только переносить в корзину, где будут храниться письма всю оставшиеся жизнь.
В общем, открываю: module/mail/include/service/process.class.php, нахожу функцию adminDelete и добавляю в нее следующий код:
В этой функции, в запрос добавляю поле total_attachment для выборки.
Весь код моей функции:
В общем, открываю: module/mail/include/service/process.class.php, нахожу функцию adminDelete и добавляю в нее следующий код:
// Удаление вложений
if ($mail['total_attachment'])
{
Phpfox::getService('attachment.process')->deleteMass($mail['mail_id'], 'mail');
} // Удаление вложений End
В этой функции, в запрос добавляю поле total_attachment для выборки.
Весь код моей функции:
// Delicate function, physically deletes a message from the mail and mail_text tables
public function adminDelete($id)
{
Phpfox::getUserParam('admincp.has_admin_access', true);
Phpfox::getUserParam('mail.can_read_private_messages', true); // they need to see it in order to delete it
Phpfox::getUserParam('mail.can_delete_others_messages', true);
if (Phpfox::getParam('mail.threaded_mail_conversation'))
{
$mail = $this->database()
->select('thread_id')
->from(Phpfox::getT('mail_thread'))
->where('thread_id = ' . (int) $id)
->execute('getSlaveRow');
if (empty($mail['thread_id']))
{
return false;
}
$this->database()->delete(Phpfox::getT('mail_thread'), 'thread_id = ' . (int) $id);
$this->database()->delete(Phpfox::getT('mail_thread_text'), 'thread_id = ' . (int) $id);
$this->database()->delete(Phpfox::getT('mail_thread_user'), 'thread_id = ' . (int) $id);
}
else
{
$mail = $this->database()
->select('mail_id, viewer_user_id, total_attachment')
->from(Phpfox::getT('mail'))
->where('mail_id = ' . (int) $id)
->execute('getSlaveRow');
if (empty($mail['mail_id']))
{
return false;
}
// do some logging before deleting?
$this->database()->delete($this->table, 'mail_id = ' . (int) $id);
$this->database()->delete(Phpfox::getT('mail_text'), 'mail_id = ' . (int) $id);
// Удаление вложений
if ($mail['total_attachment'])
{
Phpfox::getService('attachment.process')->deleteMass($mail['mail_id'], 'mail');
} // Удаление вложений End
}
return true;
}