101 / 100 / 51
Регистрация: 19.04.2011
Сообщений: 955
1

Найти | Удалить все дочерние комментарии

03.03.2016, 08:02. Показов 1459. Ответов 3
Метки нет (Все метки)

Доброго времени суток.
У меня как всегда проблема...
На сайте можно комментировать все, что угодно (фотки, статьи, заметки, видео и так далее), можно даже комментировать комментарий и комментарий комментария тоже можно комментировать (тавтология какая та), получается, что то типа деревовидный разговор из комментариев, например:
HTML5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
1 комментарий
-- 1 ответ на 1 комментарий
-- -- 1 ответ на ответ
-- -- 2 ответ на ответ
-- -- -- 1 ответ на ответ ответа
-- 2 ответ на 1 комментарий
2 комментарий
3 комментарий
-- 1 ответ на 3 комментарий
-- -- 1 ответ на ответ
-- -- 2 ответ на ответ
-- -- -- 1 ответ на ответ ответа
-- 2 ответ на 3 комментарий
4 комментарий
В движке есть недочет по удалению комментариев. Если я удаляю комментарий, который имеет дочерные ответы, то эти ответы остаются в базе и ни где не используются, то есть мусор. Я хочу, исправить, что бы все дочерные комменты удалялись вместе с удаляемым комментом.

В таблице комментов для построения дерева используется поле parent_id, в это поле записывается id родителя, то есть того коммента, на который ответили.

Думаю, тут нужна рекурсия (и наверно только так), но как собрать список id, даже представить не могу...

Подскажите, пожалуйста, как найти все дочерные комменты для удаления?
Спасибо.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
03.03.2016, 08:02
Ответы с готовыми решениями:

Удалить все дочерние элементы из виджета
Нужно было удалить все дочерние элементы из виджета и сделал так QList<QWidget*> widgets =...

Найти все дочерние OU
Помогите решить задачу. Использую PowerShell -> import-module activedirectory Есть главная...

Удалить все многострочные комментарии
Добрый день. Помогите удалить из скрипта все многострочные комментарии, никак не могу сообразить...

Возможно ли удалить сразу все комментарии на движке ВП?
Получилось так, что на сайте собралось 4102 коммента на 206 страниц. Если удалять по 20 штук, как...

3
Эксперт PHP
3712 / 3093 / 1299
Регистрация: 01.08.2012
Сообщений: 10,552
03.03.2016, 08:21 2
Получать список не нужно (вернее не обязательно), удаление можно сразу в рекурсии прописать. Передаёте в функцию id комментария, а она должна удалить сам комментарий и вызвать себя ещё раз, передав id потомка, что-то вроде:

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function Delete_Comment_Recursive($id)
{
    // Удаляем текущий комментарий
    mysql_query('DELETE FROM `comments` WHERE `id` = ' . (int) $id);
 
    // Получаем потомки комментария
    $comment_childs = mysql_query('SELECT `id` FROM `comments` WHERE `parent_id` = ' . (int) $id);
    
    // Если потомки есть - удаляем рекурсивно
    if(mysql_num_rows($comment_childs))
    {
        while($row = mysql_fetch_assoc($comment_childs))
            Delete_Comment_Recursive($row['id']);
    }
}
Добавлено через 3 минуты
Либо да, изменить функцию, чтобы она не удаляла комментарии, а только возвращала id потомков, объединить все id в один массив... и затем удалить всех одним запросом WHERE `id` IN().
1
Эксперт PHP
5627 / 4055 / 1459
Регистрация: 06.01.2011
Сообщений: 11,110
03.03.2016, 08:42 3
Raisin Zn, я бы сделал вообще без использования php. Для таких вещей я использую FOREIGN KEY с "ON DELETE CASCADE" в базе данных.
Когда удаляется родитель — по цепочке удаляются и все дочерние.

https://dev.mysql.com/doc/refm... -keys.html
0
101 / 100 / 51
Регистрация: 19.04.2011
Сообщений: 955
03.03.2016, 13:58  [ТС] 4
В общем пока вот что получилось:
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
    # Deletes a comment given its comment id
    # @param int $iId
    public function delete($iId)
    {       
        # delete the feed as well
        $sType = $this->database()->select('type_id')
            ->from(Phpfox::getT('comment'))
            ->where('comment_id = ' . (int) $iId)
            ->execute('getSlaveField');
        
        (Phpfox::isModule('feed') ? Phpfox::getService('feed.process')->delete($sType, (int) $iId) : null);
 
        $this->database()->delete(Phpfox::getT('like'), 'type_id = \'feed_mini\' AND item_id = ' . (int) $iId);
        $this->database()->delete(Phpfox::getT('comment'), 'comment_id = ' . (int) $iId);
        $this->database()->delete(Phpfox::getT('comment_text'), 'comment_id = ' . (int) $iId);
        $this->database()->delete(Phpfox::getT('comment_rating'), 'comment_id = ' . (int) $iId);
        
        (($sPlugin = Phpfox_Plugin::get('comment.service_process_delete')) ? eval($sPlugin) : false);
 
        $iCommentsLimb = $this->database()->select('*')
            ->from(Phpfox::getT('comment'))
            ->where('parent_id = ' . (int) $iId)
            ->execute('getRows');
        
        if ($iCommentsLimb)
        {
            $this->deletelimb($iCommentsLimb);
        }   
    }
 
    # Удаление дерево комментов  
    private function deletelimb($limb)
    {
        foreach ($limb as $value)
        {
            if ($value['total_like'])
            {
                $this->database()->delete(Phpfox::getT('like'), 'type_id = \'feed_mini\' AND item_id = ' . (int) $value['comment_id']);
            }
            
            $rows = $this->database()->select('*')
                ->from(Phpfox::getT('comment'))
                ->where('parent_id = ' . (int) $value['comment_id'])
                ->execute('getRows');
                
            $this->database()->delete(Phpfox::getT('comment'), 'comment_id = ' . (int) $value['comment_id']);
            $this->database()->delete(Phpfox::getT('comment_text'), 'comment_id = ' . (int) $value['comment_id']);
            $this->database()->delete(Phpfox::getT('comment_rating'), 'comment_id = ' . (int) $value['comment_id']);
 
            if ($rows)
            {
                $this->deletelimb($rows);
            }           
        }   
    }
Первая функция delete родная, вторую написал я, пока такой вариант... Все работает как я и хотел, не нравится только то, что запросов много получается, но думаю, как ни будь потом это исправлю...
Если Вам не трудно покритикуйте мою рекурсию...
Спасибо.

Добавлено через 1 минуту
Получается, что я запускаю один и тот же цикл несколько раз одновременно...
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
03.03.2016, 13:58
Помогаю со студенческими работами здесь

Удалить из текста все однострочные и многострочные комментарии
Текст представляет собой программу на языке Си. Удалить из него все однострочные и многострочные...

Удалить все комментарии и теги из HTML файла
Есть задание: Написать сценарий для sed и awk для удаления тегов и комментариев HTML. Теги и...

Удалить из файла все комментарии вида {комментарий}
Дан текстовый файл, содержащий строки длиной до 255 символов. Файл является программой на языке...

Прочитать программу на языке C++ и удалить все комментарии
кто-нибудь)помогите написать эту программу=\


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru