Symfony2 :FOS:elastica populate fails for serializer with callback - symfony

I am using symfony LTS with master FOS:elastica and master jms_serializer.
Config
fos_elastica:
clients:
default: { host: %elastic_host%, port: %elastic_port% }
serializer:
callback_class: FOS\ElasticaBundle\Serializer\Callback
serializer: serializer
indexes:
c_search:
client: default
types:
adverts:
mappings:
id:
type: integer
user:
type: string
Media:
type: nested
properties:
urlMedia: ~
persistence:
driver: orm
model: WebSite\MyBundle\Entity\Advert
provider: ~
listener: ~
finder: ~
Populate
php app/console fos:elastica:populate
This command work without any problem before I added the lines below. When I try to run "php app/console fos:elastica:populate" there is an infinite loop since I have added these lines:
serializer:
callback_class: FOS\ElasticaBundle\Serializer\Callback
serializer: serializer
Troubleshooting:
After this I made a simple request (without serialize because of my problem) like this on my controller :
public function testAction()
{
$repositoryManager = $this->container->get('fos_elastica.manager');
$repository = $repositoryManager->getRepository('WebSiteMyBundle:Advert');
$data = json_encode($repository->find('68200'));
return $this->render('WebSiteMyBundle:Default:test.html.twig', array(
'test'=> $data,
));
}
On my result test there is like 5 empty arrays. I know the result is good since there is normaly 5 response in my raw request but I can't find the solution to show the real content if anyone have an idea.

Ok, I was right in my comment, this issue was related to serializer and is quite logical.
Actually, if you do not specify anything, elastic will index every property and every relation in cascade which is a problem when having some circular references.
Here is what you could do to fix you problem :
First, add some properties in your group :
<?php
namespace WebSite\MyBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as Serializer;
/**
* Advert
*
* #ORM\Table(name="advert")
*/
class Advert
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=55)
* #Serializer\Groups({"elastica"})
*/
private $title;
...
Then, add this in your config file :
fos_elastica:
clients:
default: { host: %elastic_host%, port: %elastic_port% }
serializer:
callback_class: FOS\ElasticaBundle\Serializer\Callback
serializer: serializer
indexes:
c_search:
client: default
types:
adverts:
serializer:
groups: [elastica]
mappings:
id:
type: integer
user:
type: string
Media:
type: nested
properties:
urlMedia: ~
persistence:
driver: orm
model: WebSite\MyBundle\Entity\Advert
provider: ~
listener: ~
finder: ~
Then, you shouldn't have any circular reference and only having title property in your elasticsearch index.
Good luck.

Related

Attempted to call an undefined method named "search" of class "FOS\ElasticaBundle\Repository"

