C B
C B

Reputation: 21

Extend shopware database, creating relations

I'm trying to implement a plugin to add sales representative data to my shop and associate this data to users.

On this context (users and sales representative) I have:

sales_rep - Sales representative table sales_rep_user - Relation between User and Sales Representative

1st For the swg_sales_rep and swg_sales_rep_user relation (OneToMany) I could create that without problems

SwgSalesRepresentative.php

...
**
 * @ORM\Entity
 * @ORM\Table(name="swg_sales_rep")
 */
class SwgSalesRepresentative extends ModelEntity
{
    ...
/**
     * INVERSE SIDE
     *
     * @var \Doctrine\Common\Collections\ArrayCollection
     *
     * @ORM\OneToMany(
     *      targetEntity="Shopware\CustomModels\SwagUserSalesRepresentative\SwgSalesRepresentative",
     *      mappedBy="salesRepresentative",
     *      orphanRemoval=true
     * )
     */
    protected $salesRepresentativeUsers;

...

SwgSalesRepresentativeUsers.php

/**
 * @ORM\Entity
 * @ORM\Table(name="swg_sales_rep_users")
 */
class SwgSalesRepresentativeUsers extends ModelEntity
{

...

/**
     *
     * @ORM\ManyToOne(targetEntity="Shopware\CustomModels\SwagUserSalesRepresentative\SwgSalesRepresentative")
     * @ORM\JoinColumn(name="sales_rep_id", referencedColumnName="id")
     */
    protected $salesRepresentative;

/**
     * @return mixed
     */
    public function getSalesRepresentative()
    {
        return $this->salesRepresentative;
    }

    /**
     * @param $salesRepresentative
     * @return ModelEntity
     */
    public function setSalesRepresentative($salesRepresentative)
    {
        return $this->setManyToOne(
            $salesRepresentative,
            '\Shopware\CustomModels\SwagUserSalesRepresentative\SwgSalesRepresentative',
            'salesRepresentativeUsers'
        );
    }

And after install I get my tables with foreign key ok.

For the relation between swg_sales_rep_user and s_user (OneToOne) I have problems. My first idea was extend the User model and add the additional logic we need. But this implies to overwrite my users table, take the risk to lose data. What I did was create a SwgUser model that extends User model, like

SwgSalesRepresentativeUsers.php

/**
 * @ORM\Entity
 * @ORM\Table(name="swg_sales_rep_users")
 */
class SwgSalesRepresentativeUsers extends ModelEntity
{

...

    /**
     * @var \Shopware\CustomModels\SwagUserSalesRepresentative\SwgUser $user
     *
     * @ORM\OneToOne(targetEntity="Shopware\CustomModels\SwagUserSalesRepresentative\SwgUser", inversedBy="salesRepresentative")
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
     */
    protected $user;

 /**
     * @return mixed
     */
    public function getUser()
    {
        return $this->user;
    }

    /**
     * @param $user
     * @return ModelEntity
     */
    public function setUser($user)
    {
        return $this->setOneToOne(
            $user,
            '\Shopware\CustomModels\SwagUserSalesRepresentative\SwgUser',
            'user',
            'salesRepresentative'
        );
    }

...

SwgUser.php

/**
 * @ORM\Entity
 * @ORM\Table(name="s_user")
 */
class SwgUser extends User
{

    /**
     *
     * @ORM\OneToOne(targetEntity="Shopware\CustomModels\SwagUserSalesRepresentative\SwgSalesRepresentativeUsers", mappedBy="user")
     */
    protected $salesRepresentative;
 ...

And bootstrap.php install/uninstall looks like

 /**
     * Install method
     *
     * @return bool
     */
    public function install()
    {
        $this->updateSchema();

        return true;
    }

    /**
     * Uninstall method
     *
     * @return bool
     */
    public function uninstall()
    {
        $this->registerCustomModels();

        $em = $this->Application()->Models();
        $tool = new \Doctrine\ORM\Tools\SchemaTool($em);

        $classes = array(
            $em->getClassMetadata('Shopware\CustomModels\SwagUserSalesRepresentative\SwgSalesRepresentative'),
            $em->getClassMetadata('Shopware\CustomModels\SwagUserSalesRepresentative\SwgUser'),
            $em->getClassMetadata('Shopware\CustomModels\SwagUserSalesRepresentative\SwgSalesRepresentativeUsers')
        );

        $tool->dropSchema($classes);

        return true;
    }


    /**
     * Creates the database scheme from existing doctrine models.
     *
     * Will remove the table first, so handle with care.
     */
    protected function updateSchema()
    {
        $this->registerCustomModels();

        $em = $this->Application()->Models();
        $tool = new \Doctrine\ORM\Tools\SchemaTool($em);

        $classes = array(
            $em->getClassMetadata('Shopware\CustomModels\SwagUserSalesRepresentative\SwgSalesRepresentative'),
            $em->getClassMetadata('Shopware\CustomModels\SwagUserSalesRepresentative\SwgUser'),
            $em->getClassMetadata('Shopware\CustomModels\SwagUserSalesRepresentative\SwgSalesRepresentativeUsers')
        );

        try {
            $tool->dropSchema($classes);
        } catch (Exception $e) {
            //ignore
        }
        $tool->createSchema($classes);
    }

I tried to use the unidirectional association mapping and it creates the field but not the relation with s_user table (Foreign key).

So question is, how can I create relations with core tables on shopware without have to recreate (drop/create) the core tables? Is it possible to alter tables programmatically? what is the best approach for these needs. Do you have an example that demonstrate this?

Thanks for helping.

Upvotes: 2

Views: 1293

Answers (1)

barbieswimcrew
barbieswimcrew

Reputation: 448

there is no way to create bidirectional associations with shopware core tables yet. You can have unidirectional associations for sure, but you will not be able to add relational properties to core entities so far.

Except you intend to modify the shopware core itself which should be avoided at any time.

The only - and very tiny - possibility would be by trying to create a relation over a core entities attribute table which is quite "magic stuff" in shopware.

Upvotes: 1

Related Questions