1. Приветствуем Вас на неофициальном форуме технической поддержки XenForo на русском языке. XenForo - новый и перспективный форумный движок от бывших создателей vBulletin.

1.1.x Запрос выполняется несколько раз

Тема в разделе "Вопросы и ответы по XenForo Framework", создана пользователем Agel_Nash, 2 апр 2012.

Загрузка
  1. Agel_Nash

    Agel_Nash Пользователь

    Регистрация:
    23.01.12
    Сообщения:
    16
    Симпатии:
    7
    Версия XF:
    1.1.2
    Допустим имеется следующий код
    PHP:
    $db XenForo_Application::getDb();
    $db->insert("time",array("time"=>time()));
    Который необходимо выплонять на всех страницах форума. Для этого внедряю его в index.php
    После чего при 1 просмотре страницы в базе вижу появление от 2 до 6 новых записей!!! О0!!
    От куда? Битый час ковыряюсь, а найти причину не могу(

    Скорее всего я слишком костыльно подошел к решению вопроса. Проще наверное нада было создать какой-то автоподгружаемый класс и туда запихнуть мой код. Если так, то тогда подскажите, в какую сторону копать, чтобы мой класс выполнялся на всех страницах...
     
  2. infis

    infis Местный Команда форума

    Регистрация:
    27.06.11
    Сообщения:
    5.525
    Симпатии:
    3.322
    Версия XF:
    1.5.9
    Зависит от конечной цели. Что Ваш код должен делать?
     
  3. Agel_Nash

    Agel_Nash Пользователь

    Регистрация:
    23.01.12
    Сообщения:
    16
    Симпатии:
    7
    Версия XF:
    1.1.2
    Делать вставку определенной записи в базу, либо если она существует инкрементно увеличивать счетчик... (аля внутренний счетчик посещений, на основе GeoIP, т.е. с какого региона сколько человек посетило сайт и сколько просмотрело.

    Вот рабочий код
    PHP:
    $geoCode=$_SERVER['GEOIP_COUNTRY_CODE'];
    $sql=$db->select()->from(array('gi'=>'an_geo_info'),array('code','count','countHint','id'))->where("code = '".$geoCode."'  AND mode='forum'");
    $select=$sql->query();
    $tmp=$select->fetchAll();
    if(
    count($tmp)>0){
        if(isset(
    $_SESSION['view']) && $_SESSION['view']=='1'){
        
    $count=$tmp[0]['countHint']+1;
        
    $db->update("an_geo_info",array('countHint'=>$count),array("code = '".$geoCode."' AND id='".$tmp[0]['id']."' AND mode='forum' "));
    }else{
        
    $countA=$tmp[0]['count']+1;
        
    $countB=$tmp[0]['countHint']+2;
      
    $db->update("an_geo_info",array('count'=>$countA,'countHint'=>$countB),array("code = '".$geoCode."' AND id='".$tmp[0]['id']."' AND mode='forum'"));
        
    $_SESSION['view']='1';
    }
    }else{
    $db->insert("an_geo_info",array("code"=>$geoCode,"count"=>"1",'countHint'=>'1','mode'=>'forum'));
    $_SESSION['view']='1';
    }
    Но он тоже выполняется от 2 до 6 раз за 1 обращение к странице.
     
  4. infis

    infis Местный Команда форума

    Регистрация:
    27.06.11
    Сообщения:
    5.525
    Симпатии:
    3.322
    Версия XF:
    1.5.9
    В этом случае, наверное, проще всего будет это повесить на хук footer, который вызывается для каждой генерируемой страницы.
    1. Создаем папку в library с именем, например, GeoVisitor.
    2. В этой папке создаем файл Listener.php с кодом примерно следующего содержания:
    Код:
    <?php
    class GeoVisitor_Listener
    {
        public static function template_hook ($hookName, &$contents, array $hookParams, XenForo_Template_Abstract $template)
        {
            if($hookName=='footer')
            {
    ... здесь помещаете Ваш код ...
            }
        }
    
    3. Затем в админке в "Разработка" - "Обработчики событий" создаете новый обработчик. Обратите внимание, что для отображения меню "Разработка" должен быть включен режим отладки в конфиге: $config['debug'] = true;
    4. В этом обработчике нужно заполнить следующее:
    а) выбираем из списка template_hook;
    б) в качестве класса указываем GeoVisitor;
    в) в качестве метода указываем template_hook;
    г) остальное можно оставить, как есть.
    5. В общем-то все. Теперь при построении каждой страницы будет срабатывать Ваш код, так как хук footer срабатывает для каждой страницы при формировании ее низа ("подвала").

    Напрямую включать код в index.php крайне не рекомендуется, так как там код вызывается совсем не обязательно для отображаемой страницы. Например, тот же cron также вызывает index.php, что, видимо, у Вас и происходит.
     
    Agel_Nash нравится это.
  5. Pepelac

    Pepelac Продам луц в бутылках Команда форума

    Регистрация:
    28.09.10
    Сообщения:
    1.794
    Симпатии:
    1.349
    Может лучше на событие front_controller_post_view?
     
  6. infis

    infis Местный Команда форума

    Регистрация:
    27.06.11
    Сообщения:
    5.525
    Симпатии:
    3.322
    Версия XF:
    1.5.9
    Можно и так. Но в таком случае не все просмотры будут зафиксированы. Ведь этот контроллер, если не ошибаюсь, только при просмотре тем работает. Т.е. не попадут просмотры главной страницы форума, профиля пользователя и прочие. Хотя, конечно, вешать абсолютно на на все страницы запрос на апдейт будет как-то не очень правильно. Но хозяин - барин. Ему ведь нужно по условиям задачи
    Если подходить к решению этой задачи рационально, то есть смысл использовать кеш и не гонять лишний раз
    PHP:
    $sql=$db->select()->from(array('gi'=>'an_geo_info'),array('code','count','countHint','id'))->where("code = '".$geoCode."'  AND mode='forum'");
    Да и сохранять визиты также можно не каждый раз, а через очередь.
     
  7. Pepelac

    Pepelac Продам луц в бутылках Команда форума

    Регистрация:
    28.09.10
    Сообщения:
    1.794
    Симпатии:
    1.349
    Фронт контроллер работает всегда (см. файл index.php). И событие это срабатывает перед отправкой полностью сгенерированной страницы пользователю.
     
  8. infis

    infis Местный Команда форума

    Регистрация:
    27.06.11
    Сообщения:
    5.525
    Симпатии:
    3.322
    Версия XF:
    1.5.9
    Тьфу блин. Я перепутал с классом. Да, в этом случае можно и это событие использовать. Но надо посмотреть, не будет ли оно срабатывать во всплывающих окнах, что будет нежелательным. Футер там точно будет отсутствовать, а вот событие может и сработать.

    И еще похоже оно и для админки будет срабатывать, что наверняка не нужно топикстартеру.
     
  9. Agel_Nash

    Agel_Nash Пользователь

    Регистрация:
    23.01.12
    Сообщения:
    16
    Симпатии:
    7
    Версия XF:
    1.1.2
    Всем спасибо. Разобрался...
     

Поделиться этой страницей