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

1.1.x Как извлечь user_id из поста и передать в свой хук аддона?

Тема в разделе "Вопросы и ответы по XenForo Framework", создана пользователем Rasalom, 23 апр 2013.

Загрузка
  1. Rasalom

    Rasalom Активный пользователь

    Регистрация:
    06.12.12
    Сообщения:
    19
    Симпатии:
    0
    Суть задумки (можно не читать :) )

    У меня был такой аддон на PHPBB3, он из моей соседней базы сообщества вытаскивал особые звания и должности и делал префикс к username и постфикс с должностью. Выходило что-то типа


    вместо просто Greymonkey

    Перезжаем на Xenforo. Переписываю аддон.

    Цель аддона: везде где нужно обработать таким образом имя пользователя. В профиле, в постах и еще парочке мест.
    Основа готова, с созданием хуков разобрался и уже могу подставлять данные куда надо.

    Проблема: Могу из хука передать переменные в свой шаблон, который подставляю к имени. Но не могу получить из основного шаблона user_id, по которому я бы вытаскивал у себя из базы звание и должность.

    Нужно взять штатный хук message_user_info_text и передать user_id поста в мой хук raRanks.
    Я второй день перелопачиваю туториалы и документацию, но все что получилось, это найти $visitor и передать его в свой хук.

    Как извлечь из message_user_info_text переменную автора поста user_id и прислать в хук?



    Вот шаблон, который я подставляю перед именем.

    HTML:
    <xen:require css="raRank.css" />
     
    <div>TEST:{$user_id} - {$userRank}</div>
    $userRank я могу принять, но чтобы его вычислить нужен user_id автора поста.

    Вот мой хук

    PHP:
    <?php
     
    class raRanks_Listener
    {
            public static function 
    templateHook($hookName, &$contents, array $hookParamsXenForo_Template_Abstract $template)
        {
                switch (
    $hookName)
                {
                    case 
    'message_user_info_text';
                    {
                        
    $delim ='<h3 class="userText">';
                        
    $pos strpos($contents$delim);
                        
    $contents_parts explode($delim$contents);
                        if (
    $pos !== false)
                        {
                           
                            
    // ---- RA BASE CONNECTOR
                            
    $query mysql_query("SELECT * FROM phpbb_ra_levels WHERE xf_forum_id=`$xenforo_user_id`") or die(mysql_error()); //соседняя база со званиями и $xenforo_user_id я получить не могу, подставление id вручную работает кооректно
                            
    $received mysql_fetch_array($query);
                            
    // ----- RA BASE CONNECTOR
                            
    $params $template->getParams();
                            
    $params += array('userRank' => $received['rank']);
                            
    $theRank $template->create('raRank'$params);
                            
    $contents $contents_parts[0] . $delim$theRankю $contents_parts[1];
                        }
                    break;
                    }
                   
                }
        }
    }
    Ткните носом чайника, где найти данные об авторе поста и как их в хуке получить.
    Заранее огромное спасибо.

    P.s. Прошу прощения если тема уже была, но я не смог найти ее.
     
  2. nmn

    nmn Активный пользователь

    Регистрация:
    11.04.13
    Сообщения:
    163
    Симпатии:
    71
    Версия XF:
    1.1.3
    Где именно вы создали хук raRanks? Вы что-то путано пишете, мозголомно.
    --- добавлено : 23 апр 2013 в 13:13 ---
    А, понял, вам, наверное, вот так нужно получать: $user_id = $hookParams['user']['user_id'];
    И то, что вы создали - это не хук, а шаблон.
     
    Rasalom нравится это.
  3. Rasalom

    Rasalom Активный пользователь

    Регистрация:
    06.12.12
    Сообщения:
    19
    Симпатии:
    0
    Значит, сам инжект происходит здесь (ничего не правил здесь)

    [​IMG]
    Файл хука лежит где надо, в своей папке

    [​IMG]

    Сам аддон с template_hook создан здесь и вот так

    [​IMG]

    И вот мой тестовый шаблон, без особых изысков. Только проверка.

    [​IMG]
    Я сейчас попробую это вслепую :)
    --- добавлено : 23 апр 2013 в 13:35 ---
    Спасибо огромное!
    Почему это сработало не пойму, но это мои проблемы. Теперь буду разбираться.

    Еще раз спасибо.
     
  4. Pepelac

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

    Регистрация:
    28.09.10
    Сообщения:
    1.794
    Симпатии:
    1.349
    То, что вы называете "файл хука" — это обработчик события. Само событие — template_hook.

    В хук message_user_info_text передается два параметра: user и isQuickReply.

    Screen Shot 2013-04-23 at 11.30.09 .png

    Эти параметры становятся доступны в обработчике события в переменной $hookParams. Соответственно, как вам сказали выше, ID пользователя, написавшего сообщения, доступно через $hookParams['user']['user_id'].
     
    Rasalom нравится это.
  5. Rasalom

    Rasalom Активный пользователь

    Регистрация:
    06.12.12
    Сообщения:
    19
    Симпатии:
    0
    Я это понимал, но все таки, из-за малоопытности в программировании, связи не видел и как доступ к этому всему получить не понимал. Спасибо большое за объяснения.
     
  6. Pepelac

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

    Регистрация:
    28.09.10
    Сообщения:
    1.794
    Симпатии:
    1.349
    И да. Вместо этого

    PHP:
    $query mysql_query("SELECT * FROM phpbb_ra_levels WHERE xf_forum_id=`$xenforo_user_id`") or die(mysql_error()); //соседняя база со званиями и $xenforo_user_id я получить не могу, подставление id вручную работает кооректно
    $received mysql_fetch_array($query);
    рекомендую делать так

    PHP:
    $received XenForo_Application::getDb()->fetchRow('SELECT * FROM phpbb_ra_levels WHERE xf_forum_id = ?'$hookParams['user']['user_id']);
     
    Rasalom нравится это.
  7. nmn

    nmn Активный пользователь

    Регистрация:
    11.04.13
    Сообщения:
    163
    Симпатии:
    71
    Версия XF:
    1.1.3
    Ещё надо как-то убрать sql-запросы из обработчика хука, обросший таким творчеством форум будет заметно тормозить. Сейчас одну штуку придумал для этого, отпишусь, как попробую.
     
    Rasalom нравится это.
  8. Pepelac

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

    Регистрация:
    28.09.10
    Сообщения:
    1.794
    Симпатии:
    1.349
    Убрать sql запросы можно, к примеру, повесив обработчик события load_class_model и расширив модель XenForo_Model_User так, чтобы в запрос на получение данных о юзере добавилась связь с таблицей phpbb_ra_levels
     
    Rasalom нравится это.
  9. nmn

    nmn Активный пользователь

    Регистрация:
    11.04.13
    Сообщения:
    163
    Симпатии:
    71
    Версия XF:
    1.1.3
    Тоже вариант. Но я сейчас изучаю возможность отложенной загрузки, как с фразами.
     
  10. Rasalom

    Rasalom Активный пользователь

    Регистрация:
    06.12.12
    Сообщения:
    19
    Симпатии:
    0
    Спасибо. Просто у меня две разных базы и к phpbb_ra_levels Xenforo доступа не имеет. Но я наверное просто перенесу ее туда.

    А может как-то можно где-то найти где формируется этот самый $user и туда уже включить мои звания, а в обработчике просто доставать его уже без лишних телодвижений.
     
  11. Yoskaldyr

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

    Регистрация:
    27.09.10
    Сообщения:
    1.921
    Симпатии:
    1.160
    Версия XF:
    1.0.4
    Все данные должны быть уже подготовлены до передачи во вьюху. Если пытаться извлекать данные в момент рендера, то это довольно таки нарушает классическую веб-MVC архитектуру ксена, т.е. вьюха ничего не должна знать о том откуда данные, она должна только их отобразить и все и уж тем более она не должна пытаться что-то дергать из базы.
    Именно так и надо делать.
    Но все будет зависеть от того где именно должно отображаться, т.е. массив пользователя в разных частях генерится разными запросами к базе, поэтому если надо чтобы отображалось везде где только можно придется расширять базовые классы в нескольких местах (минимум модели пользователей, тем и сообщений)
     
    Rasalom нравится это.
  12. Rasalom

    Rasalom Активный пользователь

    Регистрация:
    06.12.12
    Сообщения:
    19
    Симпатии:
    0
    Перенес таблицы в родную базу Xenforo и заменил ваши запросы и исчезла ошибка базы данных при развороте скрытого модератором поста. А я уже думал стреляться :)
     
  13. Pepelac

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

    Регистрация:
    28.09.10
    Сообщения:
    1.794
    Симпатии:
    1.349
    Можете просто сделать доступ к базе phpbb пользователю, имеющиму доступ к базе xenforo. В запросе тогда нужно будет к имени таблицы добавить имя базы.

    Смотрите сообщение номер 8. Там идея, от которой вы можете оттолкнуться. Хотя, там я поспешил с моделью — если речь идет только о ранке в сообщениях темы, то разумнее начинать копать с метода XenForo_Model_Post::getPostsInThread
     
    Rasalom нравится это.
  14. Rasalom

    Rasalom Активный пользователь

    Регистрация:
    06.12.12
    Сообщения:
    19
    Симпатии:
    0
    Везде где только можно не нужно. Главное чтобы было в профиле, в списке пользователей\онлайн\администраторов и в непосредственно в постах (что уже сейчас работает отлично).

    А вы не могли бы сказать где лежат эти самые модели? Попробую раскурить.
     
  15. nmn

    nmn Активный пользователь

    Регистрация:
    11.04.13
    Сообщения:
    163
    Симпатии:
    71
    Версия XF:
    1.1.3
    Никакого нарушения MVC нет. Вьюхе для такого поведения не требуется никаких новых предположений о данных, для неё они непрозрачны. В Ксене так уже делается для фраз.
     
    Rasalom нравится это.
  16. Pepelac

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

    Регистрация:
    28.09.10
    Сообщения:
    1.794
    Симпатии:
    1.349
    Если везде, то нужно подумать глубже и отследить все места, где это нужно. В принципе — это просто время :)

    Модели лежат в папке library/XenForo/Model
     
    Rasalom нравится это.
  17. Rasalom

    Rasalom Активный пользователь

    Регистрация:
    06.12.12
    Сообщения:
    19
    Симпатии:
    0
    Большое всем спасибо. Очень выручили. Буду дальше разбираться.
     
  18. Yoskaldyr

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

    Регистрация:
    27.09.10
    Сообщения:
    1.921
    Симпатии:
    1.160
    Версия XF:
    1.0.4
    Для отображения дополнительных данных в момент просмотра темы скорее всего придется расширять метод
    XenForo_Model_Post::preparePostJoinOptions
    и добавить дополнительный join при условиях когда дергается профиль (XenForo_Model_Post::FETCH_USER_PROFILE)
    т.е. добавить свои поля и таблицы по аналогии с кодом:
    PHP:
                if ($fetchOptions['join'] & self::FETCH_USER_PROFILE)
                {
                    
    $selectFields .= ',
                        user_profile.*'
    ;
                    
    $joinTables .= '
                        LEFT JOIN xf_user_profile AS user_profile ON
                            (user_profile.user_id = post.user_id)'
    ;
                }
     
    Rasalom нравится это.
  19. Rasalom

    Rasalom Активный пользователь

    Регистрация:
    06.12.12
    Сообщения:
    19
    Симпатии:
    0
    Я только что осознал, что мою идею со званиями можно, кажется, провернуть просто через штатную функцию дополнительных полей и потом только шаблоны подправить. Ведь по сути, мне нужно указать 20 званий и иметь возможность каждому их выдавать персонально в админке. Сейчас попробую.
     
  20. infis

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

    Регистрация:
    27.06.11
    Сообщения:
    5.525
    Симпатии:
    3.322
    Версия XF:
    1.5.9
    В этом случае будут сложности с выводом в постбит. У дополнительных полей определены места размещения и их вывести в других местах будет не просто, хотя и возможно.
    С другой стороны можно поменять немного концепт и сделать все штатными средствами :)
     

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