I want to use search method from elastica repository but i got error
Attempted to call an undefined method named "search" of class "FOS\ElasticaBundle\Repository".
I use symfony 4 with fos elastica bundle, latest version. In repo i working find method but it don't return any results.
I want do search-as-you-type-autocomplete like here https://www.codevate.com/blog/14-implementing-search-as-you-type-autocomplete-with-elasticsearch-and-symfony
Controller:
/**
* #Route("/search")
*/
public function searchElastic(RepositoryManagerInterface $finder, Request $request){
$searchTerm = $request->query->get('s');
$searchTerm = htmlentities($searchTerm, ENT_QUOTES);
// $finder = $finder->getRepository(\App\Entity\User::class)->find($searchTerm);
// return new response(var_dump($finder[0]->getUsername()));
$completion = new Suggest\Completion('suggest', 'name_suggest');
$completion->setText($searchTerm);
$completion->setFuzzy(array('fuzziness' => 2));
/** var array of App\Entity\User */
$resultSet = $finder->getRepository(\App\Entity\User::class)->search((Query::create($completion)));
var_dump($resultSet);
$suggestions = array();
foreach ($resultSet->getSuggests() as $suggests) {
foreach ($suggests as $suggest) {
foreach ($suggest['options'] as $option) {
$suggestions[] = array(
'id' => $option['_source']['id'],
'username' => $option['_source']['username']
);
}
}
}
return new JsonResponse(array(
'suggestions' => $suggestions,
));
}
Config:
# Read the documentation: https://github.com/FriendsOfSymfony/FOSElasticaBundle/blob/master/Resources/doc/setup.md
fos_elastica:
clients:
default: { host: localhost, port: 9200 }
# indexes:
# app: ~
indexes:
app:
client: default
#FOR AUTOCOMPLETE
settings:
index:
analysis:
analyzer:
name_analyzer:
type: custom
tokenizer: standard
filter: [standard, lowercase, asciifolding, elision]
#END FOR AUTOCOMPLETE
types:
user:
properties:
# username: ~
# username:
name_suggest:
# MAPPINGS ADDED FOR AUTOCOMPLETE
type: completion
analyzer: name_analyzer
search_analyzer: name_analyzer
# payloads: true
id:
type: keyword
username:
type: keyword
#MAPPINGS ADDED FOR AUTOCOMPLETE
persistence:
# the driver can be orm, mongodb, phpcr or propel
# listener and finder are not supported by
# propel and should be removed
driver: orm
model: App\Entity\User
provider: ~
listener: ~
finder: ~
User entity
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\UserInterface;
use App\Repository\UserRepository;
use Elastica\Search;
/**
* #UniqueEntity(fields="email", message="Email already taken")
* #UniqueEntity(fields="username", message="Username already taken")
* #ORM\Entity(repositoryClass="App\Repository\UserRepository")
* #Search(repositoryClass="AppBundle\SearchRepository\PropositionRepository")
*/
class User implements UserInterface
{
Please help, i'm beginner in elastica.
UPADTE:
Now i get this error.
Cannot autowire argument $finder of "App\Controller\DevController::searchElastic2()": it references class "FOS\ElasticaBundle\Doctrine\RepositoryManager" but no such service exists. Try changing the type-hint to "FOS\ElasticaBundle\Manager\RepositoryManagerInterface" instead.
UPDATE:
Argument 1 passed to App\Repository\UserRepository::__construct() must implement interface Symfony\Bridge\Doctrine\RegistryInterface, instance of FOS\ElasticaBundle\Finder\TransformedFinder given, called in C:\xampp\htdocs\projects\symfonysite\vendor\friendsofsymfony\elastica-bundle\src\Manager\RepositoryManager.php on line 101
UPDATE:
UserRepository.php a link
User.php entity a link
Controller a link
**Update: **
I don't get it. Tutorial in link reqire search function which is not in my version, and find function which work for me find only one resuly. Here's simple code which work for me, but find one result.
/**
* #Route("/search")
*/
public function searchElastic(RepositoryManagerInterface $finder, Request $request){
$searchTerm = $request->query->get('s');
$searchTerm = htmlentities($searchTerm, ENT_QUOTES);
$finder = $finder->getRepository(\App\Entity\User::class)->find($searchTerm);
return new response(var_dump($finder[0]->getUsername())); //i tried changing index to 1 but always it return undefined offset
The Search annotation support has been removed the a look to this merged PR , as the repository should be no more accessed through the Bundle:Entity notation, but requesting index/type.
To use the custom repository specify it in the mapping for your user just decalre it under your fos_elastica:
fos_elastica:
...
indexes:
app:
client: default
types:
user:
properties:
# your properties
persistence:
...
repository: App\Repository\UserRepository
Then the custom queries will be available when using the repository returned from the manager:
use FOS\ElasticaBundle\Repository;
class UserRepository extends Repository
{
...
function search(RepositoryManagerInterface $finder, Request $request)
{
/** var FOS\ElasticaBundle\Manager\RepositoryManagerInterface */
$repositoryManager = $finder;
/** var FOS\ElasticaBundle\Repository */
$repository = $repositoryManager->getRepository(AppEntityUser::class);
/** var array of Acme\UserBundle\Entity\User */
$users = $repository->search('bob');
....

Empty Dashboard Symfony3 sonata adminBundle

Faced the problem of setting up the admin panel. I do everything according to the documentation, there are no errors, Dashboard opens and everything is empty. The project is simple as a door - the simplest blog. Nothing shows up - neither the names of categories nor posts. The whole brain broke itself.
config.yml
imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: services.yml }
# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
locale: en
framework:
#esi: ~
translator: { fallbacks: [en] }
secret: '%secret%'
router:
resource: '%kernel.project_dir%/app/config/routing.yml'
strict_requirements: ~
form: ~
csrf_protection: ~
validation: { enable_annotations: true }
#serializer: { enable_annotations: true }
templating:
engines: ['twig']
default_locale: '%locale%'
trusted_hosts: ~
session:
# https://symfony.com/doc/current/reference/configuration/framework.html#handler-id
handler_id: session.handler.native_file
save_path: '%kernel.project_dir%/var/sessions/%kernel.environment%'
fragments: ~
http_method_override: true
assets: ~
php_errors:
log: true
# Twig Configuration
twig:
debug: '%kernel.debug%'
strict_variables: '%kernel.debug%'
# Doctrine Configuration
doctrine:
dbal:
driver: pdo_mysql
host: '%database_host%'
port: '%database_port%'
dbname: '%database_name%'
user: '%database_user%'
password: '%database_password%'
charset: UTF8
# if using pdo_sqlite as your database driver:
# 1. add the path in parameters.yml
# e.g. database_path: '%kernel.project_dir%/var/data/data.sqlite'
# 2. Uncomment database_path in parameters.yml.dist
# 3. Uncomment next line:
#path: '%database_path%'
orm:
auto_generate_proxy_classes: '%kernel.debug%'
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: true
# Swiftmailer Configuration
swiftmailer:
transport: '%mailer_transport%'
host: '%mailer_host%'
username: '%mailer_user%'
password: '%mailer_password%'
spool: { type: memory }
#Cache
doctrine_cache:
providers:
my_markdown_cache:
type: file_system
file_system:
directory: /tmp/doctrine_cache
sonata_admin:
title: My Blog Admin
sonata_block:
default_contexts: [cms]
blocks:
sonata.admin.block.admin_list:
contexts: [admin]
services.yml
parameters:
#parameter_name: value
services:
# default configuration for services in *this* file
_defaults:
# automatically injects dependencies in your services
autowire: true
# automatically registers your services as commands, event subscribers, etc.
autoconfigure: true
# this means you cannot fetch services directly from the container via $container->get()
# if you need to do this, you can override this setting on individual services
public: false
# makes classes in src/AppBundle available to be used as services
# this creates a service per class whose id is the fully-qualified class name
AppBundle\:
resource: '../../src/AppBundle/*'
# you can exclude directories or files
# but if a service is unused, it's removed anyway
exclude: '../../src/AppBundle/{Entity,Repository,Tests}'
# controllers are imported separately to make sure they're public
# and have a tag that allows actions to type-hint services
AppBundle\Controller\:
resource: '../../src/AppBundle/Controller'
public: true
tags: ['controller.service_arguments']
# add more services, or override services that need manual wiring
# AppBundle\Service\ExampleService:
# arguments:
# $someArgument: 'some_value'
services:
app.admin.category:
class: AppBundle\Admin\CategoryAdmin
arguments: [~, AppBundle\Entity\Category, ~]
tags:
- { name: sonata.admin, manager_type: orm, label: Category }
public: true
app.admin.articles:
class: AppBundle\Admin\ArticlesAdmin
arguments: [~, AppBundle\Entity\Articles, ~]
tags:
- { name: sonata.admin, manager_type: orm, label: Blog post }
public: true
CategoryAdmin class
namespace AppBundle\Admin;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Show\ShowMapper;
class CategoryAdmin extends AbstractAdmin
{
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper->add('name', 'text', array('label' => 'Название'));
}
protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
$datagridMapper->add('name');
}
protected function configureListFields(ListMapper $listMapper)
{
$listMapper->addIdentifier('name');
}
protected function configureShowFields(ShowMapper $showMapper)
{
$showMapper
->add('name');
}
}
Category Entity Class
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Category
*
* #ORM\Table(name="category")
* #ORM\Entity(repositoryClass="AppBundle\Repository\CategoryRepository")
*/
class Category
{
/**
* #ORM\OneToMany(targetEntity="Articles", mappedBy="category")
*/
private $blogPosts;
public function __construct()
{
$this->blogPosts = new ArrayCollection();
}
public function getBlogPosts()
{
return $this->blogPosts;
}
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
*
* #return Category
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
The problem is solved. The solution was not in the documentation for the bundle but in the documentation of the symphony

Error: doctrine.mongodb:generate:document No bundle Bundle was found with Symfony3

Error: doctrine.mongodb:generate:document No bundle Bundle was found with Symfony3.
c:\Bitnami\wampstack-5.6.20-0\apache2\htdocs\sym\patmonS1>php bin/console doctrine:mongodb:generate:document PatmonBundle:Product
PHP Warning: Module 'mongo' already loaded in Unknown on line 0
[Symfony\Component\Console\Exception\RuntimeException]
The "--filter" option does not exist.
config.tml
doctrine_mongodb:
connections:
default:
server: "%mongodb_server%"
options: {}
default_database: hello_%kernel.environment%
document_managers:
default:
mappings:
PatmonBundle: ~
#filters:
# filter-name:
# class: Class\Example\Filter\ODM\ExampleFilter
# enabled: true
metadata_cache_driver: array # array, apc, xcache, memcache
C:\Bitnami\wampstack-5.6.20-0\apache2\htdocs\sym\patmonS1\app\config\services.yml
services:
mongo_client:
class: MongoClient
# if using a username and password
arguments: ['mongodb://%mongodb_username%:%mongodb_password%#%mongodb_host%:27017']
session.handler.mongo:
class: Symfony\Component\HttpFoundation\Session\Storage\Handler\MongoDbSessionHandler
arguments: ['#mongo_client', '%mongo.session.options%']
C:\Bitnami\wampstack-5.6.20-0\apache2\htdocs\sym\patmonS1\app\config\parameters.yml
parameters:
mongodb_server: mongodb://localhost:27017
mongodb_username: username
mongodb_password: password
mongodb_host: localhost
mongo.session.options:
db_name: mdb_patmonS1
collection: session
C:\Bitnami\wampstack-5.6.20-0\apache2\htdocs\sym\patmonS1\src\Pat\monBundle\Document\Product.php
<?php
namespace Pat\monBundle\Document;
// http://symfony.com/doc/current/bundles/DoctrineMongoDBBundle/index.html
// http://symfony.com/doc/current/bundles/DoctrineMongoDBBundle/index.html#cookbook-mongodb-field-types
// http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/basic-mapping.html
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
//use Doctrine\ODM\MongoDB\Mapping\Annotations\Document; with annotation #Document
/**
* #MongoDB\Document
*/
class Product
{
/**
* #MongoDB\Id
*/
protected $id;
/**
* #MongoDB\Field(type="string")
*/
protected $name;
/**
* #MongoDB\Field(type="float")
*/
protected $price;
}
Just realized, that such a command does not exist in mongodb. I am new with mongodb. Nevertheless, exists command:
php bin/console doctrine:mongodb:generate:documents PatmonBundle
http://symfony.com/doc/current/bundles/DoctrineMongoDBBundle/index.html

Gedmo Doctrine Extensions - Sluggable + Translatable Yaml Configuration

I'm trying to translate entities with gedmo doctrine extensions.
https://github.com/Atlantic18/DoctrineExtensions
I'm using yml as orm mapping file (auto generating entities).
orm.yml:
CS\ContentBundle\Entity\Post:
type: entity
table: posts
repositoryClass: CS\ContentBundle\Entity\PostRepository
gedmo:
soft_deleteable:
field_name: deleted_at
translation:
locale: locale
fields:
id:
type: integer
length: 11
id: true
generator:
strategy: AUTO
title:
type: string
length: 500
gedmo:
- translatable
slug:
type: string
length: 500
gedmo:
translatable: {}
slug:
separator: -
fields:
- title
I can translate the title without a problem. But slug is not working...
Normally, on default language (tr), slug auto generated without any generation process by me.
Entity file:
<?php
namespace CS\ContentBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Translatable\Translatable;
use Gedmo\Mapping\Annotation as Gedmo;
use APY\DataGridBundle\Grid\Mapping as GRID;
/**
* Post
* #Gedmo\SoftDeleteable(fieldName="deleted_at", timeAware=false)
* #GRID\Source(columns="id,title,is_active,created_at,updated_at")
*/
class Post implements Translatable
{
/**
* #var integer
*/
private $id;
/**
* #var string
* #Gedmo\Translatable
* #GRID\Column(title="Başlık", filterable=true)
*/
private $title;
/**
* #var string
* #Gedmo\Translatable
*/
private $slug;
/**
* #Gedmo\Locale
*/
private $locale;
public function setLocale($locale)
{
$this->locale = $locale;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set title
*
* #param string $title
* #return Post
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* #return string
*/
public function getTitle()
{
return $this->title;
}
/**
* Set slug
*
* #param string $slug
* #return Post
*/
public function setSlug($slug)
{
$this->slug = $slug;
return $this;
}
/**
* Get slug
*
* #return string
*/
public function getSlug()
{
return $this->slug;
}
}
There is a part in documentation:
https://github.com/Atlantic18/DoctrineExtensions/blob/master/doc/sluggable.md#using-translationlistener-to-translate-our-slug
I don't know how to apply these listeners.
What should i do to translate the slug automatically?
EDIT
My config.yml for doctrine and stof_doctrine_extensions:
doctrine:
dbal:
default_connection: default
connections:
default:
driver: "%database_driver%"
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
mapping_types:
enum: string
orm:
auto_generate_proxy_classes: "%kernel.debug%"
auto_mapping: true
metadata_cache_driver: redis
query_cache_driver: redis
filters:
softdeleteable:
class: Gedmo\SoftDeleteable\Filter\SoftDeleteableFilter
enabled: true
mappings:
StofDoctrineExtensionsBundle: ~
gedmo_translatable:
type: annotation
prefix: Gedmo\Translatable\Entity
dir: "%kernel.root_dir%/../vendor/gedmo/doctrine-extensions/lib/Gedmo/Translatable/Entity"
alias: GedmoTranslatable # this one is optional and will default to the name set for the mapping
is_bundle: false
gedmo_tree:
type: annotation
prefix: Gedmo\Tree\Entity
dir: "%kernel.root_dir%/../vendor/gedmo/doctrine-extensions/lib/Gedmo/Tree/Entity"
alias: GedmoTree # this one is optional and will default to the name set for the mapping
is_bundle: false
stof_doctrine_extensions:
default_locale: "%locale%"
translation_fallback: true
orm:
default:
tree: true
sluggable: true
translatable: true
timestampable: true
softdeleteable: true
After a bit of struggling, I think I've managed to find a solution to your problem. Let's get down to business.
First of all, I've noticed you're using StofDoctrineExtensionsBundle which is a wrapper of the Gedmo Doctrine2 extensions.
It might have seemed easier to install/use but in the long run it complicates matters. In this case, for example, in order to solve your problem you have to modify listeners and with that bundle the only solution I can come up with is to hack the code and change the priority of the service manually. This leads to the first solution:
First solution: hack the bundle (not a good one)
The services can be found in
StofDoctrineExtensionsBundle/Resources/config/listeners.xml
You need to find and modify the sluggable service and increase its priority. That way, this service will execute before the translatable service. The slug would be created first and translatable would store it nicely.
Modification (haven't tried it though I think it might work):
<service id="stof_doctrine_extensions.listener.sluggable" class="%stof_doctrine_extensions.listener.sluggable.class%" public="false">
<tag name="kernel.cache_warmer" priority="1" />
<call method="setAnnotationReader">
<argument type="service" id="annotation_reader" />
</call>
</service>
However, I don't like this solution. To be honest, I don't like wrappers. I'm going to give you another solution that I find more satisfactory (and I tried it and works).
Second solution (and the best one)
First off, get rid of StofDoctrineExtensionsBundle. Secondly, install Gedmo Doctrine2 extensions (how to do it here).
You'll notice that in order to install the extensions you had to create a file in your bundle containing the necessary services. That is good. Go to that file and modify the priority for the sluggable service:
gedmo.listener.sluggable:
class: Gedmo\Sluggable\SluggableListener
tags:
- { name: doctrine.event_subscriber, connection: default, priority: 1 }
calls:
- [ setAnnotationReader, [ #annotation_reader ] ]
And now it is ready.
These are my yml and php for the entity Post (I think they are really similar to yours but can differ):
YML
DSG\AcmeBundle\Entity\Post:
type: entity
table: posts
gedmo:
soft_deleteable:
field_name: deleted_at
translation:
locale: locale
fields:
id:
type: integer
length: 11
id: true
generator:
strategy: AUTO
title:
type: string
length: 255
gedmo:
- translatable
slug:
type: string
length: 255
unique: true
gedmo:
translatable: {}
slug:
separator: _
style: camel
fields:
- title
And the PHP
namespace DSG\AcmeBundle\Entity;
use Gedmo\Translatable\Translatable;
class Post implements Translatable
{
/**
* #var integer
*/
private $id;
/**
* #var string
*/
private $title;
/**
* #var string
*/
private $slug;
/**
* #var string
*/
private $locale;
public function setTranslatableLocale($locale)
{
$this->locale = $locale;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set title
*
* #param string $title
* #return Post
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* #return string
*/
public function getTitle()
{
return $this->title;
}
/**
* Set slug
*
* #param string $slug
* #return Post
*/
public function setSlug($slug)
{
$this->slug = $slug;
return $this;
}
/**
* Get slug
*
* #return string
*/
public function getSlug()
{
return $this->slug;
}
}
When you create and entity and store it in the database, it will create the slug and store the title and the slug in the translation table (if you change the locale).
If you try:
$em = $this->getDoctrine()->getEntityManager();
$article = new Post();
$article->setTitle('the title');
$em->persist($article);
$em->flush();
$article = $this->getDoctrine()->getRepository('DSGMDayBundle:Post')->find(1);
$article->setTitle('my title in de');
$article->setTranslatableLocale('de_de'); // change locale
$em->persist($article);
$em->flush();
You'll see that your translation table gets two rows, one for the title and the other for the slug for the local de_de.
Hope it helps and kind regards.
Something weird to me : Your ORM config by entity is done in 2 files (yaml and annotation) ?
Listeners look to be well loaded, in the proper order. Maybe it's the entity field config in orm.yml. Try to invert translatable and sluggable on the field slug:
CS\ContentBundle\Entity\Post:
type: entity
table: posts
repositoryClass: CS\ContentBundle\Entity\PostRepository
gedmo:
soft_deleteable:
field_name: deleted_at
translation:
locale: locale
fields:
id:
type: integer
length: 11
id: true
generator:
strategy: AUTO
title:
type: string
length: 500
gedmo:
- translatable
slug:
type: string
length: 500
gedmo:
slug:
separator: -
fields:
- title
translatable: {}
Your configurations is look like correct. However, did you try to update vendors? Maybe some files may be corrupted.
If update process does not work, could you full compare configurations with mine:
doctrine:
dbal:
driver: "%database_driver%"
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
orm:
auto_generate_proxy_classes: "%kernel.debug%"
auto_mapping: true
dql:
string_functions:
GroupConcat: DoctrineExtensions\Query\Mysql\GroupConcat
IF: DoctrineExtensions\Query\Mysql\IfElse
filters:
softdeleteable:
class: Gedmo\SoftDeleteable\Filter\SoftDeleteableFilter
enabled: true
mappings:
StofDoctrineExtensionsBundle: ~
gedmo_tree:
type: annotation
prefix: Gedmo\Tree\Entity
dir: "%kernel.root_dir%/../vendor/gedmo/doctrine-extensions/lib/Gedmo/Tree/Entity"
alias: GedmoTree
is_bundle: false
translatable:
type: annotation
alias: Gedmo
prefix: Gedmo\Translatable\Entity
# make sure vendor library location is correct
dir: "%kernel.root_dir%/../vendor/gedmo/doctrine-extensions/lib/Gedmo/Translatable/Entity"
And make sure that you do not override the gedmo.listener.translatable on your services.yml. If there is any code that overrides the default one, remove it. Default configuration:
gedmo.listener.translatable:
class: Gedmo\Translatable\TranslatableListener
tags:
- { name: doctrine.event_subscriber, connection: default }
calls:
- [ setAnnotationReader, [ #annotation_reader ] ]
- [ setDefaultLocale, [ %locale% ] ]
- [ setTranslationFallback, [ false ] ]
I use StofDoctrineExtensionsBundle for sluggable and translatable and had the same problem.
I have searched and tried a while and found a solution working for me:
Entity:
the slug field gets generated from the name field
use Gedmo\Mapping\Annotation as Gedmo;
use Gedmo\Translatable\Translatable;
/**
* #var string
*
* #Gedmo\Translatable
* #ORM\Column(name="name", type="string", length=150, unique=true)
*/
private $name;
/**
* #Gedmo\Translatable
* #Gedmo\Slug(fields={"name"}, updatable=true)
* #ORM\Column(type="string", unique=true)
*/
private $slug;
config.yml: here you have to set persist_default_translation: true
https://github.com/Atlantic18/DoctrineExtensions/issues/542#issuecomment-12983553
parameters:
locale: en
doctrine:
orm:
auto_generate_proxy_classes: '%kernel.debug%'
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: true
mappings:
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
gedmo_translator:
type: annotation
prefix: Gedmo\Translator\Entity
dir: "%kernel.root_dir%/../vendor/gedmo/doctrine-extensions/lib/Gedmo/Translator/Entity"
alias: GedmoTranslator # (optional) it will default to the name set for the mapping
is_bundle: false
stof_doctrine_extensions:
default_locale: '%locale%'
translation_fallback: true
persist_default_translation: true # I think this does the trick
orm:
default:
sluggable: true
translatable: true
DefaultController use ParamConverter for calling a query which returns correct entity for current locale
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
/**
* #Route("/entry/{slug}", name="entry_detail")
* #ParamConverter("entry", class="AppBundle:Entry", options={"repository_method" = "findOneByCriteria"})
*/
public function entryDetailAction(Request $request, Entry $entry)
{
return $this->render('frontend/entry.html.twig', [
'entry' => $entry,
]);
}
Entity Repository with the query method to return entity
/**
* Find an entry by criteria
* Need this special function, because of translatable
* https://github.com/stof/StofDoctrineExtensionsBundle/issues/232
*
* #param $params
* #return mixed
*/
public function findOneByCriteria(array $params)
{
$query = $this->createQueryBuilder('e');
$i = 0;
foreach ($params as $column => $value) {
if ($i < 1) {
$query->where("e.$column = :$column");
} else {
$query->andWhere("e.$column = :$column");
}
$query->setParameter($column, $value);
$i++;
}
$query = $query->getQuery();
$query->setHint(\Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER, 'Gedmo\\Translatable\\Query\\TreeWalker\\TranslationWalker');
return $query->getOneOrNullResult();
}
I hope this example helps someone.

Symfony2 FOS User not a valid entity

im not sure what ive done wrong here.
I am following the instruction on how to install the fos bundle and have come across a problem.
I am getting the following error:
PHP Fatal error: Uncaught exception
'Doctrine\ORM\Mapping\MappingException' with message 'Class
RS\Entity\User is not a valid entity or mapped super class.' in
PATH\vendor\doctrine\lib\Doctrine\ORM\Mapping\MappingException.php:142
My user class is in /src/RS/Entity/User.php
And i have'RS' => __DIR__.'/../vendor/reportsuite/src'in app/autoload.php
The class is
<?php
// /src/RS/Entity/User.php
namespace RS\Entity;
use FOS\UserBundle\Entity\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="fos_user")
*/
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
public function __construct()
{
parent::__construct();
// your own logic
}
}
As far as i can tell this is a mapped entity, unless im missing something?
Ive also tried creating the entity in by bundle and another bundle like Acme/UserBundle/Entity/User.php
# Doctrine Configuration
doctrine:
dbal:
default_connection: default
connections:
default:
dbname: axpdb
user: %database_user%
password: %database_password%
host: %database_host%
port: %database_port%
charset: UTF8
reportsuite:
dbname: reportsuite
user: %database_user%
password: %database_password%
host: %database_host%
port: %database_port%
charset: UTF8
orm:
entity_managers:
default:
connection: default
mappings:
ReportSuiteMainMenuBundle: ~
reportsuite:
connection: reportsuite
mappings:
# Security
jms_security_extra:
secure_controllers: true
secure_all_services: false
# FOS User Config
#fos_user:
# db_driver: orm
# firewall_name: main
# user_class: RS\Entity\User
# model_manager_name: reportsuite
I have 2 databases that I need to access and I have commented out the fos stuff so i can continue working.
Did You checkd a namespace ?
I think it should be:
namespace Namespace\YourBundle\Entity
You can use entites from all of Your bundles.
Run
touch Entity/*
and you are OK.
Had this problem - don't forget the annotation * #ORM\Entity like below:
/**
* Powma\ServiceBundle\Entity\User
*
* #ORM\Entity
* #ORM\Table(name="users")
*/

Resources