i try setup translations form
http://a2lix.fr/bundles/translation-form/ and https://github.com/Atlantic18/DoctrineExtensions/blob/master/doc/translatable.md#translatable-entity-example
composer.json
"a2lix/translation-form-bundle": "2.*#dev",
"stof/doctrine-extensions-bundle": "1.2.*#dev",
config.yml
stof_doctrine_extensions:
default_locale: en
orm:
default:
translatable: true
sluggable: true
sluggable: true
timestampable: true
a2lix_translation_form:
locale_provider: default # [1]
locales: [pl, en, de] # [1-a]
default_locale: en
manager_registry: doctrine # [2]
templating: "A2lixTranslationFormBundle::default.html.twig"
entity
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use APY\DataGridBundle\Grid\Mapping as GRID;
use Gedmo\Mapping\Annotation as Gedmo;
use Gedmo\Translatable\Translatable;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity
* #ORM\Table(name="c_Base"
,indexes={
* #ORM\Index(name="search_name", columns={"name"}),
* #ORM\Index(name="orderCity", columns={"city"})
* })
*/
class Base implements Translatable{
/**
* #ORM\Column(type="bigint")
* #ORM\Id
*/
private $id;
/**
* Hexaid
* #var string
*/
private $hid;
/**
* #ORM\Column(type="string")
* #GRID\Column(title="name")
* #Gedmo\Translatable
* #var string
*/
private $name;
/**
* #Gedmo\Locale
* Used locale to override Translation listener`s locale
* this is not a mapped field of entity metadata, just a simple property
*/
private $locale;
build form
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('translations', 'a2lix_translations', array(
'fields'=>array(
'name'=>array(),
'description'=>array(
'field_type' => 'ckeditor'
)
)
)
);
error
Neither the property "translations" nor one of the methods "getTranslations()", "translations()", "isTranslations()", "hasTranslations()", "__get()" exist and have public access in class "Mea\CharterBundle\Entity\Base".
i dont't have private $translations; var in base - because is public translation - in example for personal translations exist $translations
https://github.com/Atlantic18/DoctrineExtensions/blob/master/doc/translatable.md#personal-translations
but for https://github.com/Atlantic18/DoctrineExtensions/blob/master/doc/translatable.md#translatable-entity-example not.
Can i use it in http://a2lix.fr/bundles/translation-form/ ?
here is other way example
DoctrineExtensions Notice: Undefined index: foreignKey in $em->getRepository('Gedmo\\Translatable\\Entity\\Translation');
Here is the working example from my current project how to use DoctrineExtension from KNP (I know this doesn't answer the question, look at the comments above).
composer.json:
"knplabs/doctrine-behaviors": "dev-master",
"a2lix/translation-form-bundle" : "dev-master"
config.yml:
imports:
...
- { resource: ../../vendor/knplabs/doctrine-behaviors/config/orm-services.yml }
framework:
translator:
fallback: "%locale%"
...
a2lix_translation_form:
locale_provider: default
locales: [ru, en]
default_locale: ru
required_locales: [ru]
manager_registry: doctrine
templating: "#SLCore/includes/translation.html.twig" # if you want to use your own template
Entities:
Product
use Knp\DoctrineBehaviors\Model\Translatable\Translatable;
class Product
{
use Translatable;
// other fields which should not be translated
// $translations field alredy has been created and mapped by DE
ProductTranslation (DE requires this entity):
use Knp\DoctrineBehaviors\Model\Translatable\Translation;
class ProductTranslation
{
use Translation;
// fields that should be translated
// e.g. $title, $description (id, locale, translatable fields already have been created by Translation trait, mapped by DE)
ProductType form:
->add('translations', 'a2lix_translations', [/* other options go here */])
form.html.twig:
{% block javascripts %}
{{ parent() }}
<script type="text/javascript" src="{{ asset('bundles/a2lixtranslationform/js/a2lix_translation_bootstrap.js') }}"></script>
{% endblock %}
...
{{ form_widget(form.translations) }}
I know this is not an interesting example, but it works.
Related
I've forked a Symfony 3 project and I'm trying to add a new Entity and the matching form type, but I can't make it work.
I've tried with the generator and manually, both won't work. A solution with the generator would be the best option
I've generated my entity School with php bin/console doctrine:generate:entity, but when I'm trying to generate the Form, I get the error Class GreenBundle\Entity\School does not exist.
I then tried to create the Form manually and got : Expected to find class "GreenBundle\Form\SchoolType" in file "/var/www/symfony/src/GreenBundle/Form/SchoolType.php" while importing services from resource "../../src/GreenBundle/*", but it was not found! Check the namespace prefix used with the resource.
My school entity generated by the command line is simple
<?php
namespace GreenBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* School
*
* #ORM\Table(name="school")
* #ORM\Entity(repositoryClass="GreenBundle\Repository\SchoolRepository")
*/
class School
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="nom", type="string", length=255)
*/
private $nom;
(... Some other variables, the getters and setters )
}
The SchoolType I added is :
<?php
namespace GreenBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\OptionsResolver\OptionsResolver;
class SchoolType extends AbstractType
{
/**
* #param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'GreenBundle\Entity\School',
));
}
/**
* #return string
*/
public function getName()
{
return 'green_mainbundle_school';
}
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('nom', TextType::class, array(
'label' => "Nom de l'école",
'required' => false,
'attr' => array(
'class' => 'form-control',
'placeholder' => 'ex: École Saint-Exupéry')
));
}
}
And the block In services.yml the error code is referring to is :
# this creates a service per class whose id is the fully-qualified class name
GreenBundle\:
resource: '../../src/GreenBundle/*'
# you can exclude directories or files
# but if a service is unused, it's removed anyway
exclude: '../../src/GreenBundle/{Entity,Repository,Tests}'
Do you know what I'm doing wrong to get the server to run with the new SchoolType and be able to use it in a controller ?
Thanks
======== Edit
I do have Symfony 3
php bin/console --version
Symfony 3.4.14 (kernel: app, env: dev, debug: true)
The project architecture is classic I guess, I have the default folders of Symfony
In the src folder I have :
AppBundle (unused)
GreenBundle
Controller
DataFixtures
DBAL
DependencyInjection
Entity
Form
Repository (Empty, I don't think they created entities with the generator)
Service
Tests
Twig
GreenBundle.php
======== Edit 2
The namespace I use in GreenBundle.php is GreenBundle, you can see the file below
namespace GreenBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class GreenBundle extends Bundle
{
public function getParent()
{
return 'FOSUserBundle';
}
}
In case anybody ever have the same kind of issue, I was running my project in a Docker container and it was a synch problem. The Symfony file themselves are correct. Docker detected that new file were added but didn't set the content properly. Rebuild and/or changing the way I use docker with this app fixes the issue
Is there some examples to implement this? Don't show nothing on my page.
{% include 'FOSCommentBundle:Thread:async.html.twig' with {'id': 'foo'} %}
I don't understand how to place this code and what will show on my page.
And when i place this on my config.yml
assetic:
bundles: [ "FOSCommentBundle" ]
Creates an error:
Unrecognized option "assetic" under "fos_comment".
My configuration:
fos_comment:
db_driver: orm
class:
model:
comment: BackEndBundle\Entity\Comment
thread: BackEndBundle\Entity\Thread
assetic:
bundles: [ "FOSCommentBundle" ]
I assume you have configure the bundle and have created the require classes like this
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use FOS\CommentBundle\Entity\Comment as BaseComment;
/**
* #ORM\Entity
* #ORM\ChangeTrackingPolicy("DEFERRED_EXPLICIT")
*/
class Comment extends BaseComment
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* Thread of this comment
*
* #var Thread
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Thread")
*/
protected $thread;
}
And Thread.php like this
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use FOS\CommentBundle\Entity\Thread as BaseThread;
/**
* #ORM\Entity
* #ORM\ChangeTrackingPolicy("DEFERRED_EXPLICIT")
*/
class Thread extends BaseThread
{
/**
* #var string $id
*
* #ORM\Id
* #ORM\Column(type="string")
*/
protected $id;
}
In your config.yml, you will now have something like this
fos_comment:
db_driver: orm
class:
model:
comment: AppBundle\Entity\Comment
thread: AppBundle\Entity\Thread
run the following commands
doctrine:cache:clear-metadata
doctrine:schema:update --force
After this you will have tables in the database for the entities
Now include this at top of the template
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
where you've included this
{% include 'FOSCommentBundle:Thread:async.html.twig' with {'id': 'foo'} %}
Clear both dev and prod cache after this step.
PS: I have selected the doctrine ORM method
My boss installed this bundle for the softdelete filter, but the documentation is beyond sparse. How do I use this in my delete queries?
Enable it in your config:
stof_doctrine_extensions:
orm:
default:
...
softdeleteable: true
doctrine:
...
orm:
filters:
softdeleteable:
class: Gedmo\SoftDeleteable\Filter\SoftDeleteableFilter
enabled: true
Then in your entity:
<?php
namespace Foo\BarBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* ...
* #Gedmo\SoftDeleteable(fieldName="deletedAt")
* #ORM\Entity
*/
class Foo
{
/**
* #var \DateTime $deletedAt
*
* #ORM\Column(name="deleted_at", type="datetime", nullable=true)
*/
private $deletedAt;
Then just delete entities like you normally would (the extension takes care of the rest):
$em = $this->getDoctrine()->getManager();
$em->remove($entity);
$em->flush();
I also needed another puzzle part: The doctrine yaml config:
XYBundle\Entity\Adresse:
type: entity
table: adresse
gedmo:
soft_deleteable:
field_name: deleted_at
time_aware: false
id:
id:
type: integer
generator: { strategy: AUTO }
fields:
ort:
type: string
length: 100
plz:
type: string
columnDefinition: varchar(255) NOT NULL DEFAULT ''
deleted_at:
type: datetime
nullable: true
I have been trying out Symfony 2.2, the FOSRest Bundle (using JMS Serializer), and Doctrine ODM using MongoDB.
After many hours of trying to figure out how to correctly setup the FOSRest Bundle I'm still having some trouble: I have a very simple route that returns a list of products and prices. Whenever I request for the HTML format I get the correct response, but if I request any other format (JSON, XML) I get an error:
[{"message": "Resources are not supported in serialized data. Path: Monolog\\Handler\\StreamHandler -> Symfony\\Bridge\\Monolog\\Logger -> Doctrine\\Bundle\\MongoDBBundle\\Logger\\Logger -> Doctrine\\Bundle\\MongoDBBundle\\Logger\\AggregateLogger -> Doctrine\\ODM\\MongoDB\\Configuration -> Doctrine\\MongoDB\\Connection -> Doctrine\\ODM\\MongoDB\\LoggableCursor",
"class": "JMS\\Serializer\\Exception\\RuntimeException",...
you can see the full error message here
My current setup is very simple: I have created a single route to a controller that returns a list of products and the price (I followed this example to create the product document).
This is the route:
rest_product:
type: rest
resource: Onema\RestApiBundle\Controller\ProductController
This is the controller:
<?php
namespace Onema\RestApiBundle\Controller;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\Routing\ClassResourceInterface;
use FOS\Rest\Util\Codes;
use JMS\Serializer\SerializationContext;
use Onema\RestApiBundle\Document\Product;
class ProductController extends FOSRestController implements ClassResourceInterface
{
public function getAction()
{
$dm = $this->get('doctrine_mongodb')->getManager();
$products = $dm->getRepository('RestApiBundle:Product')->findAll();
if(!$products)
{
throw $this->createNotFoundException('No product found.');
}
$data = array('documents' => $products);
$view = $this->view($data, 200);
$view->setTemplate("RestApiBundle:Product:get.html.twig");
return $this->handleView($view);
}
}
This is the view called from the controller Resources/Product/get.html.twig:
<ul>
{% for document in documents %}
<li>
{{ document.name }}<br />
{{ document.price }}
</li>
{% endfor %}
</ul>
Any ideas why this would work correctly for one format but not the others? Anything additional I'm supposed to setup?
UPDATE:
This is the config values I have been using.
At the end of app/config/config.yml I had this:
sensio_framework_extra:
view: { annotations: false }
router: { annotations: true }
fos_rest:
param_fetcher_listener: true
body_listener: true
format_listener: true
view:
formats:
json: true
failed_validation: HTTP_BAD_REQUEST
default_engine: twig
view_response_listener: 'force'
WORKAROUND:
Doing a bit more research I ran into another error which lead me to this questions and answer:
https://stackoverflow.com/a/14030646/155248
Once I got rid of the Doctrine\ODM\MongoDB\LoggableCursor by adding every result to an array like this:
$productsQ = $dm->getRepository('RestApiBundle:Product')->findAll();
foreach ($productsQ as $product) {
$products[] = $product;
}
return $products;
I started getting the results in the correct format. This is kind of a lame solution and still hope to find a better answer to this issue.
If you want to get a colection of RestApiBundle:Product documents, you MUST call the method "toArray" after calling find method from repository or getQuery method from query builder
/**
* #Route("/products.{_format}", defaults={"_format" = "json"})
* #REST\View()
*/
public function getProductsAction($_format){
$products = $this->get('doctrine_mongodb')->getManager()
->getRepository('RestApiBundle:Product')
->findAll()->toArray();
return $products;
}
also you can call array_values($products) for correct serialization of exclude strategy
Most likely the error lies somewhere in your config files or perhaps lack of? Add your configs and if I can I will update my answer.
For now I'll walk you through a simple implementation.
First lets start with the configs:
Note: I'm going to be using annotations for some of the settings see SensioFrameworkExtraBundle.
#app/config/config.yml
sensio_framework_extra:
view:
annotations: false
fos_rest:
param_fetcher_listener: true
body_listener: true
format_listener: true
view:
view_response_listener: 'force'
First we setup sensio extra bundle. The default config enables annotations are set to true. I disabled annotations for the view(I won't be using them here).
For fos_rest we are setting up the Listeners, we're keeping it simple so we're going to use the example from their docs.
We will create the entity:
<?php
namespace Demo\DataBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints;
use JMS\Serializer\Annotation\ExclusionPolicy; //Ver 0.11+ the namespace has changed from JMS\SerializerBundle\* to JMS\Serializer\*
use JMS\Serializer\Annotation\Expose; //Ver 0.11+ the namespace has changed from JMS\SerializerBundle\* to JMS\Serializer\*
/**
* Demo\DataBundle\Entity\Attributes
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="Demo\DataBundle\Entity\AttributesRepository")
*
* #ExclusionPolicy("all")
*/
class Attributes
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*
* #Expose
*/
private $id;
/**
* #var string $attributeName
*
* #ORM\Column(name="attribute_name", type="string", length=255)
*
* #Expose
*/
private $attributeName;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set attributeName
*
* #param string $attributeName
* #return Attributes
*/
public function setAttributeName($attributeName)
{
$this->attributeName = $attributeName;
return $this;
}
/**
* Get attributeName
*
* #return string
*/
public function getAttributeName()
{
return $this->attributeName;
}
}
You will notice a couple of annotation settings. First we set #ExclusionPolicy("all") then we manually set which object we want to #Expose to the API. You can find out more about this here and a list of JMS Serializer annotations
Now lets move on to a simple controller:
<?php
namespace Demo\DataBundle\Controller;
use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\Controller\Annotations as Rest; //Lets use annotations for our FOSRest config
use FOS\RestBundle\Routing\ClassResourceInterface;
use FOS\Rest\Util\Codes;
use Symfony\Component\HttpFoundation\Request;
use Demo\DataBundle\Entity\Attributes;
class AttributesController extends FOSRestController implements ClassResourceInterface
{
/**
* Collection get action
* #var Request $request
* #return array
*
* #Rest\View()
*/
public function cgetAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('DemoDataBundle:Attributes')->findAll();
return array(
'entities' => $entities,
);
}
}
This is a simple controller that will return everything.
Hopefully this helped. I think your error is coming from a bad setting related to the Serializer. Make sure your exposing some data.
I have a pretty standard Entity with the correct imports:
/**
* Budhaz\aMailerBundle\Entity\Instance
*
* #ORM\Table()
* #ORM\Entity
*/
class Instance {
use TimestampableEntity;
/** #ORM\Id #ORM\GeneratedValue #ORM\Column(type="integer") */
private $id;
...
}
But I would like to remove the createdAt (and updatedAt) from my form so the user don't and can't set them, so I remove it from the InstanceForm:
class InstanceType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('startAt')
->add('endAt')
//->add('createdAt')
//->add('updatedAt')
->add('campaign')
;
}
...
}
But now I have this error:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'createdAt' cannot be null
createdAt and updatedAt should automaticaly be set by Doctrine, but it stays null, anyone know why?
You have to set the values within the class manually. Then you can tell doctrine to set the new value before every update:
public function __construct() {
$this->setCreatedAt(new \DateTime());
$this->setUpdatedAt(new \DateTime());
}
/**
* #ORM\PreUpdate
*/
public function setUpdatedAtValue() {
$this->setUpdatedAt(new \DateTime());
}
app/config/config.yml
stof_doctrine_extensions:
orm:
default:
timestampable: true
You need to check if the bundle is installed. If not, run:
composer require stof/doctrine-extensions-bundle
It should create file: app/config/packages/stof_doctrine_extensions.yaml with the content:
stof_doctrine_extensions:
default_locale: en_US
orm:
default:
timestampable: true