Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem together with SonataTranslationBundle #235

Closed
kilhage opened this issue Sep 15, 2016 · 5 comments
Closed

Problem together with SonataTranslationBundle #235

kilhage opened this issue Sep 15, 2016 · 5 comments

Comments

@kilhage
Copy link

kilhage commented Sep 15, 2016

Environment

php 7
CentOS 6
nginx
mysql

Sonata packages

$ composer show sonata-project/*
sonata-project/admin-bundle              3.7.1              The missing Symfony Admin Generator
sonata-project/block-bundle              3.1.1              Symfony SonataBlockBundle
sonata-project/cache                     1.0.7              Cache library
sonata-project/classification-bundle     3.1.0              Symfony SonataClassificationBundle
sonata-project/core-bundle               3.1.1              Symfony SonataCoreBundle
sonata-project/datagrid-bundle           2.2                Symfony SonataDatagridBundle
sonata-project/doctrine-extensions       1.0.2              Doctrine2 behavioral extensions
sonata-project/doctrine-orm-admin-bundle 3.1.0              Symfony Sonata / Integrate Doctrine ORM into the SonataAdminBundle
sonata-project/easy-extends-bundle       2.1.10             Symfony SonataEasyExtendsBundle
sonata-project/exporter                  1.7.0              Lightweight Exporter library
sonata-project/google-authenticator      1.0.2              Library to integrate Google Authenticator into a PHP project
sonata-project/intl-bundle               2.2.4              Symfony SonataIntlBundle
sonata-project/media-bundle              3.x-dev fabd14b    Symfony SonataMediaBundle
sonata-project/notification-bundle       3.0.0              Symfony SonataNotificationBundle
sonata-project/translation-bundle        2.0.2              SonataTranslationBundle
sonata-project/user-bundle               3.0.1              Symfony SonataUserBundle

Symfony packages

$ composer show symfony/*
symfony/assetic-bundle                   v2.8.0             Integrates Assetic into Symfony2
symfony/monolog-bundle                   2.11.1             Symfony MonologBundle
symfony/polyfill-apcu                    v1.2.0             Symfony polyfill backporting apcu_* functions to lower PHP versions
symfony/polyfill-intl-icu                v1.2.0             Symfony polyfill for intl's ICU-related data and classes
symfony/polyfill-mbstring                v1.2.0             Symfony polyfill for the Mbstring extension
symfony/polyfill-php54                   v1.2.0             Symfony polyfill backporting some PHP 5.4+ features to lower PHP versions
symfony/polyfill-php55                   v1.2.0             Symfony polyfill backporting some PHP 5.5+ features to lower PHP versions
symfony/polyfill-php56                   v1.2.0             Symfony polyfill backporting some PHP 5.6+ features to lower PHP versions
symfony/polyfill-php70                   v1.2.0             Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions
symfony/polyfill-util                    v1.2.0             Symfony utilities for portability of PHP codes
symfony/security-acl                     v3.0.0             Symfony Security Component - ACL (Access Control List)
symfony/swiftmailer-bundle               v2.3.11            Symfony SwiftmailerBundle
symfony/symfony                          v2.8.11            The Symfony PHP framework

PHP version

$ php -v
PHP 7.0.10 (cli) (built: Aug 31 2016 17:12:30) ( NTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies
    with blackfire v1.12.0, https://blackfire.io, by Blackfireio Inc.

Subject

I'm having an issue when trying to integrate this bundle with SonataTranslationBundle. When trying to make the category entity translatable it doesn't store the translation for me. It works for other entites when doing the exactly same thing.

Steps to reproduce

Setup the bundle like this:

config.yml

sonata_classification:
    class:
        tag:          App\Sonata\ClassificationBundle\Entity\Tag
        category:     App\Sonata\ClassificationBundle\Entity\Category
        collection:   App\Sonata\ClassificationBundle\Entity\Collection
        context:      App\Sonata\ClassificationBundle\Entity\Context
    admin:
        tag:
            class:    App\Sonata\ClassificationBundle\Admin\TagAdmin
        category:
            class:    App\Sonata\ClassificationBundle\Admin\CategoryAdmin
        collection:
            class:    App\Sonata\ClassificationBundle\Admin\CollectionAdmin

sonata_translation:
    locales: [en_US, sv_SE]
    default_locale: en_US
    gedmo:
        enabled: true

src/App/Sonata/ClassificationBundle/Entity/Category.php

<?php

namespace App\Sonata\ClassificationBundle\Entity;

use App\Sonata\MediaBundle\Entity\Media;
use Doctrine\Common\Collections\ArrayCollection;
use Sonata\ClassificationBundle\Entity\BaseCategory;
use Doctrine\ORM\Mapping as ORM;
use Sonata\TranslationBundle\Model\Gedmo\TranslatableInterface;
use Sonata\TranslationBundle\Traits\Gedmo\PersonalTranslatable;
use Gedmo\Mapping\Annotation as Gedmo;

/**
 * @ORM\Table(name="categories")
 * @ORM\Entity(repositoryClass="App\Sonata\ClassificationBundle\Entity\CategoryRepository")
 * @Gedmo\TranslationEntity(class="App\Sonata\ClassificationBundle\Entity\CategoryTranslation")
 */
