#forms #symfony #doctrine
#формы #симфония #доктрина
Вопрос:
Добрый день, я ввел сущность ScheduledCommand в отношение OneToMany к ScheduledCommandLimitRange
/**
* @ORMMappedSuperclass (repositoryClass="SynoliaSyliusSchedulerCommandPluginRepositoryScheduledCommandRepository")
* @ORMTable("scheduled_command")
*/
class ScheduledCommand implements ScheduledCommandInterface
{
/**
* @var int|null
* @ORMId()
* @ORMGeneratedValue()
* @ORMColumn(type="integer")
*/
private $id;
/**
* @var string
* @ORMColumn(type="string")
*/
private $name = '';
/**
* @var string
* @ORMColumn(type="string")
*/
private $command = '';
/**
* @var int
* @ORMColumn(type="integer")
*/
private $priority = 0;
/**
* @ORMOneToMany(targetEntity="ScheduledCommandLimitRange", mappedBy="scheduledCommand", orphanRemoval=true, cascade={"persist"})
* @ORMJoinColumn(nullable=false)
*/
private $commandLimitRanges;
public function getId(): ?int
{
return $this->id;
}
public function getName(): string
{
return $this->name;
}
public function setName(string $name): ScheduledCommandInterface
{
$this->name = $name;
return $this;
}
public function getCommand(): string
{
return $this->command;
}
public function setCommand(string $command): ScheduledCommandInterface
{
$this->command = $command;
return $this;
}
public function getPriority(): int
{
return $this->priority;
}
public function setPriority(int $priority): ScheduledCommandInterface
{
$this->priority = $priority;
return $this;
}
public function getCommandLimitRanges(): ?Collection
{
return $this->commandLimitRanges;
}
public function setCommandLimitRanges(Collection $commandLimitRange): ?Collection
{
$this->commandLimitRanges = $commandLimitRange;
return $this->commandLimitRanges;
}
}
Это мой единственный урок:
/**
* @ORMEntity(repositoryClass="SynoliaSyliusSchedulerCommandPluginRepositoryScheduledCommandLimitRangeRepository")
* @ORMTable(name="scheduled_command_limit_range")
*/
class ScheduledCommandLimitRange implements ScheduledCommandLimitRangeInterface
{
/**
* @ORMId()
* @ORMGeneratedValue()
* @ORMColumn(type="integer")
*/
private $id;
/**
* @var DateTime|null
* @ORMColumn(type="datetime", nullable=true)
*/
private $timeFrom;
/**
* @var DateTime|null
* @ORMColumn(type="datetime", nullable=true)
*/
private $timeTo;
/**
* @ORMManyToOne(targetEntity="ScheduledCommand", inversedBy="commandLimitRanges")
*/
private $scheduledCommand;
public function getId(): ?int
{
return $this->id;
}
public function getTimeFrom(): ?DateTime
{
return $this->timeFrom;
}
public function setTimeFrom(?DateTime $timeFrom): ScheduledCommandLimitRangeInterface
{
$this->timeFrom = $timeFrom;
return $this;
}
public function getTimeTo(): ?DateTime
{
return $this->timeTo;
}
public function setTimeTo(?DateTime $timeTo): ScheduledCommandLimitRangeInterface
{
$this->timeTo = $timeTo;
return $this;
}
public function getScheduledCommand(): ?ScheduledCommand
{
return $this->scheduledCommand;
}
public function setScheduledCommand(ScheduledCommand $scheduledCommand): ?ScheduledCommand
{
$this->scheduledCommand = $scheduledCommand;
return $this;
}
Я получил ScheduledCommandType, который имеет CollectionType в одном поле, которое имеет entry_type CommandLimitType .
final class ScheduledCommandType extends AbstractType
{
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('name')
->add('command', CommandChoiceType::class)
->add('arguments')
->add('cronExpression')
->add('commandLimitRanges', CollectionType::class, [
'label' => 'sylius.ui.scheduled_command_limit',
'entry_type' => CommandLimitType::class,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
'inherit_data' => true,
'entry_options' => array(
'scheduledCommand' => 'id'),
])
->add('logFile')
->add('priority')
->add('executeImmediately')
->add('enabled')
;
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => ScheduledCommand::class,
]);
}
}
Это мой тип входа:
class CommandLimitType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('timeTo', DateTimeType::class, [
'widget' => 'single_text',
])
->add('timeFrom', DateTimeType::class, [
'widget' => 'single_text'
])
->add('scheduledCommand', HiddenType::class)
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setRequired(['scheduledCommand']);
$resolver->setDefaults([
'data_class' => ScheduledCommandLimitRange::class,
]);
}
}
У меня была проблема, что когда я хочу отправить это значение формы CommandLimitRange ParentID было null, поэтому я попытался передать родительский идентификатор дочерней формы в качестве скрытого поля. Но все равно после отправки все еще есть ошибка:
Cannot read index "0" from object of type "SynoliaSyliusSchedulerCommandPluginEntityScheduledCommand" because it doesn't implement ArrayAccess.
Как правильно передать идентификатор родительской сущности в запись, чтобы после отправки правильный родительский идентификатор был связан со строкой в БД?
Большое вам спасибо
Ответ №1:
Я нашел свое решение. Хорошо, итак, вот несколько проблем, которые я раньше не понимал. Прежде всего — у меня был только базовый сеттер, а не метод добавления / удаления.
public function addCommandLimitRange(ScheduledCommandLimitRange $commandLimitRange): self
{
if (!$this->commandLimitRanges->contains($commandLimitRange)) {
$this->commandLimitRanges[] = $commandLimitRange;
$commandLimitRange->setScheduledCommand($this);
}
return $this;
}
public function removeCommandLimitRange(ScheduledCommandLimitRange $commandLimitRange): self
{
if ($this->commandLimitRanges->removeElement($commandLimitRange)) {
// set the owning side to null (unless already changed)
if ($commandLimitRange->getScheduledCommand() === $this) {
$commandLimitRange->setScheduledCommand(null);
}
}
return $this;
}
Затем мне нужно было сделать мое свойство объектом ArrayCollection в конструкторе:
public function __construct()
{
$this->commandLimitRanges = new ArrayCollection();
}
И последнее, чтобы получить правильное удаление, вместо запуска update с null для ParentID мне нужно было добавить параметр orphan_removal в аннотацию.
/**
* @ORMOneToMany(targetEntity="ScheduledCommandLimitRange", mappedBy="scheduledCommand", cascade={"persist"}, orphanRemoval=true)
*/
private $commandLimitRanges;