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

Как "переопределить" только часть стандартного метода класса XenForo?

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

Загрузка
  1. Exile

    Exile Местный

    Регистрация:
    27.06.11
    Сообщения:
    997
    Симпатии:
    545
    Версия XF:
    1.4.4
    Всем привет.

    Потихоньку разбираюсь тут с XenForo, потребовалось внести правку в стандартную функцию движка. Не понимаю, как через расширение классов это сделать (я же не расширяю, я наоборот сокращаю), поэтому просто опишу свою последовательность действий, может кто-то из знающих людей подскажет что у меня не так.

    Хочу в файле library/XenForo/ControllerPublic/Member.php "удалить" фрагмент кода
    PHP:
                    if (!$user['location'])
                    {
                        unset(
    $dwInput['location']);
                    }
    Так как правка стандартных файлов движка - не правильно, делаю дополнение.

    1) В разделе Code Event Listeners создаю новое действие load_class, которое вызывает следующий callback: Exile_DelPermission_Listener::load_controller
    2) В вызываемом Listener.php следующее:
    PHP:
    <?php

    class Exile_DelPermission_Listener
    {
        public static function 
    load_controller($class, array &$extend)
        {
            if (
    $class == 'XenForo_ControllerPublic_Member')
            {
                
    $extend[] = 'Exile_DelPermission_Extend_ControllerPublic_Member';
            }
        }
    }
    3) В файле library/Exile/DelPermission/Extend/ControllerPublic/Member.php следующее:
    PHP:
    <?php

    class Exile_DelPermission_Extend_ControllerPublic_Member extends XFCP_Exile_DelPermission_Extend_ControllerPublic_Member
    {
       public function 
    actionEdit()
       {
         
    /// код аналогичной функции из library/XenForo/ControllerPublic/Member.php с удаленным участком кода
       
    }
    }
    И все бы хорошо, да вот портянка-дубликат кода из library/XenForo/ControllerPublic/Member.php получается. А если разработчики в следующей версии внесут в эту функцию - придется править и мне. То есть особой разницы между правкой файлов движка особо и нет.

    Я понимаю, что что-то делаю не так. Вопрос - что? Как сделать иначе и удалить именно указанный фрагмент кода, не дублируя функцию целиком? Заранее большое спасибо.
     
  2. infis

    infis Местный

    Регистрация:
    27.06.11
    Сообщения:
    5 966
    Симпатии:
    3 548
    Версия XF:
    1.5.9
    Навскидку. Вы можете вызвать оригинальный код, а в своем коде заново установить нужную переменную и сохранить ее.
     
    Egorpom и Exile нравится это.
  3. FractalizeR

    FractalizeR XenForo Addicted

    Регистрация:
    27.09.10
    Сообщения:
    1 085
    Симпатии:
    832
    Версия XF:
    1.3.2
    В общем случае эта проблема никак не решается. Самая мелкая единица, которой мы можем манипулировать при расширении функционала XenForo, это метод. До строк никак не опуститься.

    Ну, разве что в качестве экзотически-извращенных вариантов можно предложить динамически получить текст оригинального метода, как это делает, например, SuperClosure, пропатчить его налету и выполнить внутри своего метода уже в измененном варианте. Это ужасно! Не делайте так :)
     
    Exile нравится это.
  4. Yoskaldyr

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

    Регистрация:
    27.09.10
    Сообщения:
    1 921
    Симпатии:
    1 163
    Версия XF:
    1.0.4
    Это стандартная ситуация и вот почему разрабы хотят изменять логику работы в 2.х версиях для более удобного написания дополнений и вот почему я писал свое дополнение CMF_Core.
    В данной ситуации возможны только костыльные решения и какое именно выбирать зависит только от предпочтений разработчика и конкретной задачи.
    Список возможных костылей:
    • Повторный вызов датарайтера обновлением нужного поля после работы парента (дополнительный запрос апдейта + не всегда подходит если какое-то зависимое от других полей поле со своей логикой при сохранении)
    • Перед вызовом парента сохранять значение инпута в реестр (XenForo_Application::set) или в какую статик переменную с дальнейшим расширением датарайтера и установкой сохраненного значения инпута в _preSave методе
    • Можно использовать мой аддон CMF_Core (автоматизация предыдущего метода). Иногда достаточно только описания входных полей инпута и сохраняемых полей датарайтера и даже не надо расширять контроллер и датарайтер, но все это магия и неявное поведение, как следствие не рекомендуется использовать тем кто не понимает как работает мое ядро.
    --- добавлено : Apr 19, 2015 8:47 AM ---
    Добавлю еще. Если работаете в методе после вызова парента то всегда проверяйте что именно он вернул, например в случае контроллера, какой тип респонса и какие параметры если это ResponceView
     
    Последнее редактирование модератором: 27.04.2015
    Kolya groza morey и Exile нравится это.
  5. Exile

    Exile Местный

    Регистрация:
    27.06.11
    Сообщения:
    997
    Симпатии:
    545
    Версия XF:
    1.4.4

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