class Category extends BaseCategory implements TranslatableInterface
{
    use PersonalTranslatable;

    /**
     * @var int
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @var Media
     * @ORM\ManyToOne(targetEntity="App\Sonata\MediaBundle\Entity\Media")
     * @ORM\JoinColumn(name="media_id", referencedColumnName="id")
     */
    protected $media;

    /**
     * @var Context
     * @ORM\ManyToOne(targetEntity="App\Sonata\ClassificationBundle\Entity\Context")
     * @ORM\JoinColumn(name="context", referencedColumnName="id")
     */
    protected $context;

    /**
     * @var string
     * @Gedmo\Translatable
     */
    protected $name;

    /**
     * @var string
     * @Gedmo\Translatable
     */
    protected $slug;

    /**
     * @var string
     * @Gedmo\Translatable
     */
    protected $description;

    /**
     * @var string
     * @ORM\Column(type="string", nullable=true)
     */
    private $color;

    /**
     * @var ArrayCollection
     *
     * @ORM\OneToMany(
     *     targetEntity="App\Sonata\ClassificationBundle\Entity\CategoryTranslation",
     *     mappedBy="object",
     *     cascade={"persist", "remove"}
     * )
     */
    protected $translations;

    /**
     * Get id
     *
     * @return int $id
     */
    public function getId()
    {
        return $this->id;
    }

    public function __construct()
    {
        $this->translations = new ArrayCollection();
    }

    /**
     * @return string
     */
    public function getColor()
    {
        return $this->color;
    }

    /**
     * @param string $color
     */
    public function setColor($color)
    {
        $this->color = $color;
    }
}

src/App/Sonata/ClassificationBundle/Entity/CategoryTranslation.php

<?php

namespace App\Sonata\ClassificationBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Sonata\TranslationBundle\Model\Gedmo\AbstractPersonalTranslation;

/**
 * @ORM\Entity
 * @ORM\Table(name="category_translations",
 *     uniqueConstraints={
 *     @ORM\UniqueConstraint(name="unique_idx", columns={
 *         "locale", "object_id", "field"
 *     })}
 * )
 *
 * @author Emil Kilhage
 */
class CategoryTranslation extends AbstractPersonalTranslation
{
    /**
     * @ORM\ManyToOne(targetEntity="Category", inversedBy="translations")
     * @ORM\JoinColumn(name="object_id", referencedColumnName="id", onDelete="CASCADE")
     */
    protected $object;
}

Edit

  1. Open the admin UI and navigate to a category and edit it
  2. Switch to Swedish
  3. Enter the translations
  4. Save the category

Expected results

The translations should be inserted to the category_translations table and when toggling between English and Swedish the name should change between the translations.

Actual results

The new name of the category gets written directly to the categories.

@dmarkowicz
Copy link
Contributor

dmarkowicz commented Sep 15, 2016

You need also switch to annotation to overide BaseCategory.orm.xml. Your @Gedmo\Translatable annotations for fields already defined in xml are probably ignored now.

config.yml

