Переопределить вывод UI контроллера

Главные вкладки

Аватар пользователя jsv jsv 3 апреля 2017 в 15:02

Есть некий модуль, в котором реализован класс, использующий стандартный EntityDefaultUIController. В нём есть публичная функция overviewForm, которая выводит специфическую форму.
Как в моем модуле оформить код так, чтобы переопределить вывод этой формы, что где нужно указать?
Было бы сделано обычными формами бы - через alter залез бы и поменял, одна функция. А тут что писать надо и где? Как-то с контроллерами не приходилось ещё работать...

Фактически просто нужно переопределить одну функцию в классе. Как это сделать? Попытка решить проблему в лоб заканчивается так
  Fatal error: Call to undefined method MyUIController::load() in X:\home\mysite\www\includes\common.inc on line 7991  

Лучший ответ

Аватар пользователя jsv jsv 3 апреля 2017 в 16:54

Хорошо, как же тут drupal-way "переопределить" метод? Я и пытаюсь наследовать.

<?php
function mymodule_entity_info_alter(&$entity_info) {
$entity_info['group']['controller class'] = 'MyUIController';

}

?>
<?php  class MyUIController extends EntityDefaultUIController {
  public function 
overviewForm($form, &$form_state) {
  
Здесь типа переопределяем
 
return $form;
  }

}

?>

Контроллер находится, но сразу выскакивает фатальная ошибка, указанная выше.
Что я делаю не так?
PS Блин, простейшая ошибка. Надо было $entity_info['group']['admin ui']['controller class'] = 'MyUIController';

Комментарии

Аватар пользователя jsv jsv 3 апреля 2017 в 16:03

А так не выходит - Друпал не может найти эти формы. Они спрятаны в классе и по _alter их не переопределить.

Аватар пользователя bumble bumble 3 апреля 2017 в 16:03

В каком смысле "Друпал не может найти эти функции"?
Покажите как альтерите.

Нет разницы как строится форма - рендеринг стандартный. И альтрация перед рендером вызывается, а не в процессе построения.

Аватар пользователя jsv jsv 3 апреля 2017 в 16:13
 function mymodule_form_alter(&$form, &$form_state, $form_id) {
        echo "--$form_id--";
        }
        return;
}  

Ничего не находит, кроме головной формы( головная форма состоит из 4 форм, типа как на admin/people, нужна только одна форма - которая список выводит) - в которой вообще ничего нет, кроме как указания, что строиться она должна из класса .
Да, тут есть уже готовый вывод. Но мне нужно сформировать одну из подформ - переписать функцию(метод) её формирования, и вот к этому методу я никак не могу получить доступ.

Ещё раз поясняю - форма, нужная мне, определена в КЛАССЕ.
Там она видимо и строится

<?php  public function overviewForm($form, &$form_state) {
    
form_load_include($form_state'inc''group''admin/group');

    if (

$form_state['rebuild']) {
      
$args array_merge(array($form, &$form_state), $form_state['rebuild_info']['args']);
      return 
call_user_func_array($form_state['rebuild_info']['callback'], $args);
    }
    
$form['#submit'] = array('group_filters_form_submit');
    
$form['filters'] = group_filters_form();
    
$form['options'] = group_options_form();
    
$form['groups'] = group_groups_form($this->overviewPagerLimit); // Вот ЭТУ строчку надо поменять - чтобы тут вывод сделать другим....
    
$form['pager'] = array('#markup' => theme('pager'));

    return 

$form;
  }
?>
Аватар пользователя bumble bumble 3 апреля 2017 в 16:15

Ок. И я еще раз поясню - нет разницы где и как строится форма. Рендеринг происходит отдельно.

Вам нужно определить ID формы, и далее в модуле произвести альтер:
Step 1:

<?php
function MY_MODULE_form_alter(&$form, &$form_state$form_id) {
  
var_dump($form_id);
  
// Или, если стоит devel, можно так:
  // dpm($form_id);
}
?>
  • сбрасываете кеш и заходите на страницу с формой
  • копируете/записываете ID
  • вместо прошлой ф-ции записываете следующую:

Step 2:

<?php
function MY_MODULE_form_FORM_ID_alter(&$form, &$form_state) {
  
// Производите необходимые манипуляции
}
?>

Step 3:

  • сбрасываете кеш и заходите на страницу с формой
  • находите "кусок основной формы", который Вам нужен и с ним работаете.
  • MY_MODULE - имя Вашего модуля
  • FORM_ID - ID формы, полученный в 1м шаге

Полезные ссылки:

Аватар пользователя jsv jsv 3 апреля 2017 в 16:24

Короче данный частный случай решили, ок.
А как в принципе метод класса в Друпале переопределять? Есть класс, в нем метод. Как, не патча модуль, в нем поменять поведение метода?

Аватар пользователя bumble bumble 3 апреля 2017 в 16:29

Методы не переопределяют.
Можно отнаследоваться от родительского (необходимого) класса и переопределить в нем метод.
С новым (своим, дочерним) классом производить нужные действия.

В 7м друпале - большую часть (все что сделано "друпал-вейно") можно альтерить и изменять на разных этапах.

Аватар пользователя jsv jsv 3 апреля 2017 в 16:54

Хорошо, как же тут drupal-way "переопределить" метод? Я и пытаюсь наследовать.

<?php
function mymodule_entity_info_alter(&$entity_info) {
$entity_info['group']['controller class'] = 'MyUIController';

}

?>
<?php  class MyUIController extends EntityDefaultUIController {
  public function 
overviewForm($form, &$form_state) {
  
Здесь типа переопределяем
 
return $form;
  }

}

?>

Контроллер находится, но сразу выскакивает фатальная ошибка, указанная выше.
Что я делаю не так?
PS Блин, простейшая ошибка. Надо было $entity_info['group']['admin ui']['controller class'] = 'MyUIController';

Аватар пользователя bumble bumble 3 апреля 2017 в 17:01

Ошибка говорит об отсутствии метода load().
Что не так - не готов сказать. Нужно видеть и понимать картину целиком.

Аватар пользователя bumble bumble 3 апреля 2017 в 16:17

ЗЫ - используйте Devel для удобного просмотра массивов, после установки:

<?php
function MY_MODULE_form_FORM_ID_alter(&$form, &$form_state) {
  
dpm($form);
}
?>

покажет Вам все, из чего состоит форма.