Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP][MySQL] Symfony 2 i nadpisanie formularza rejestracji
Forum PHP.pl > Forum > Gotowe rozwiązania
swiezak
Witam.
Korzystam z FOS User Bundle dostepnym w Symfony 2 i chcialbym, aby podczas rejestracji uzytkownik mogl wybrac rodzaj formularza z okreslonymi polami do wypelnienia.
Bylyby to 2 formularze: dla osoby prywatnej i firmy (wybor odbywalby sie poprzez klikniecie na stosowny link: Osoba prywatna | Firma)

Na chwile obecna zrobilem formularz dla osoby prywatnej. Wszystko dziala jak nalezy, ale nie mam pomyslu, jak zrobic form dla firmy i podpiac go pod odpowiedni link o etykiecie Firma.

Ponizej fragmenty kodu.

Ml\UserBundle\Form\RegistrationType.php
  1. namespace Ml\UserBundle\Form;
  2.  
  3. use Symfony\Component\Form\AbstractType;
  4. use Symfony\Component\Form\FormBuilderInterface;
  5.  
  6. use Symfony\Component\OptionsResolver\OptionsResolverInterface;
  7. use Symfony\Component\Validator\Constraints\Email;
  8. use Symfony\Component\Validator\Constraints\Length;
  9. use Symfony\Component\Validator\Constraints\NotBlank;
  10. use Symfony\Component\Validator\Constraints\Collection;
  11.  
  12. class RegistrationType extends AbstractType
  13. {
  14. public function buildForm(FormBuilderInterface $builder, array $options)
  15. {
  16. // custom field
  17. $builder
  18. ->add('name', 'text', array('label' => 'Imię'))
  19. ->add('surname', 'text', array('label' => 'Nazwisko'))
  20. ->add('address', 'text', array('label' => 'Adres'))
  21. ->add('city', 'text', array('label' => 'Miejscowość'))
  22. ->add('post_code', 'text', array('label' => 'Kod pocztowy'))
  23. ->add('phone', 'text', array('label' => 'Telefon stacjonarny'))
  24. ->add('mobile', 'text', array('label' => 'Telefon komórkowy'));
  25. }
  26.  
  27. public function getParent()
  28. {
  29. return 'fos_user_registration';
  30. }
  31.  
  32. public function getName()
  33. {
  34. return 'ml_user_registration';
  35. }
  36. }