doctrine:
    orm:
        entity_managers:
            default:
                mappings:
                    SonataClassificationBundle: ~
                    ApplicationSonataClassificationBundle: # AppSonataClassificationBundle in your case?
                        type: annotation

As you override xml you need to implement callbacks again.

src/App/Sonata/ClassificationBundle/Entity/Category.php

/**
 * ...
 * @ORM\HasLifecycleCallbacks()
 */
class Category extends BaseCategory implements TranslatableInterface
{
    /**
     * @ORM\PrePersist
     */
    public function prePersist()
    {
        parent::prePersist();
    }

    /**
     * @ORM\PreUpdate
     */
    public function preUpdate()
    {
        parent::preUpdate();
    }
...

Also to make this fully work you need to switch to dev versions of SonataClassificationBundle and SonataTranslationBundle with fixes:

@OskarStark OskarStark changed the title Problem togeather with SonataTranslationBundle Problem together with SonataTranslationBundle Sep 16, 2016
@kilhage
Copy link
Author

kilhage commented Sep 16, 2016

Still doesn't work

My doctrine config looks like this:

# Doctrine Configuration
doctrine:
    dbal:
        types:
            json: Sonata\Doctrine\Types\JsonType
        driver:   pdo_mysql
        host:     "%database_host%"
        port:     "%database_port%"
        dbname:   "%database_name%"
        user:     "%database_user%"
        password: "%database_password%"
        charset:  UTF8

    orm:
        auto_generate_proxy_classes: "%kernel.debug%"
        naming_strategy: doctrine.orm.naming_strategy.underscore
        auto_mapping: true
        mappings:
            SonataClassificationBundle: ~
            AppSonataClassificationBundle:
                type: annotation
            gedmo_translatable:
                type: annotation
                prefix: Gedmo\Translatable\Entity
                dir: "%kernel.root_dir%/../vendor/gedmo/doctrine-extensions/lib/Gedmo/Translatable/Entity"
                alias: GedmoTranslatable # (optional) it will default to the name set for the mapping
                is_bundle: false

I also updated the dependencies. I was unable to use the dev versions of sonata-project/classification-bundle since sonata-project/media-bundle requires a stable version...

$ composer show | grep sonata-project
sonata-project/admin-bundle              3.7.1              The missing Symfony Admin Generator
sonata-project/block-bundle              3.1.1              Symfony SonataBlockBundle
sonata-project/cache                     1.0.7              Cache library
sonata-project/classification-bundle     3.1.0              Symfony SonataClassificationBundle
sonata-project/core-bundle               3.1.1              Symfony SonataCoreBundle
sonata-project/datagrid-bundle           2.2                Symfony SonataDatagridBundle
sonata-project/doctrine-extensions       1.0.2              Doctrine2 behavioral extensions
sonata-project/doctrine-orm-admin-bundle 3.1.0              Symfony Sonata / Integrate Doctrine ORM into the SonataAdminBundle
sonata-project/easy-extends-bundle       2.1.10             Symfony SonataEasyExtendsBundle
sonata-project/exporter                  1.7.0              Lightweight Exporter library
sonata-project/google-authenticator      1.0.2              Library to integrate Google Authenticator into a PHP project
sonata-project/intl-bundle               2.2.4              Symfony SonataIntlBundle
sonata-project/media-bundle              3.x-dev fabd14b    Symfony SonataMediaBundle
sonata-project/notification-bundle       3.0.0              Symfony SonataNotificationBundle
sonata-project/translation-bundle        dev-master 67b2808 SonataTranslationBundle
sonata-project/user-bundle               3.0.1              Symfony SonataUserBundle

I also added the lifecycle callbacks to my class that seem to run since the updatedAt columns gets updated in the database once I update a record..

Any suggestions?

@kilhage
Copy link
Author

kilhage commented Sep 16, 2016

I also tried now so my Category class does not extend the BaseCategory but only implements the CategoryInterface and move all code into my class with the same result..

@dmarkowicz
Copy link
Contributor

ClassificationBundle 3.2.0 was released, so I made a simple demo just to proof that integration is possible and works as expected https://github.com/dmarkowicz/sonata-translatable-classification-demo.

@jordisala1991
Copy link
Member

if it is proven, then closing. Ping me if this issue is relevant.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants