sonata-project / SonataDoctrineMongoDBAdminBundle

Symfony Sonata / Integrate Doctrine MongoDB ODM into the SonataAdminBundle
https://docs.sonata-project.org/projects/SonataDoctrineMongoDBAdminBundle
MIT License
65 stars 95 forks source link

No metadata found for property `App\Document\SonataUserUser::$groups` #547

Closed webdevilopers closed 3 years ago

webdevilopers commented 3 years ago

Packages

    "require": {
        "php": "^7.4",
        "ext-ctype": "*",
        "ext-iconv": "*",
        "ext-intl": "*",
        "friendsofsymfony/user-bundle": "dev-master",
        "sonata-project/admin-bundle": "^3.93",
        "sonata-project/doctrine-mongodb-admin-bundle": "^3.7",
        "sonata-project/exporter": "2.x",
        "sonata-project/intl-bundle": "^2.10",
        "sonata-project/translation-bundle": "^2.7",
        "sonata-project/user-bundle": "^4.11",
        "symfony/apache-pack": "^1.0",
        "symfony/dotenv": "^4.4",
        "symfony/flex": "^1.12",
        "symfony/framework-bundle": "^4.4",
        "symfony/http-kernel": "^4.4",
        "symfony/monolog-bundle": "^3.6",
        "symfony/yaml": "^4.4",
        "twig/twig": "^2.9"
    },

Subject

When trying to create a new user the error is:

No metadata found for property App\Document\SonataUserUser::$groups.

The property is added inside FOS\UserBundle\Model\User:

namespace FOS\UserBundle\Model;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Symfony\Component\Security\Core\User\UserInterface as BaseUserInterface;

/**
 * Storage agnostic user object.
 *
 * @author Thibault Duplessis <thibault.duplessis@gmail.com>
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
abstract class User implements UserInterface, GroupableInterface
{
    /**
     * @var mixed
     */
    protected $id;

    /**
     * @var GroupInterface[]|Collection
     */
    protected $groups;

The mapping of this bundle for Users does not include it:

<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mongo-mapping xmlns="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping"
                        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                        xsi:schemaLocation="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping
                        http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping.xsd">

    <mapped-superclass name="FOS\UserBundle\Model\User" collection="fos_user_user">

        <field name="username" type="string" />

        <field name="usernameCanonical" type="string" />

        <field name="email" type="string" />

        <field name="emailCanonical" type="string" />

        <field name="enabled" type="boolean" />

        <field name="salt" type="string" />

        <field name="password" type="string" />

        <field name="lastLogin" type="date" />

        <field name="confirmationToken" type="string" />

        <field name="passwordRequestedAt" type="date" />

        <field name="roles" type="collection" />

        <indexes>
            <index>
                <key name="usernameCanonical" order="asc" />
                <option name="safe" value="true" />
                <option name="unique" value="true" />
            </index>
            <index>
                <key name="emailCanonical" order="asc" />
                <option name="safe" value="true" />
                <option name="unique" value="true" />
            </index>
            <index>
                <key name="confirmationToken" order="asc" />
                <option name="safe" value="true" />
                <option name="sparse" value="true" />
                <option name="unique" value="true" />
            </index>
        </indexes>

    </mapped-superclass>

</doctrine-mongo-mapping>

A hotfix for this:

<?php declare(strict_types=1);

namespace App\Document;

use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
use Sonata\UserBundle\Document\BaseUser;

/**
 * @MongoDB\Document
 */
class SonataUserUser extends BaseUser
{
    /**
     * @MongoDB\Id
     */
    protected $id;

    /**
     * @MongoDB\ReferenceMany(targetDocument=SonataUserGroup::class)
     */
    protected $groups;
}

Refs: https://github.com/sonata-project/SonataUserBundle/issues/1091

franmomu commented 3 years ago

hmm but is this related to this bundle? or SonataUserBundle?

webdevilopers commented 3 years ago

The SonataUserBundle is based on the FOSUserBundle Userclasses which hold the $groups property.

namespace FOS\UserBundle\Model;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Symfony\Component\Security\Core\User\UserInterface as BaseUserInterface;

