Модификация макета формы доктрины Admin Generator

#symfony1 #symfony-1.4

#symfony1 #symfony-1.4

Вопрос:

Мне нужно изменить форму доктрины Admin Generator, которая включена:

 $this->embedRelation('MyRelation');
 

Макет по умолчанию выглядит следующим образом:

Скриншот 1

Цель — каждый элемент выбора должен отображаться в виде текста в отдельной строке, плюс цена и количество:

Скриншот 2

schema.yml

 Game:
    actAs:
      Timestampable: ~
    columns:
      id: { type: integer(4), primary: true, autoincrement: true, unsigned: true }
      game_name: { type: string(100), notnull: true }
    indexes:
      it:
  fields: game_name
  type: unique

  Campaign:
    actAs:
      Timestampable: ~
    columns:
      id: { type: integer(4), primary: true, autoincrement: true, unsigned: true }
      name: { type: string(100), notnull: true }
      is_active: { type: boolean, notnull: true, default: 0 }
      start: { type: datetime, notnull: true }
      end: { type: datetime, notnull: true }
    relations:
      CampaignMatrix: { onDelete: CASCADE, local: id, foreign: campaign_id, foreignAlias: CampaignMatrixCampaign }

  CampaignGames:
    actAs:
      Timestampable: ~
    columns:
      id: { type: integer(4), primary: true, autoincrement: true, unsigned: true }
      campaign_id: { type: integer(4), notnull: true, unsigned: true }
      game_id: { type: integer(4), notnull: true, unsigned: true }
    indexes:
      tc:
  fields: [campaign_id, game_id]
  type: unique
    relations:
      Campaign: { onDelete: CASCADE, local: campaign_id, foreign: id, foreignAlias: CampaignCampaignGames }
      Game: { onDelete: CASCADE, local: game_id, foreign: id, foreignAlias: GameCampaignGames }

  CampaignMatrix:
    actAs:
      Timestampable: ~
    columns:
      id: { type: integer(4), primary: true, autoincrement: true, unsigned: true }
      item_id: { type: integer(4), notnull: true, unsigned: true }
      campaign_id: { type: integer(4), notnull: true, unsigned: true }
      price_id: { type: integer(4), notnull: true, unsigned: true }
      quantity: { type: integer(4), notnull: true, unsigned: true }
    relations:
      Item: { onDelete: CASCADE, local: item_id, foreign: id, foreignAlias: ItemCampaignMatrix }
      Campaign: { onDelete: CASCADE, local: campaign_id, foreign: id, foreignAlias: CampaignCampaignMatrix }
      Price: { onDelete: CASCADE, local: price_id, foreign: id, foreignAlias: PriceItems }

  Price:
    columns:
      id: { type: integer(4), unsigned: true }
      currency_code: { type: string(3), notnull: true }
      price: { type: float, notnull: true }
    indexes:
      tc:
  fields: [id, currency_code]
  type: unique

  Item:
    actAs:
      Timestampable: ~
      I18n:
  fields: [name, description, image]
    columns:
      id: { type: integer(4), primary: true, autoincrement: true, unsigned: true }
      game_id: { type: integer(4), notnull: true, unsigned: true }
      product_id: { type: string(100), notnull: true }
      price_id: { type: integer(4), notnull: true, unsigned: true }
      quantity: { type: integer(4), notnull: true, unsigned: true }
      name: { type: string(100), notnull: true }
      description: { type: string(255), notnull: true }
      image: { type: string(255), notnull: true }
    indexes:
      it:
  fields: item_type
    relations:
      Game: { onDelete: CASCADE, local: game_id, foreign: id, foreignAlias: GameItems }
      Price: { onDelete: CASCADE, local: price_id, foreign: id, foreignAlias: PriceItems }
 

Вот как я это делаю:

 $list = MainItemTable::getInstance()->findByGameId($gameId);

$CampaignMatrix = new CampaignMatrix();

foreach($list as $index => $item) {

    $itemAssocForm = new CampaignMatrixForm($CampaignMatrix);
    $itemAssocForm->item_id = $item->getId(); // Need it in the form as hidden field
    $this->embedForm($item->getProductId(), $itemAssocForm);
}
 

И вот как я пытаюсь получить значение:

 $this->widgetSchema['item_id'] = new sfWidgetFormInputText(array(), array('value' => $this->item_id)); // It doesn't get the Id
 

Но у меня ошибка:
Фатальная ошибка: превышено максимальное время выполнения на 30 секунд в /vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Relation/Parser.php в строке 237

  1. Если я сброшу значение price_id в CampaignMatrixForm, ошибка не возникнет. Как избежать выполнения выбора одних и тех же данных для каждой строки элемента в цикле?
  2. Идентификатор элемента отсутствует, но он мне нужен как скрытое поле. Как передать идентификатор CampaignMatrix текущей строки в CampaignMatrixForm?

Комментарии:

1. можете ли вы опубликовать соответствующие таблицы из своей схемы?

Ответ №1:

Вы должны выполнить итерацию по ассоциации, чтобы добавить форму ассоциации в основную форму. Это может быть просто, если вы опубликуете часть своего schema.yml.

Попробуйте повторно использовать этот фрагмент :

 $list = MyRelatedObjectTable::getInstance()->findAll();

foreach($list as $item)
{
  $itemAssoc = AssociationTable::getInstance()->findByObjectId($this->object->id, $item->id);

  if(!$itemAssoc)
  {
    $itemAssoc = new Association();
    $itemAssoc->value_id = $itemAssoc->id;
    $itemAssoc->user_id = $this->object->id;
  }

  $itemAssocForm = new AssociationForm($itemAssoc);
  $this->embedForm('itemAssoc'.$item->code, $itemAssocForm);
}
 

Комментарии:

1. Итак, как вы получаете доступ к preference_id и user_id в форме?

2. Возможно, ваша модель слишком сложна … попробуйте реорганизовать CampaignMatrix в CampaignGames. Чтобы достичь своей цели, вы должны глубоко вложить себя в создание и обработку пользовательских форм. Создайте пользовательский класс формы, загрузите пользовательские виджеты и widgetSchema. Для обработки создайте свой собственный метод dobind и save для обновления вашего объекта doctrine. EmbedForm имеет плохой дизайн и, возможно, просто не соответствует вашим целям.

3. Я не смог обновить данные в своей форме, а только вставить… Вставленные элементы не могут быть предварительно выбраны во встроенной форме. Швы такие, какие мне нужны, чтобы сделать его полностью индивидуальным. Я думаю, что AJAX поможет.

Ответ №2:

Лучший способ — создать для этого часть. Имейте в виду, что вам нужно unset установить поле выбора для элемента в классе Form, иначе вы потеряете свою ассоциацию. Я могу подробнее остановиться на этом, если вам понадобится дополнительная помощь.

Комментарии:

1. Почему связь будет потеряна, если я не отменю выбор элемента?

2. если действие отправки не получает никакой информации в этом поле (виджет не отображается), это похоже на отправку пустого поля. Это очищает значение. Но лучшим вариантом было бы преобразование поля в a sfWidgetFormInputHidden , которое сохраняет связь и предотвращает потерю значения.

Ответ №3:

вы можете получить код из кэша и перейти к своему бэкэнду / модулям / nameAPP и следующему шаблону редактирования

Комментарии:

1. эта форма доктрины. Я думаю, что должен быть лучший способ.