В настоящее время я застрял в проблеме, и я не могу найти свет в конце туннеля.
У меня есть своего рода простая функция контроллера:
public function settingsAction(Request $request)
{
$org = $this->getUser()->getOrganisation();
$form = $this->createForm(new OrgSettingsType(), $org);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid())
{
$dm = $this->get('doctrine_mongodb')->getManager();
$dm->persist($this->getUser()->getOrganisation());
$dm->flush();
$this->get('session')->getFlashBag()->add('success', 'msg.changes_saved');
return $this->redirect($this->generateUrl('metacloud_account_organisation_settings'));
}
if ($form->isSubmitted())
{
$this->get('session')->getFlashBag()->add('danger', 'msg.update_failed_see_errors');
}
return $this->render('MetaCloudAccountBundle:Organisation:settings.html.twig', array('form' => $form->createView() ));
}
Форма на самом деле не более сложная, но это двухуровневая форма:
class OrgSettingsType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('groups', 'collection', array(
'type' => 'text',
'allow_add' => true,
'options' => array(
'label' => false
)
));
$builder->add('cloudAccounts', 'cloud_account', array(
));
$builder->add('settings', new OrganisationConfigType());
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'MetaCloud\DataBundle\Document\Organisation',
'cascade_validation' => true,
'validation_groups' => array('account_edit', 'Default')
));
}
public function getName()
{
return 'org_config';
}
}
OrganisationConfigType форма достаточно проста и связана с документом OrganisationConfig где ограничения объявляются в форме аннотаций.
Проблема в том, что когда я отправляю форму, даже если данные неверны и форма говорит об этом, она все равно сохраняет изменения в базе данных. Насколько я понимаю, форма не сохраняла никаких данных сама по себе, а просто сравнивала данные с заданными мной аннотациями ограничений. Я не хочу задавать вопрос, поэтому я не показываю весь свой код, но если вам нужна дополнительная информация, пожалуйста, спросите, и я отредактирую!
Большое спасибо.
РЕДАКТИРОВАТЬ: кто-то спросил мой код сущности: я публикую его здесь, без посторонних получателей и установщиков.
/**
* @MongoDB\Document(collection="societe", repositoryClass="MetaCloud\DataBundle\Repository\OrganisationRepository")
* @MongoDB\HasLifecycleCallbacks
* @Unique("email")
*/
class Organisation
{
/**
* @MongoDB\Id(strategy="AUTO", name="_id")
*/
protected $id;
/**
* @MongoDB\String(name="nom")
*
* @Assert\NotNull(message="error name")
*/
protected $name;
/**
* @MongoDB\String(name="siret", nullable=true)
*
*
*/
protected $number;
/**
* @MongoDB\String(name="nomRep")
*
* @Assert\NotNull(
* message = "contact last name cant be null"* )
*/
protected $contactLastName;
/**
* @MongoDB\String(name="prenomRep")
*
* @Assert\NotNull(message="error contact first name")
*/
protected $contactFirstName;
/**
* @MongoDB\String(name="titreRep", nullable=true)
*/
protected $contactTitle;
/**
* @MongoDB\String(name="civilite")
*
* @Assert\NotNull(message="civilite is null")
*/
protected $contactHonorific;
/**
* @MongoDB\String(name="email")
*
* @Assert\NotNull()
* @Assert\Email()
*/
protected $email;
/**
* @MongoDB\String(name="emailadmin", nullable = true)
*
* @Assert\Email()
*/
protected $emailAdmin = "";
/**
* @MongoDB\String(name="telephone")
*
* @Assert\NotNull
*/
protected $phone;
/**
* @MongoDB\Int(name="maxutilisateurs")
*
* @Assert\NotNull(groups={"account_edit"})
* @Assert\Range(min=1, groups={"account_edit"})
* @Assert\NotNull()
*/
protected $maxUsers;
/**
* @MongoDB\Int(name="restutilisateurs", nullable=true)
*/
protected $remainingUsers;
/**
* @MongoDB\EmbedOne(targetDocument="Contract", name="contract", nullable=true)
*/
protected $contract;
/**
* @MongoDB\String(name="datecreated")
*/
protected $createdAt;
/**
* @MongoDB\Date(name="datedeleted", nullable=true)
*/
protected $deletedAt;/**
* @MongoDB\EmbedOne(targetDocument="Address", name="adresse")
*
* @Assert\NotNull()
* @Assert\Valid()
*/
protected $address;
/**
* @MongoDB\Collection(name="groupes", nullable=true)
*
*/
protected $groups = array();
/**
* @MongoDB\EmbedOne(targetDocument="Administrator", name="administrateur")
*/
protected $administrator;
/**
* @MongoDB\ReferenceOne(targetDocument="User", name="mappedadmin")
*
* @Gedmo\ReferenceIntegrity("nullify")
*/
protected $mappedAdmin;
/**
* @MongoDB\EmbedOne(targetDocument="OrganisationConfig", name="configpublique", nullable=true)
*/
protected $settings;
/**
* @MongoDB\Collection(name="cloudstockages", nullable=true)
*
* @Assert\Count(min=1, groups={"account_edit"})
*/
protected $cloudAccounts = array();
/**
* @MongoDB\ReferenceMany(targetDocument="User", mappedBy="organisation", nullable=true)
*
* @Gedmo\ReferenceIntegrity("nullify")
*/
protected $users;/**
* @MongoDB\ReferenceMany(targetDocument="SecurityCode", mappedBy="organisation", nullable=true)
*
* @Gedmo\ReferenceIntegrity("nullify")
*/
protected $invites;
/**
* @MongoDB\ReferenceMany(targetDocument="Organisation", mappedBy="integrator", name="organisations", nullable=true)
*/
protected $organisations;
/**
* @MongoDB\ReferenceOne(targetDocument="Organisation", inversedBy="organisations", name="integrator", simple="true")
*/
protected $integrator;/**
* @MongoDB\Field(type="boolean", name="anintegrator")
*
*/
protected $anIntegrator;
/**
* Determine if there are enough accounts to provide Confidentiality
*
* @Assert\True(
* message = "org_not_enough_accounts_for_confidentiality",
* groups={"account_edit"}
* )
*
* @return bool
*/
public function isEnoughCloudAccountsForConfidentiality()
{
if(null === $this->getSettings()) {
return true;
}
if('NO' != $this->getSettings()->getIntegrity() && null !== $this->getSettings()->getIntegrity()) {
// validate if getIntegrity is selected as it has a higher level validation rule
return true;
}
if('NO' != $this->getSettings()->getConfidentiality() && null !== $this->getSettings()->getConfidentiality()) {
return count($this->cloudAccounts) >= 1;
}
return true;
}
/**
* Determine if there are enough accounts to provide Integrity
*
* @Assert\True(
* message = "org_not_enough_accounts_for_integrity",
* groups={"account_edit"}
* )
*
* @return bool
*/
public function isEnoughCloudAccountsForIntegrity()
{
if(null === $this->getSettings()) {
return true;
}
if('NO' != $this->getSettings()->getIntegrity() && null !== $this->getSettings()->getIntegrity()) {
return count($this->cloudAccounts) >= 2;
}
return true;
}
Я думаю, что нашел проблему. Ты делаешь это :
$dm->persist($this->getUser()->getOrganisation());
Вы должны сделать это:
$dm->persist($org);
Действительно, проверка from связана с переменной $ org, а не ссылкой на объект, я думаю. Попробуй и расскажи нам 🙂
Возможно, операция persist в вашем контроллере не имеет ничего общего с самой формой. Ваши формы, лежащие в основе data_class — это «MetaCloud \ DataBundle \ Document \ Organization», вы уверены, что
$org = $this->getUser()->getOrganisation();
возвращает объект типа ‘MetaCloud \ DataBundle \ Document \ Organization’? Чтобы уточнить вещи, пожалуйста, отправьте код вашей сущности.
Редактировать: также попробуйте добавить
$org = $form->getData();
прежде чем вы сохраните данные.
Я нашел проблему. На самом деле, только сервис валидатора Symfony говорит данные недействительны, но не обновляют измененную сущность в базе данных. Все, что мне нужно было сделать, это обновить объект, связанный с формой, чтобы все заработало:
if ($form->isSubmitted())
{
$dm->refresh($org);
$this->get('session')->getFlashBag()->add('danger', 'msg.update_failed_see_errors');
}
Если у кого-то есть такая же проблема, интересные источники можно найти здесь:
Обсуждение в группах Google о проблеме
Билет на тему для symfony2