Ankündigung

Einklappen
Keine Ankündigung bisher.

Notice: Array to string conversion, Forms ChoiceType, Objekt-Property ist ein Array

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • [Symfony] Notice: Array to string conversion, Forms ChoiceType, Objekt-Property ist ein Array

    Hallo,

    nach endlosen Versuchen stelle ich die Frage hier. Der FormTypes ist echt schwierig zu verstehen... aus der Symfony Doku:
    In other words, the value of each item is the value you want to get/set in PHP code, while the key is what will be shown to the user
    Also, ich habe ein (Filter-) Objekt mit Eigenschaften:
    PHP-Code:
    // Filter.php
    <?php

    namespace App\Entity\Filter;

    class 
    MyFilter {


        private 
    $areaFilters = [];
        private 
    $catFilters = [];
        ...

        public function 
    setAreaFilters(array $filters) {
            
    $this->areaFilters $filters;
        }

        public function 
    getAreaFilters(): array {
            return 
    $this->areaFilters;
        }

        public function 
    setCatFilters(array $filters) {
            
    $this->areaFilters $filters;
        }

        public function 
    getCatFilters(): array {
            return 
    $this->areaFilters;
        }
        ...
    }
    Jeder Filter enthält enstprechende Filters, welche wiederum Arrays sind
    PHP-Code:
    $areaFilters = [
        
    'AreaA' => [
            
    'id' => 1,
            
    'disabled' => true,
            
    'checked' => false
        
    ],
        
    'AreaB' => [
            
    'id' => 7,
            
    'disabled' => true,
            
    'checked' => true
        
    ]
    ]; 
    Diese Werte will ich nun im ChoiceType darstellen:
    PHP-Code:
    // MyController.php
    <?php
    ...
            
    $filterForm $this->createForm(MyFilterType::class, $filter);   

    ?>    

    // MyFormType.php
    <?php
        
    ...   
            
    $builder
            
    ->add('areaFilters'ChoiceType::class, [
                
    'choices' => $this->createAreaChoices(),
                
    'expanded' => true,
                
    'required' => false,
                
    'label' => false,
                
    'placeholder' => false,
                
    'multiple' => true,
            ]);
        ... 

        private function 
    createAreaChoices() {
            
    $choices = [];
            foreach (
    $this->options['data']->getAreaFilters() as $key => $filter) {
                
    $choices[$key] =  $filter['id'];
            }
        ...
    Eigentlich denke ich, mit der Funktion übergebe ich ein Array nach dem Muster $key => $value, also:
    PHP-Code:
    [
        
    'AreaA' => 1,
        
    'AreaB' => 2,
        ...

    und im HTML erwarte ich
    HTML-Code:
    ...
    <input type="checkbox" id="my_filter_areaFilters_0" name="my_filter[areaFilters][]" value="1">
    ...
    <input type="checkbox" id="my_filter_areaFilters_0" name="my_filter[areaFilters][]" value="2">
    ...
    Alle meine Ansätze führen immer zum selben Ergebnis:
    HTML-Code:
    Notice: Array to string conversion
    
    ...
    Es ist mit Sicherheit ein Verständnisproblem, dank für Hilfe

    Gruss


  • #2
    PHP-Code:
    $filterForm $this->createForm(MyFilterType::class, $filter); 
    Ich weiß nicht ob es daran liegt, allerdings versuchst du das Data Attribute als Values für dein ChoiceType zu verwenden. Der Choice Type speichert das Ergebnis der Auswahl aber wiederum im Data Attribute.

    Wenn du Daten in dein Formular Übertragen möchtest, erstelle eine neue Option Parameter und missbrauche nicht ein vorhanden dafür.

    Kommentar


    • #3
      Zitat von Zeichen32 Beitrag anzeigen
      PHP-Code:
      $filterForm $this->createForm(MyFilterType::class, $filter); 
      Ich weiß nicht ob es daran liegt, allerdings versuchst du das Data Attribute als Values für dein ChoiceType zu verwenden. ...
      Entschuldige, welches Data Attribute? Meinst du choice_attr ?,Nochmal, alle notwendigen Daten liegen im 2. Parameter $filter von createForm() und liegen ja auch im FormType vor. Die würde ich gerne nutzen zum Aufbau und Handling des der choices... ist das der falsch Weg?

      Kommentar


      • #4
        Nochmal, alle notwendigen Daten liegen im 2. Parameter $filter von createForm()
        Genau und der zweite Parameter ist der Parameter für das Model (Data). Dieses nutzt du zum Übergeben der Choice Attribute, ich denke das ist nicht möglich. Erstelle lieber eine eigene Option und übergib diese dann im dritten Parameter.

        Entweder so:
        https://symfony.com/doc/current/form...endencies.html

        Oder als eigenen FormType so:
        https://symfony.com/doc/current/form...the-field-type

        Kommentar


        • #5
          Zitat von Zeichen32 Beitrag anzeigen

          Genau und der zweite Parameter ist der Parameter für das Model (Data). Dieses nutzt du zum Übergeben der Choice Attribute, ich denke das ist nicht möglich. Erstelle lieber eine eigene Option und übergib diese dann im dritten Parameter.

          Entweder so:
          https://symfony.com/doc/current/form...endencies.html
          ... und dann? Es ist wirklich eine schwierige Doku, im Moment hab ich es so:
          PHP-Code:
          // controller
          <?php
             
          ...
             
          $filterForm $this->createForm(MyFilterType::class, $filter,[
                      
          'filters' => $this->object->getAllFilters()
                  ]);
             ...
          ?>

          // form type
          <?php
             
          ...
             
          $builder
                  
          ->add('areaFilters'ChoiceType::class, [
                      
          'choices' => $this->createChoices($options['filters']->getAreaFilters()),
                     ...
             ....
             public function 
          configureOptions(OptionsResolver $resolver)
              {
                  
          $resolver->setRequired('filters');
              }
              ...
              private function 
          createChoices($filter) {
                 
          var_dump($filter); // ['A' => ['id' => int 5, 'checked' => boolean false, 'disabled' => boolean false], 'B' ...
                 
          choices = []
                 foreach(
          $filter as $name => $values) {
                     
          $choices[$name] => $value['id']
                 }
                 return 
          $choices;
              }
              ...
          Bleibt dabei...
          HTML-Code:
          Notice: Array to string conversion

          Kommentar


          • #6
            PHP-Code:
            choices = [] // Hier fehlt ein $ sowie das abschließende ; Zeichen.

            $choices[$name] => $value['id']   // Hier fehlt ebenfalls das abschließende ; Zeichen 
            Weiter würde ich mir jetzt ja mal den StackTrace anschauen, um herauszufinden an welcher Stelle der Fehler auftritt. Da du auch immer nur teile postet, kann man so auch nur raten.

            Kommentar


            • #7
              Zitat von Zeichen32 Beitrag anzeigen
              Weiter würde ich mir jetzt ja mal den StackTrace anschauen, um herauszufinden an welcher Stelle der Fehler auftritt. Da du auch immer nur teile postet, kann man so auch nur raten.
              Ich habe das teil jetzt umgebaut.

              An createForm() übergebe ich nun ein Object mit eeinfachen getter-Methode getAreaFilters() sowie options
              PHP-Code:
              // controller
              $filters = new
              ...
              $filterForm $this->createForm(AdminFilterType::class, $filters,[
                          
              'areaFilters' => $currentFilters['area'],
                          
              'action' => $this->generateUrl('userarea'),
                          
              'method' => 'POST',            
                      ]);

              ... 
              Im FormType
              PHP-Code:
              <?php

              namespace App\Form;

              use 
              App\Entity\AdminFilter;
              use 
              Symfony\Component\Form\AbstractType;
              use 
              Symfony\Component\Form\FormBuilderInterface;
              use 
              Symfony\Component\Form\Extension\Core\Type\ChoiceType;
              use 
              Symfony\Component\OptionsResolver\OptionsResolver;

              class 
              AdminFilterType extends AbstractType {

                  public function 
              buildForm(FormBuilderInterface $builder, array $options) {

                      
              $builder
                      
              ->add('areaFilters'ChoiceType::class, [
                          
              'choices' => [
                              
              $options['data']->getAreaFilters()
                          ],
                          
              'choice_attr' => function($filter$key$value) {
                              return [
                                  
              'checked' => $filter->getChecked(),
                                  
              'value' => $filter->getId(),
                                  
              'disabled' => $filter->getDisabled()
                              ];
                          },
                          
              'choice_label' => function($filter$key$value) {
                              return 
              $filter->getName();
                          },
                          
              'expanded' => true,
                          
              'required' => true,
                          
              'label' => false,
                          
              'placeholder' => false,
                          
              'multiple' => true,
                      ]);
                  }

                  public function 
              configureOptions(OptionsResolver $resolver)
                  {
                      
              $resolver->setRequired('areaFilters');
                  }

                  private function 
              getChoices($filters) {

                      
              $choices = [];
                      foreach (
              $filters as $filter) {
                          
              array_push($choices,$filter);
                      }
                      return 
              $choices;
                  }
              }
              In Twig
              PHP-Code:
              {{form_start(filterForm)}}
                  <
              h3>Filter</h3>
                  <
              input type="checkbox" class="filter-opener" id="filter_area" checked>
                  <
              label for="filter_area">Area ({{countAreaFilters}})</label>
                  <
              div class="filter-area">
                      {{
              form_widget(filterForm.areaFilters)}}
                  </
              div>
              {{
              form_end(filterForm)}} 
              Daraus wird im HTML
              HTML-Code:
              <form name="admin_filter" method="post" action="/userarea/">
                  <h3>Filter</h3>
                  <input type="checkbox" class="filter-opener" id="filter_area" checked="">
                  <label for="filter_area">Area (2)</label>
                  <div class="filter-area">
                      <div id="admin_filter_areaFilters">
                             <input type="checkbox" id="admin_filter_areaFilters_0" name="admin_filter[areaFilters][]" value="5" checked="checked">
                             <label for="admin_filter_areaFilters_0">Antiquität</label>
                             ....
                       </div>
                  </div>
                  <input type="hidden" id="admin_filter__token" name="admin_filter[_token]" value="6EhPxDgbqgtBI5wMA-7OA6p8zT9a_uqJQ9yDL0JyeF8"></form>
              Was passiert und ungewolltes Verhalten ist, ist folgendes:

              - Alle Attribute checked="checked" obwohl einige Eigenschaften checked im Objekt auf false gesetzt sind ( 'checked' => $filter->getChecked())


              Die Codes sind sehr lang, deshalb nur Schnipsel.

              Kommentar


              • #8
                Ok, ich bitte die vorherige Antwort zu ignorieren, es war doch recht spät gestern um schlüssig zu fragen.

                Aber ich habe mein Problem jetzt mal in einem Skript zusammengefasst:
                PHP-Code:
                <?php

                namespace App\Controller;

                use 
                Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
                use 
                Symfony\Component\Form\AbstractType;
                use 
                Symfony\Component\Form\Extension\Core\Type\ChoiceType;
                use 
                Symfony\Component\Form\FormBuilderInterface;
                use 
                Symfony\Component\HttpFoundation\Request;

                class 
                LocaleController extends AbstractController {

                    public function default(
                Request $request) {

                        
                $filterGroup = new FilterGroup();
                        foreach ([
                'GroupA''GroupB'] as $groupName) {
                            
                $filters = [];
                            for (
                $i 1$i 4$i++) {
                                
                $filter = new Filter();
                                
                $filter->setId($i);
                                
                $filter->setName('Filter_' $groupName '_' $i);
                                
                $filter->setChecked($i === true false);
                                
                $filter->setDisabled($i === false true);

                                
                $filters[] = $filter;
                            }
                            
                $methodName 'set' $groupName;
                            
                $filterGroup->$methodName($filters);
                        }

                        
                $form $this->createForm(FilterType::class, $filterGroup);

                        return 
                $this->render('test.twig', [
                            
                'form' => $form->createView(),
                        ]);
                    }
                }

                class 
                FilterType extends AbstractType {

                    public function 
                buildForm(FormBuilderInterface $builder, array $options) {

                        
                // var_dump($options['data']);

                        
                $builder
                            
                ->add('groupA'ChoiceType::class, [
                                
                'choices' => $options['data']->getGroupA(),
                                
                'choice_attr' => function ($filter) {
                                    return [
                                        
                'value' => $filter->getId(),
                                        
                'checked' => $filter->getChecked(), // ??? obwohl unterschiedliche Werte für Attribute 'checked', werden alle als checked ausgegeben                         
                                        
                'disabled' => $filter->getDisabled(), 
                                    ];
                                },
                                
                'choice_label' => function ($filter$key$value) {
                                    return 
                $filter->getName();
                                },
                                
                'expanded' => true,
                                
                'multiple' => true,
                            ]);
                    }
                }

                class 
                FilterGroup {

                    private 
                $groupA = [];
                    private 
                $groupB = [];

                    public function 
                setGroupA($group) {
                        
                $this->groupA $group;
                    }

                    public function 
                getGroupA() {
                        return 
                $this->groupA;
                    }

                    public function 
                setGroupB($group) {
                        
                $this->groupB $group;
                    }

                    public function 
                getGroupB() {
                        return 
                $this->groupB;
                    }
                }

                class 
                Filter {
                    private 
                $id 0;
                    private 
                $checked false;
                    private 
                $disabled false;
                    private 
                $name;

                    public function 
                setId(int $id) {
                        
                $this->id $id;
                    }

                    public function 
                getId(): int {
                        return 
                $this->id;
                    }

                    public function 
                setChecked($bool) {
                        
                $this->checked $bool;
                    }

                    public function 
                getChecked() {
                        return 
                $this->checked;
                    }

                    public function 
                setDisabled($bool) {
                        
                $this->disabled $bool;
                    }

                    public function 
                getDisabled($bool) {
                        return 
                $this->disabled;
                    }

                    public function 
                setName($name) {
                        
                $this->name $name;
                    }

                    public function 
                getName() {
                        return 
                $this->name;
                    }
                }
                Alle Attribute (value, disabled) werden richtig gesetzt, nur das checked Attribute wird falsch gesetzt. Warum?

                Kommentar


                • #9
                  Niemand eine Idee auf weiter Flur?

                  Kommentar


                  • #10
                    Das Checked Attribute wird normalerweise je nach Auswahl festgelegt von der Form Komponente, keine Ahnung ob man das so machen kann.

                    Du benutzt auch wieder das Data Attribute, welches eigentlich das Model enthält, wo am Ende die Daten des Benutzers drin gespeichert werden.
                    Das Feld $groupA enthält später ja die Auswahl welche der Benutzer ausgewählt halt, gleichzeitig Benutzt du das selbe Feld um die Optionen zu generieren, das kann so nicht ganz Funktionieren.


                    Kommentar

                    Lädt...
                    X