подписка на комментарии

Тема в разделе "PHP", создана пользователем fafee, 4 июл 2009.

Статус темы:
Закрыта.
Модераторы: latteo
  1. fafee

    fafee Постоялец

    Регистр.:
    4 окт 2008
    Сообщения:
    92
    Симпатии:
    0
    Добрый день. возникла проблема:
    Есть пользователи с user_id и альбом с media_id каждого элемента, которые хранятся в соответствующей таблице. по умолчанию каждый пользователь может комментировать любую фотографию, но не может ответить на другой комментарий, то есть комментарии выстраиваются в столбик, а не в дерево.
    Уведомления о новом комментарии отправляются только владельцу альбома.
    Чтобы улучшить ситуацию, пришла в голову мысль сделать "подписку на комментарии для любого элемента". То есть пользователь ставит галку "подписаться на комменты" и уведомление приходит не только владельцу альбома, но и ему (такая возможность встроена в движки многих форумов).
    А вот с тем как это реализовать вышла загвоздка. По идее, в таблице с media_id должно быть поле где будет массив, с user_id подписавшихся. Но тут возникает вопрос - может ли ячейка таблицы хранить массив и как потом по нему делать выборку.
    Второй вариант - создать вспомогательную таблицу - с media_id по строкам и user_id по столбцам, где будут по умолчанию ноли, и единица, если пользователь подписался на комментарий. Тут опять вопрос - при большом количестве пользователей и фотографий, таблица будет немаленькая. И скорее всего нагрузка на сервер тоже. Может есть какой-то более изящный способ?..
    php и mySQL только начинаю учить, буду благодарен любым советам. Cпасибо :)
     
  2. polyetilen

    polyetilen Заблокирован

    Регистр.:
    10 авг 2006
    Сообщения:
    814
    Симпатии:
    474
    для древовидной структуры коментариев добавить поле parent_id (от какого id) и вытягивать с рекурсией дерево коментариев, а с подпиской на элемент (коментарий?) создать новую таблицу user_id и comment_id (id коментария на который юзер подписался).

    После коментирования отправить письмо подписчику с parent_id=comment_id (parent_id из коментариев а comment_id из таблицы подписчиков)
     
  3. fafee

    fafee Постоялец

    Регистр.:
    4 окт 2008
    Сообщения:
    92
    Симпатии:
    0
    извиняюсь, а что значит с рекурсией?.. как это выглядит?
     
  4. tostrss

    tostrss

    Регистр.:
    16 окт 2007
    Сообщения:
    771
    Симпатии:
    217
    когда функция вызывает сама себя внутри.
     
  5. polyetilen

    polyetilen Заблокирован

    Регистр.:
    10 авг 2006
    Сообщения:
    814
    Симпатии:
    474
    пример скрипта
    PHP:
    <?

    $db mysql_connect("localhost""root""") or die("error");
    mysql_select_db("resursion");
    mysql_query("SET NAMES 'utf8'");

    //коментируемый объект
    $story_id 1//media_id

    $comment_array = array();
    $sql "SELECT * FROM comment WHERE story_id=$story_id";
    $result=mysql_query($sql);
    while(
    $row mysql_fetch_array($result)){
        
    $comment_array[] = $row;
    }

    echo 
    '<pre>';
    //print_r($comment_array);
    echo '</pre>';



    //первый коментарий
    $sql "SELECT MIN(parent_id) FROM comment WHERE story_id=$story_id ";
    $result=mysql_query($sql);
    if(
    mysql_num_rows($result)<=0){
        
    //нет каментов однако
        
    exit();
    }
    $row mysql_fetch_array($result);
    $comment_root_id $row[0];
    echo 
    'дерево начать от parent_id:'.$comment_root_id.'<br>';


    //распечатка дерева каментов
    child_comment($story_id$comment_root_id0);



    //когда появится коментарий, то взять его parent_id и выслать спам всем подписчикам
    //кто-то наспамил в каментах на камент с id=4, будет новый камент с parent_id=4
    $parent_id 4;
    $sql "SELECT * FROM comment_subscribe WHERE comment_id=$parent_id";
    $result=mysql_query($sql);
    while(
    $row mysql_fetch_array($result)){
        
    //пощёл спам по трубам
        //send_super_spam_to_user($row['user_id']);
    }

    //там подписка на коментарии, если надо подписка на елемент, то заменить parent_id на story_id и отсылать всем подписчикам на данный story_id







    function child_comment($story_id$comment_root_id$level) {
        global 
    $story_id$comment_array;
        if(!
    is_numeric($comment_root_id)) return false;
       
    // retrieve all children of $parent
        
    $sql="SELECT * FROM comment WHERE straipsnis_id=".$id." and parent_id = ".$komentaras_id." and rodyti=1 order by data desc ";
        
    $result=mysql_query($sql);
        
    //показываем ветки
        
    foreach($comment_array as $comment){
            if(
    $comment['parent_id'] == $comment_root_id){
                
    //чем больше уровень тем правее
                
    echo ('<div style="padding: 5px 0px 0px '.(20*$level).'px;">Коментарий id:'.$comment['id'].', parent_id:'.$comment['parent_id'].', уровень:'.$level.', текст:'.$comment['comment'].'</div>');
                
    //вытаскиваем ветку ветки на уровень больше, пропускаем ветки ссылающиеся сами на себя
                
    if($comment['id']!=$comment['parent_id'])child_comment($story_id$comment['id'], $level+1);
            }
        }
        
    //вытаскиваем коментарии коментарий
        //child_comment($row['id'], $level+1);
        
    return false;
    }



    ?>
    пример базы
    Код:
    CREATE TABLE `comment` (
      `id` int(11) NOT NULL auto_increment,
      `parent_id` int(11) NOT NULL,
      `story_id` int(11) NOT NULL,
      `comment` text NOT NULL,
      PRIMARY KEY  (`id`),
      KEY `parent_id` (`parent_id`),
      KEY `story_id` (`story_id`)
    ) ENGINE=MyISAM AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 AUTO_INCREMENT=9 ;
    
    -- 
    -- Dumping data for table `comment`
    -- 
    
    INSERT INTO `comment` VALUES (1, 0, 1, 'dfsfdsf s df sdfdsfsd f');
    INSERT INTO `comment` VALUES (2, 0, 1, '2222222sd sdf sd f sfs dfsd fs f');
    INSERT INTO `comment` VALUES (3, 0, 1, '3df sf ds f sdfsd fsf sd f');
    INSERT INTO `comment` VALUES (4, 2, 1, 'erererererererererer');
    INSERT INTO `comment` VALUES (5, 2, 1, 'ttytytytyytytytytytytyty');
    INSERT INTO `comment` VALUES (6, 4, 1, 'dsf s f s4fd4s4fdsfds f');
    INSERT INTO `comment` VALUES (0, 0, 1, 'комммммееееееенннттттт');
    INSERT INTO `comment` VALUES (8, 999, 1, 'Нет такого id, значит не покажет');
    
    -- --------------------------------------------------------
    
    -- 
    -- Table structure for table `comment_subscribe`
    -- 
    
    CREATE TABLE `comment_subscribe` (
      `user_id` int(11) NOT NULL,
      `comment_id` int(11) NOT NULL,
      KEY `user_id` (`user_id`,`comment_id`)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
    
    -- 
    -- Dumping data for table `comment_subscribe`
    -- 
    
    INSERT INTO `comment_subscribe` VALUES (1, 4);
    INSERT INTO `comment_subscribe` VALUES (2, 4);
    INSERT INTO `comment_subscribe` VALUES (3, 4);
    
    
     
    fafee нравится это.
  6. fafee

    fafee Постоялец

    Регистр.:
    4 окт 2008
    Сообщения:
    92
    Симпатии:
    0
    Подписку на комментарии прикуртил, все работает, и притом отлично. А вот с деревом, пока не понимаю. У меня комментарии реализованы как стена в контакте,так что форма куда вбивается комментарий, расположена под фотографией, а у оставленных комментариев нет функции "ответить". как смы узнаем id комментария, на который отвечаем?..
     
  7. polyetilen

    polyetilen Заблокирован

    Регистр.:
    10 авг 2006
    Сообщения:
    814
    Симпатии:
    474
    Например возле каждого коментария добавить ссылку "Ответить" и когда нажимается эта ссылка то в форму подставляется ид комментария на который отвечают с яваскриптом. Если Ответить не нажимали то parent_id=0 и будет простой комментарий.

    форма с parent_id:
    HTML:
    
    <a name="comment_form" id="comment_form"></a>
    <form action="" method="post" name="form">
        <textarea name="comment"></textarea>
        <input name="parent_id" id="parent_id" type="hidden" value="0">
        <br>
        <input name="submit_comment" type="submit" value="Коментировать">
    </form>
    
    и ссылка возле комментария:
    PHP:
    echo ('<div style="padding: 5px 0px 0px '.(20*$level).'px;">Коментарий id:'.$comment['id'].', parent_id:'.$comment['parent_id'].', уровень:'.$level.', текст:'.$comment['comment'].'<a href="#comment_form" onclick="document.getElementById(\'parent_id\').value = '.$comment['id'].';">Ответить</a></div>');
    Хорошо бы проверять перед сохранением комментария есть ли такой комментарий на который отвечают.
     
    fafee нравится это.
  8. fafee

    fafee Постоялец

    Регистр.:
    4 окт 2008
    Сообщения:
    92
    Симпатии:
    0
    Выручаете вы меня, спасибо:)
     
Статус темы:
Закрыта.