User.php (Entity)
  1. namespace Ml\UserBundle\Entity;
  2. use Gedmo\Mapping\Annotation as Gedmo;
  3.  
  4. use FOS\UserBundle\Model\User as BaseUser;
  5. use Doctrine\ORM\Mapping as ORM;
  6.  
  7. /**
  8. * @ORM\Entity
  9. * @ORM\Table(name="fos_user")
  10. * @ORM\Entity(repositoryClass="Ml\UserBundle\Entity\UserRepository")
  11. */
  12. class User extends BaseUser
  13. {
  14. /**
  15. * @ORM\Id
  16. * @ORM\Column(type="integer")
  17. * @ORM\GeneratedValue(strategy="AUTO")
  18. */
  19. protected $id;
  20.  
  21. /**
  22.   * @var string
  23.   *
  24.   * @ORM\Column(name="name", type="string", length=50, nullable=true)
  25.   */
  26. private $name;
  27.  
  28. /**
  29.   * @var string
  30.   *
  31.   * @ORM\Column(name="surname", type="string", length=50, nullable=true)
  32.   */
  33. private $surname;
  34.  
  35. /**
  36.   * @var string
  37.   *
  38.   * @ORM\Column(name="address", type="string", length=100, nullable=true)
  39.   */
  40. private $address;
  41.  
  42. /**
  43.   * @var string
  44.   *
  45.   * @ORM\Column(name="post_code", type="string", length=20, nullable=true)
  46.   */
  47. private $postCode;
  48.  
  49. /**
  50.   * @var string
  51.   *
  52.   * @ORM\Column(name="city", type="string", length=50, nullable=true)
  53.   */
  54. private $city;
  55.  
  56. /**
  57.   * @var string
  58.   *
  59.   * @ORM\Column(name="phone", type="string", length=20, nullable=true)
  60.   */
  61. private $phone;
  62.  
  63. /**
  64.   * @var integer
  65.   *
  66.   * @ORM\Column(name="mobile", type="integer", length=20, nullable=true)
  67.   */
  68. private $mobile;
  69.  
  70. /**
  71.   * @var string
  72.   *
  73.   * @ORM\Column(name="company_name", type="string", length=255, nullable=true)
  74.   */
  75. private $companyName;
  76.  
  77. /**
  78.   * @var string
  79.   *
  80.   * @ORM\Column(name="nip", type="string", length=13, nullable=true)
  81.   */
  82. private $nip;
  83.  
  84. /**
  85.   * @var integer
  86.   *
  87.   * @ORM\Column(name="regon", type="integer", length=14, nullable=true)
  88.   */
  89. private $regon;
  90.  
  91. /**
  92.   * @var boolean
  93.   *
  94.   * @ORM\Column(name="type_account", type="boolean", options={"default":0}, nullable=true)
  95.   */
  96. private $typeAccount;
  97.  
  98. /**
  99.   * @var \DateTime $created
  100.   *
  101.   * @ORM\Column(name="created", type="datetime")
  102.   * @Gedmo\Timestampable(on="create")
  103.   */
  104. protected $created;



app\Resources\FOSUserBundle\views\Registration\register.html.twig
  1. {% extends "::layout.html.twig" %}
  2.  
  3. {% block title %}Rejestracja konta | {{ parent() }}{% endblock %}
  4.  
  5. {% block contentpage %}
  6. <h1 class="section-title">Rejestracja konta</h1>
  7.  
  8. <p>Typ konta: Osoba prywatna | Firma</p>
  9.  
  10. {% block fos_user_content %}
  11. {% include "FOSUserBundle:Registration:register_content.html.twig" %}
  12. {% endblock fos_user_content %}
  13.  
  14. {% endblock contentpage %}



config.yml
  1. fos_user:
  2. db_driver: orm
  3. firewall_name: main
  4. user_class: Ml\UserBundle\Entity\User
  5. registration:
  6. form:
  7. type: ml_user_registration
  8. from_email:
  9. address: noreply@project.com
  10. sender_name: Project
  11. service:
  12. mailer: fos_user.mailer.twig_swift



services.yml
  1. services:
  2. ml.form.registration:
  3. class: Ml\UserBundle\Form\RegistrationType
  4. tags:
  5. - { name: form.type, alias: ml_user_registration }



Czy ktos pomoze? Bede wdzieczny za wszelkie wskazowki.

Dokonalem kilku poprawek.

services.xml
  1. <?xml version="1.0" ?>
  2.  
  3. <container xmlns="http://symfony.com/schema/dic/services"
  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5. xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/ser...pan>>
  6. <services>
  7. <service id="ml.form.registration" class="Ml\UserBundle\Form\RegistrationType">
  8. <tag name="form.type" alias="ml_user_registration" />
  9. <argument type="service" id="service_container" />
  10. </service>
  11. </services>
  12. </container>



services.yml
  1. services:
  2. ml.form.registration:
  3. class: Ml\UserBundle\Form\RegistrationType
  4. tags:
  5. - { name: form.type, alias: ml_user_registration }
  6. arguments: ["@service_container"]



RegistrationType.php
  1. namespace Ml\UserBundle\Form;
  2.  
  3. use Symfony\Component\Form\AbstractType;
  4. use Symfony\Component\Form\FormBuilderInterface;
  5.  
  6. use Symfony\Component\OptionsResolver\OptionsResolverInterface;
  7. use Symfony\Component\Validator\Constraints\Email;
  8. use Symfony\Component\Validator\Constraints\Length;
  9. use Symfony\Component\Validator\Constraints\NotBlank;
  10. use Symfony\Component\Validator\Constraints\Collection;
  11.  
  12. use Symfony\Component\Validator\Constraints\IsTrue;
  13. use Symfony\Component\DependencyInjection\ContainerInterface as Container;
  14.  
  15. class RegistrationType extends AbstractType
  16. {
  17. private $container;
  18. private $type;
  19.  
  20. public function __construct(Container $container) {
  21. $this->container = $container;
  22. $this->type = $this->container->get('request')->get('type');
  23. }
  24. public function buildForm(FormBuilderInterface $builder, array $options)
  25. {
  26. if ($this->type == 'company') {
  27. $builder
  28. ->add('company_name', 'text', array('label' => 'Nazwa firmy'))
  29. ->add('address', 'text', array('label' => 'Adres'))
  30. ->add('post_code', 'text', array('label' => 'Kod pocztowy'))
  31. ->add('city', 'text', array('label' => 'Miasto'))
  32. ->add('nip', 'text', array('label' => 'NIP'))
  33. ->add('regon', 'text', array('label' => 'Regon', 'required' => false))
  34. ->add('phone', 'text', array('label' => 'Telefon kontaktowy'))
  35. ->add('mobile', 'text', array('label' => 'Telefon komórkowy', 'required' => false))
  36. ->add('typeAccount', 'hidden', array('data' => '1'))
  37.  
  38. ->add('termsAccepted', 'checkbox', array(
  39. 'label' => 'Akceptuję regulamin',
  40. 'required' => true,
  41. 'mapped' => false,
  42. 'constraints' => new IsTrue(),
  43. ))
  44. } else {
  45. $builder
  46. ->add('name', 'text', array('label' => 'Imię',
  47. 'attr' => array(
  48. 'pattern' => '.{3,}' // minlength
  49. )
  50. ))
  51. ->add('surname', 'text', array('label' => 'Nazwisko',
  52. 'attr' => array(
  53. 'pattern' => '.{3,}' // minlength
  54. )
  55. ))
  56. ->add('address', 'text', array('label' => 'Adres',
  57. 'attr' => array(
  58. 'pattern' => '.{3,}' // minlength
  59. )
  60. ))
  61. ->add('post_code', 'text', array('label' => 'Kod pocztowy',
  62. 'attr' => array(
  63. 'pattern' => '.{5,}' // minlength
  64. )
  65. ))
  66. ->add('city', 'text', array('label' => 'Miejscowość',
  67. 'attr' => array(
  68. 'pattern' => '.{3,}' // minlength
  69. )
  70. ))
  71. ->add('phone', 'text', array('label' => 'Telefon kontaktowy',
  72. 'attr' => array(
  73. 'pattern' => '.{3,}' // minlength
  74. )
  75. ))
  76. ->add('mobile', 'text', array('label' => 'Telefon komórkowy',
  77. 'attr' => array(
  78. 'pattern' => '.{3,}' // minlength
  79. ), 'required' => false
  80. ))
  81. ->add('typeAccount', 'hidden', array('data' => '0'))
  82.  
  83. ->add('termsAccepted', 'checkbox', array(
  84. 'label' => 'Akceptuję regulamin',
  85. 'required' => true,
  86. 'mapped' => false,
  87. 'constraints' => new IsTrue(),
  88. ))
  89. ;
  90. }
  91. }
  92. ...
  93. }


Niestety, formularz nie dziala tak, jak nalezy. Z rejestracja osoby nie ma problemu, ale jest z rejestracja firmy. Dostaje zwrotke o nastepujacej tresci: " Ten formularz nie powinien zawierać dodatkowych pól."

Jak to naprawic? Prosze o pomoc.
lukaskolista
  1. class RegistrationType extends AbstractType {}

Powyższe zmień na klasę abstrakcyjną, która dodaje do formularza pola wspólne dla osoby fizycznej i firmy. Następnie zrób 2 klasy:
  1. // Tutaj wspolne pola
  2. abstract class AbstractRegistrationType extends AbstractType {}
  3.  
  4. // Pola dla osoby fizycznej
  5. class NaturalPersonRegistrationType extends AbstractRegistrationType {}
  6.  
  7. // Pola dla firmy
  8. class CompanyRegistrationType extends AbstractRegistrationType {}


A teraz przyczepię się do bardzo złych nawyków:
  1. class RegistrationType extends AbstractType
  2. {
  3. private $container;
  4. private $type;
  5.  
  6. public function __construct(Container $container) {
  7. $this->container = $container;
  8. $this->type = $this->container->get('request')->get('type');
  9. }
  10.  
  11. // ...
  12. }
Nie przekazuje się kontenera usług do klas nie implementujących interface'u ContainerAware, ponieważ ten kontener nie jest im do niczego potrzebny. Jak już bardzo musisz przekazać gdzieś kontener, to implementuj ContainerAwareInterface. Dużo lepszym pomysłem jest przekazanie do konstruktora po prostu typu w ten sposób:
  1. services:
  2. ml.form.registration:
  3. class: Ml\UserBundle\Form\RegistrationType
  4. tags:
  5. - { name: form.type, alias: ml_user_registration }
  6. arguments:
  7. - "@=container.get('request').get('type')"
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2024 Invision Power Services, Inc.