I am building an app based on Sylius standard edition. With the ResourceBundle i handled to integrate my own entities and the corresponding relations. This new resources should be related later to the products entity, but first i want to get it working "standalone". The backend works for both, the added resource and for relations. These are editable via form-collections. Very fine! Now i want to get translated database-content for my new resource. I tried the way i did it in Symfony earlier, but it didn't work. The last vew days i tried every possible solution found, but none of this works, or i made mistakes... Neither the translation-tables where constructed when typing:
app/console doctrine:schema:update --force
nor translatable content is visible in the forms. When calling the edit action, i get following error:
error:
Neither the property "translations" nor one of the methods "getTranslations()", "translations()", "isTranslations()", "hasTranslations()", "__get()" exist and have public access in class "KontaktBundle\Entity\Kontakte".
Is somebody out there with an example implementation of a extended Sylius-resource with translateable database-content? I'm still learning symfony and sylius too, can you tell me what i'm missing or doing wrong?
# app/config/sylius_config.yml (must be imported in config)
# Adding Resource
sylius_resource:
# Resource Settings
settings:
sortable: true
paginate: 50
allowed_paginate: [50, 100, 500]
filterable: true
resources:
dbk.authors:
driver: doctrine/orm
templates: AuthorBundle:Backend
object_manager: default
classes:
model: AuthorBundle\Entity\Kontakte
#interface: // if you have an interface configured
controller: Sylius\Bundle\ResourceBundle\Controller\ResourceController
repository: Sylius\Bundle\ResourceBundle\Doctrine\ORM\EntityRepository
translation:
model: AuthorBundle\Entity\AuthorsTranslation
mapping:
fields: ['anrede','biografie']
# app/config/sylius_services.yml (must be imported in config)
parameters:
# Parameter for our author entity
app.form.type.authors.class: AuthorBundle\Form\AuthorsType
app.form.type.authors_translation.class: AuthorBundle\Form\AuthorsTranslationType
services:
# Adding Authors Backend menu Item
dbk_backend_authors.menu_builder:
class: AuthorBundle\EventListener\MenuBuilderListener
tags:
- { name: kernel.event_listener, event: sylius.menu_builder.backend.main, method: addBackendMenuItems }
- { name: kernel.event_listener, event: sylius.menu_builder.backend.sidebar, method: addBackendMenuItems }
# Adding Authors FormType
app.form.type.authors:
class: "%app.form.type.authors.class%"
tags:
- {name: form.type, alias: dbk_authors }
app.form.type.authors_translation:
class: "%app.form.type.authors_translation.class%"
tags:
- {name: form.type, alias: dbk_authors_translation }
<?php
// AuthorBundle/EventListener/MenuBuilderListener/MenuBuilderListener.php
namespace AuthorBundle\EventListener;
use Sylius\Bundle\WebBundle\Event\MenuBuilderEvent;
class MenuBuilderListener
{
public function addBackendMenuItems(MenuBuilderEvent $event)
{
$menu = $event->getMenu();
$menu['assortment']->addChild('vendor', array(
'route' => 'Authors',
'labelAttributes' => array('icon' => 'glyphicon glyphicon-user'),
))->setLabel('Authors');
}
}
<?php
// AuthorBundle/Entity/Authors.php
namespace AuthorBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Sylius\Component\Translation\Model\AbstractTranslatable;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Authors
*
* @ORM\Entity
* @ORM\Table(name="authors")
*/
class Authors extends AbstractTranslatable
{
//
// IDENTIFIER FIELDS
//
/**
* @var integer
*
* @ORM\Column(name="id", type="bigint", length=20, nullable=false, options={"unsigned":"true"})
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
//
// FIELDS
//
/**
* @var string
*
* @ORM\Column(name="vorname", type="string", length=255)
*/
private $vorname;
/**
* @var string
*
* @ORM\Column(name="nachname", type="string", length=255)
*/
private $nachname;
public function __construct() {
parent::__construct();
}
//
// TranslationFields - Getters and Setters
//
/**
* Get Anrede
* @return string
*/
public function getAnrede()
{
return $this->translate()->getAnrede();
}
/**
* Set Anrede
*
* @param string $anrede
*
* @return Authors
*/
public function setAnrede($anrede)
{
$this->translate()->setAnrede($anrede);
return $this;
}
/**
* Get Biografie
* @return string
*/
public function getBiografie()
{
return $this->translate()->getBiografie();
}
/**
* Set Biografie
*
* @param string $biografie
*
* @return Authors
*/
public function setBiografie($biografie)
{
$this->translate()->setBiografie($biografie);
return $this;
}
//
// Getters and Setters
//
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set vorname
*
* @param string $vorname
*
* @return Authors
*/
public function setVorname($vorname)
{
$this->vorname = $vorname;
return $this;
}
/**
* Get vorname
*
* @return string
*/
public function getVorname()
{
return $this->vorname;
}
/**
* Set nachname
*
* @param string $nachname
*
* @return Authors
*/
public function setNachname($nachname)
{
$this->nachname = $nachname;
return $this;
}
/**
* Get nachname
*
* @return string
*/
public function getNachname()
{
return $this->nachname;
}
public function __toString(){
return $this->getFullName();
}
}
<?php
// AuthorBundle/Entity/AuthorsTranslation.php
namespace AuthorBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Sylius\Component\Translation\Model\AbstractTranslation;
/**
* AuthorsTranslation
*
* @ORM\Entity
* @ORM\Table(name="authors_translation")
*/
class AuthorsTranslation extends AbstractTranslation
{
/**
* @var integer
*
* @ORM\Column(name="id", type="bigint", length=20, nullable=false, options={"unsigned":"true"})
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
//
// TRANSLATABLE - FIELDS
//
/**
* @var string
* @ORM\Column(name="anrede", type="string", length=255)
*/
private $anrede;
/**
* @var string
* @ORM\Column(name="biografie", type="text")
*/
private $biografie;
/**
* {@inheritdoc}
*/
public function getId()
{
return $this->id;
}
//
// GETTERS AND SETTERS
//
/**
* Set anrede
*
* @param string $anrede
* @return Authors
*/
public function setAnrede($anrede)
{
$this->anrede = $anrede;
return $this;
}
/**
* Get anrede
*
* @return string
*/
public function getAnrede()
{
return $this->anrede;
}
/**
* Set biografie
*
* @param string $biografie
*
* @return Authors
*/
public function setBiografie($biografie)
{
$this->biografie = $biografie;
return $this;
}
/**
* Get biografie
*
* @return string
*/
public function getBiografie()
{
return $this->biografie;
}
}
<?php
// AuthorBundle/Form/AuthorsType.php
namespace AuthorBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Doctrine\ORM\QueryBuilder;
class AuthorsType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
// Add Translations to Form.
->add('translations', 'a2lix_translations', array(
'required' => false,
'fields' => array(
'anrede' => array(
'label' => 'Anrede',
),
'biografie' => array(
'label' => 'Biografie',
'attr' => array('data-edit' => 'wysiwyg', 'rows' => '15'),
'required' => false,
)
)
))
->add('vorname', null, array(
'label' => 'Vorname',
'required' => false,
))
->add('nachname', null, array(
'label' => 'Nachname',
'required' => false,
))
;
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'csrf_protection' => false,
'data_class' => 'AuthorBundle\Entity\Authors'
));
}
/**
* @return string
*/
public function getName()
{
return 'dbk_authors';
}
}
<?php
// AuthorBundle/Form/AuthorsTranslationType.php
namespace AuthorBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class AuthorsTranslationType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('anrede', 'text', array(
'label' => 'Anrede'
))
->add('biografie', 'textarea', array(
'label' => 'Biografie'
))
;
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'dbk_authors_translation';
}
}
{# AuthorBundle/Resources/views/backend/edit||add.html.twig - as you like... the call of form.translation (line 5) is the point here #}
{% form_theme form 'SyliusWebBundle:Backend:forms.html.twig' %}
<div class="row">
<div class="col-md-12">
{{ form_row(form.translations, {'attr': {'class': 'input-lg'}}) }}
{{ form_row(form.vorname) }}
{{ form_row(form.nachname) }}
</div>
</div>
Have a look at the Product and ProductTranslation under the models folder in Sylius Components to see an example of how Sylius implements it.
Kontakte needs to extend AbstractTranslatable, you also need to create a class KontakteTranslation that extends AbstractTranslation. Under sylius_resource you also need to configure the translations:
sylius_resource:
resources:
dbk.contact:
driver: doctrine/orm
templates: KontaktBundle:Backend
object_manager: default
classes:
model: KontaktBundle\Entity\Kontakte
controller: Sylius\Bundle\ResourceBundle\Controller\ResourceController
repository: Sylius\Bundle\ResourceBundle\Doctrine\ORM\EntityRepository
translation:
model: KontaktBundle\Entity\KontakteTranslation
mapping:
fields: {...fields that will be translated...}
Get rid of gedmo translatable extension because Sylius doesn't use it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With