1
votes

I'm trying to install the Sonata Admin Bundle to generate easily admin interfaces of my various entities. I've been following the official docs (https://symfony.com/doc/master/bundles/SonataAdminBundle/getting_started/creating_an_admin.html) but I'm facing a problem I can't figure out while creating my first simple Admin.

My entity is :

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Gedmo\Timestampable\Traits\TimestampableEntity;

/**
 * @ORM\Entity(repositoryClass="App\Repository\SectorRepository")
 */
class Sector
{
    use TimestampableEntity;

    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=30)
     */
    private $name;

    /**
     * @Gedmo\Slug(fields={"name"})
     * @ORM\Column(type="string", length=128)
     */
    private $slug;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Company", mappedBy="sector", cascade = {"persist"})
     * @ORM\JoinColumn(onDelete="SET NULL")
     */
    private $companies;

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

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

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }

    public function getSlug(): ?string
    {
        return $this->slug;
    }

    public function setSlug(string $slug): self
    {
        $this->slug = $slug;

        return $this;
    }

    public function getCompanies(): array
    {
        return $this->companies;
    }

    public function setCompanies($companies): self
    {
        $this->companies = $companies;

        return $this;
    }
}

My Admin class looks like this:

<?php

namespace App\Admin;

use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Symfony\Component\Form\Extension\Core\Type\TextType;

class SectorAdmin extends AbstractAdmin
{
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper->add('name', TextType::class);
    }

    protected function configureDatagridFilters(DatagridMapper $datagridMapper)
    {
        $datagridMapper->add('name');
    }

    protected function configureListFields(ListMapper $listMapper)
    {
        $listMapper->addIdentifier('name');
    }
}

I've added this configuration:

services:
    admin.sector:
        class: App\Admin\SectorAdmin
        arguments: [ ~, App\Entity\Sector, ~]
        tags:
            - { name: sonata.admin, manager_type: orm, label: Sector}
    public: true

And in my sonata admin routes file:

admin_area:
    resource: "@SonataAdminBundle/Resources/config/routing/sonata_admin.xml"
    prefix: /admin

_sonata_admin:
    resource: .
    type: sonata_admin
    prefix: /admin

Which is, as I understand from the doc the minimum configuration to get the Admin to be registered.

Yet, when I run my code, I get an error "Array to string conversion" on the {{ form_errors(form) }} of the datagrid filters. If I comment out the line adding the name attribute to these filters, the list page renders fine but if I then enter the form (creation/edition) view, I get the same error on another element so I guess the problem is deeper.

Could it be a problem of compatibility with Symfony 4.x ?

Thanks by advance !

2
Everything looks ok, can you provide the stack trace?kunicmarko20
Hi, thanks for answering. Here is the stack trace returned by Symfony: ErrorException : pasted.co/46e0232d Haha, digging into this one deeper, it seems the problem comes from another library in fact. I'm going to investigate further !TPouliquen
Yes, apparently the problem came from the fact that I used a particular package to format phone numbers. And it failed on entities that didn't even have a phone number but well.... Thanks for the exterior eye ;)TPouliquen
Good to hear that as your files look ok, I was a bit confused. If you use slack you can find support with sonata on symfony.com/slack-invite in #sonata channel.kunicmarko20

2 Answers

1
votes

Th problem came from using the Misd Phone Number Bundle (https://github.com/misd-service-development/phone-number-bundle).

I still haven't figured out why, I'll edit this if I find the cause of the bug or a solution to it ;)

0
votes

I run to the same problem. Its happened I think in symfony 3.4 where they introduced new widget with same name as the one provided from bundle.

Actually I have no idea how to solve it without BC breaks. So far I have used solution where I patch PhoneNumberBundle and rename tel_widget to misd_tel_widget.

Here is my patch - https://pastebin.com/CnjXB1bi. I'm applying patch in composer file using https://github.com/cweagans/composer-patches.

Patch code:

diff --git a/Form/Type/PhoneNumberType.php b/Form/Type/PhoneNumberType.php
index 58b67bf..9c31add 100644
--- a/Form/Type/PhoneNumberType.php
+++ b/Form/Type/PhoneNumberType.php
@@ -183,6 +183,6 @@ class PhoneNumberType extends AbstractType
      */
     public function getBlockPrefix()
     {
-        return 'tel';
+        return 'misd_tel';
     }
 }
diff --git a/Resources/views/Form/tel.html.twig b/Resources/views/Form/tel.html.twig
index 1fdfed4..c8064e4 100644
--- a/Resources/views/Form/tel.html.twig
+++ b/Resources/views/Form/tel.html.twig
@@ -1,4 +1,4 @@
-{% block tel_widget -%}
+{% block misd_tel_widget -%}
     {% if widget is constant('Misd\\PhoneNumberBundle\\Form\\Type\\PhoneNumberType::WIDGET_COUNTRY_CHOICE') %}
         <div {{ block('widget_container_attributes') }}>
             {{- form_widget(form.country) -}}
diff --git a/Resources/views/Form/tel_bootstrap.html.twig b/Resources/views/Form/tel_bootstrap.html.twig
index 79f4748..7772df9 100644
--- a/Resources/views/Form/tel_bootstrap.html.twig
+++ b/Resources/views/Form/tel_bootstrap.html.twig
@@ -1,4 +1,4 @@
-{% block tel_widget -%}
+{% block misd_tel_widget -%}
     {% if widget is constant('Misd\\PhoneNumberBundle\\Form\\Type\\PhoneNumberType::WIDGET_COUNTRY_CHOICE') %}
         {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-inline')|trim}) %}
         <div {{ block('widget_container_attributes') }}>