/**
 * Storage agnostic user object.
 *
 * @author Thibault Duplessis <thibault.duplessis@gmail.com>
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
abstract class User implements UserInterface, GroupableInterface
{
    /**
     * @var mixed
     */
    protected $id;

    /**
     * @var GroupInterface[]|Collection
     */
    protected $groups;

The message thrown here comes from this bundle:

Sonata\DoctrineMongoDBAdminBundle\Model\ MissingPropertyMetadataException No metadata found for property App\Document\SonataUserUser::$groups. Please make sure your Doctrine mapping is properly configured.

But at the bottom line this bundle does not provide the actual mappings. Even the SonataUserBundle only provides the BaseUser and skeleton mappings:

<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mongo-mapping xmlns="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping                         http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping.xsd">
    <mapped-superclass name="Sonata\UserBundle\Document\BaseUser">
        <field name="createdAt" type="date"/>
        <field name="updatedAt" type="date"/>
        <!-- Profile fields -->
        <field name="dateOfBirth" type="date"/>
        <field name="firstname" type="string"/>
        <field name="lastname" type="string"/>
        <field name="website" type="string"/>
        <field name="biography" type="string"/>
        <field name="gender" type="string"/>
        <field name="locale" type="string"/>
        <field name="timezone" type="string"/>
        <field name="phone" type="string"/>
        <!-- social fields -->
        <field name="facebookUid" type="string"/>
        <field name="facebookName" type="string"/>
        <field name="facebookData" type="hash"/>
        <field name="twitterUid" type="string"/>
        <field name="twitterName" type="string"/>
        <field name="twitterData" type="hash"/>
        <field name="gplusUid" type="string"/>
        <field name="gplusName" type="string"/>
        <field name="gplusData" type="hash"/>
        <!-- extra security fields -->
        <field name="token" type="string"/>
        <field name="twoStepVerificationCode" type="string"/>
        <lifecycle-callbacks>
            <lifecycle-callback type="prePersist" method="prePersist"/>
            <lifecycle-callback type="preUpdate" method="preUpdate"/>
        </lifecycle-callbacks>
    </mapped-superclass>
</doctrine-mongo-mapping>
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mongo-mapping xmlns="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping
                    http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping.xsd">

    <document name="{{ namespace }}\Document\User" collection="fos_user_user" customId="true">

        <field fieldName="id" id="true" strategy="INCREMENT" />

    </document>

</doctrine-mongo-mapping>

Both are missing the $groups property.

Event the FOSUserBundle itself is missing it:

<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mongo-mapping xmlns="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping"
                        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                        xsi:schemaLocation="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping
                        http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping.xsd">

    <mapped-superclass name="FOS\UserBundle\Model\User" collection="fos_user_user">

        <field name="username" type="string" />

        <field name="usernameCanonical" type="string" />

        <field name="email" type="string" />

        <field name="emailCanonical" type="string" />

        <field name="enabled" type="boolean" />

        <field name="salt" type="string" />

        <field name="password" type="string" />

        <field name="lastLogin" type="date" />

        <field name="confirmationToken" type="string" />

        <field name="passwordRequestedAt" type="date" />

        <field name="roles" type="collection" />

        <indexes>
            <index>
                <key name="usernameCanonical" order="asc" />
                <option name="safe" value="true" />
                <option name="unique" value="true" />
            </index>
            <index>
                <key name="emailCanonical" order="asc" />
                <option name="safe" value="true" />
                <option name="unique" value="true" />
            </index>
            <index>
                <key name="confirmationToken" order="asc" />
                <option name="safe" value="true" />
                <option name="sparse" value="true" />
                <option name="unique" value="true" />
            </index>
        </indexes>

    </mapped-superclass>

</doctrine-mongo-mapping>

I'm really wondering what is going on here. Maybe the $groups property has been removed in some versions. But can't find any issue on that.

I guess adding the property to the FOSUserBundle could even solve all the issues for the other bundles.

I will put @OskarStark , @core23 , @VincentLanglet in /cc, maybe they know where to delegate.

VincentLanglet commented 3 years ago

Definitely a FosUser issue or at least a SonataUser one.