I'm building my first Symfony bundle. I want to use Models instead of Entity so I have a directory Model which contains only one model. Also I have a mapping for this model which is located in Resources/config/doctrine/mymodel.orm.yaml. When I run /bin/console doctrine:migration:diff it says No changes detected in your mapping information
Here's is my model
class MyModel
{
/**
* #var mixed
*/
private $id;
/**
* #var string
*/
private $user;
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* #return null|string
*/
public function getUser(): ?string
{
return $this->user;
}
/**
* #param string $user
*
*/
public function setUser(string $user): self
{
$this->user = $user;
return $this;
}
and the mymodel.orm.yaml
MyNamespace\MyBundle\Model\MyModel:
type: mappedSuperclass
repositoryClass: MyNamespace\MyBundle\Repository\MyModelRepository
id:
id:
type: integer
generator:
strategy: AUTO
fields:
user:
type: string
What I'm missing here?
UPDATE
I'm using symfony 4.2.3
Here's my doctrine.yaml
parameters:
env(DATABASE_URL): ''
doctrine:
dbal:
driver:
charset: utf8
default_table_options:
charset: utf8
collate: utf8_unicode_ci
url: '%env(resolve:DATABASE_URL)%'
orm:
auto_generate_proxy_classes: '%kernel.debug%'
entity_managers:
default:
auto_mapping: true
mappings:
MyBundle: ~
Related
I have just put in place mongodb with symfony4.1.
When I want to persist a simple User in the database, I got this error (title) :
Uncaught PHP Exception Doctrine\Common\Persistence\Mapping\MappingException: "The class 'App\Document\User' was not found in the chain configured namespaces
Here my controller :
/**
* #Route("/mongoTest")
* #Method("GET")
* #param DocumentManager $dm
* #return JsonResponse
*/
public function mongoTest(DocumentManager $dm)
{
$user = new User();
$user->setEmail("hello#medium.com");
$user->setFirstname("Matt");
$user->setLastname("Matt");
$user->setPassword(md5("123456"));
$dm->persist($user);
$dm->flush();
return new JsonResponse(array('Status' => 'OK'));
}
Config :
doctrine_mongodb:
connections:
default:
server: "%mongodb_server%"
options: {}
default_database: "%mongodb_database_name%"
document_managers:
default:
auto_mapping: true
default_commit_options: ~
Here my Document :
<?php
namespace App\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
/**
* #MongoDB\Document
*/
class User
{
/**
* #MongoDB\Id
*/
protected $id;
/**
* #MongoDB\Field(type="string")
*/
protected $firstname;
/**
* #MongoDB\Field(type="string")
*/
protected $lastname;
/**
* #MongoDB\Field(type="string")
*/
protected $email;
/**
* #MongoDB\Field(type="string")
*/
protected $password;
/**
* #MongoDB\Field(type="date")
*/
protected $create_date;
// ...
}
Does anyone have an idea ?
Thanks a lot !!
I found the answer :
I do not use bundles.
doctrine_mongodb:
connections:
default:
server: "%mongodb_server%"
options: {}
default_database: "%mongodb_database_name%"
document_managers:
default:
mappings:
# ...
App:
type: annotation
dir: "%kernel.root_dir%/../src/Document"
is_bundle: false
prefix: App\Document
alias: App
default_commit_options: ~
I've made some changes to my doctrine Entities and need to update the database and got the following error.
$ php bin/console doctrine:schema:update -vvv
[Doctrine\DBAL\Schema\SchemaException (30)]
There is no column with name 'fleet_no' on table 'fuelData'.
Exception trace:
() at /home/sarah/workspace/telematics_tracker/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaException.php:86
Doctrine\DBAL\Schema\SchemaException::columnDoesNotExist() at /home/sarah/workspace/telematics_tracker/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Table.php:671
Doctrine\DBAL\Schema\Table->getColumn() at /home/sarah/workspace/telematics_tracker/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php:711
Doctrine\DBAL\Platforms\MySqlPlatform->getPreAlterTableAlterPrimaryKeySQL() at /home/sarah/workspace/telematics_tracker/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php:639
Doctrine\DBAL\Platforms\MySqlPlatform->getPreAlterTableIndexForeignKeySQL() at /home/sarah/workspace/telematics_tracker/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php:621
Doctrine\DBAL\Platforms\MySqlPlatform->getAlterTableSQL() at /home/sarah/workspace/telematics_tracker/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaDiff.php:199
Doctrine\DBAL\Schema\SchemaDiff->_toSql() at /home/sarah/workspace/telematics_tracker/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaDiff.php:126
Doctrine\DBAL\Schema\SchemaDiff->toSaveSql() at /home/sarah/workspace/telematics_tracker/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/SchemaTool.php:883
Doctrine\ORM\Tools\SchemaTool->getUpdateSchemaSql() at /home/sarah/workspace/telematics_tracker/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php:115
Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand->executeSchemaCommand() at /home/sarah/workspace/telematics_tracker/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/AbstractCommand.php:65
Doctrine\ORM\Tools\Console\Command\SchemaTool\AbstractCommand->execute() at /home/sarah/workspace/telematics_tracker/vendor/doctrine/doctrine-bundle/Command/Proxy/UpdateSchemaDoctrineCommand.php:50
Doctrine\Bundle\DoctrineBundle\Command\Proxy\UpdateSchemaDoctrineCommand->execute() at /home/sarah/workspace/telematics_tracker/vendor/symfony/symfony/src/Symfony/Component/Console/Command/Command.php:261
Symfony\Component\Console\Command\Command->run() at /home/sarah/workspace/telematics_tracker/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:839
Symfony\Component\Console\Application->doRunCommand() at /home/sarah/workspace/telematics_tracker/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:185
Symfony\Component\Console\Application->doRun() at /home/sarah/workspace/telematics_tracker/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php:80
Symfony\Bundle\FrameworkBundle\Console\Application->doRun() at /home/sarah/workspace/telematics_tracker/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:116
Symfony\Component\Console\Application->run() at /home/sarah/workspace/telematics_tracker/bin/console:27
Which is correct as such, since I have a column called 'fleetNo' but not one called 'fleet_no' in the 'fuelData' table. This was not one of the changes that I made either.
I have searched the project directory for any other instance of 'fleet_no' but there aren't any.
Below is a copy of the fuelData entity.
<?php
// src/AppBundle/Entity/FuelData.php
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\Column;
/**
* #ORM\Entity
* #ORM\Table(name="fuelData")
*
*
*/
class FuelData
{
/**
* #Assert\NotBlank()
* #ORM\Column(type="string")
* #ORM\Id
*/
public $fleetNo;
/**
* #Assert\NotBlank()
* #ORM\Column(type="string")
*/
public $startDate;
/**
* #Assert\NotBlank()
* #ORM\Column(type="string")
*/
public $endDate;
/**
* Set fleetNo
*
* #param string $fleetNo
*
* #return FuelData
*/
public function setFleetNo($fleetNo)
{
$this->fleetNo = $fleetNo;
return $this;
}
/**
* Get fleetNo
*
* #return string
*/
public function getFleetNo()
{
return $this->fleetNo;
}
/**
* Set startDate
*
* #param string $startDate
*
* #return FuelData
*/
public function setStartDate($startDate)
{
$this->startDate = $startDate;
return $this;
}
/**
* Get startDate
*
* #return string
*/
public function getStartDate()
{
return $this->startDate;
}
/**
* Set endDate
*
* #param string $endDate
*
* #return FuelData
*/
public function setEndDate($endDate)
{
$this->endDate = $endDate;
return $this;
}
/**
* Get endDate
*
* #return string
*/
public function getEndDate()
{
return $this->endDate;
}
}
The only thing that I can think of is that the column name is being converted from camelCase to underscore by something.
Is there something that I have missed or should I be looking in a different place?
Below are the relevant parts of my config.yml:
doctrine:
dbal:
default_connection: maxdb
connections:
maxdb:
driver: pdo_mysql
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
foxdb:
driver: pdo_mysql
host: "%database_host2%"
port: "%database_port2%"
dbname: "%database_name2%"
user: "%database_user2%"
password: "%database_password2%"
charset: UTF8
orm:
auto_generate_proxy_classes: "%kernel.debug%"
default_entity_manager: maxem
entity_managers:
maxem:
naming_strategy: doctrine.orm.naming_strategy.underscore
connection: maxdb
mappings:
AppBundle: ~
BWTCalendarBundle: ~
BWTFMBundle: ~
BWTHealthCheckBundle: ~
BWTSkytrackBundle: ~
BWTTelematicsBundle: ~
foxem:
naming_strategy: doctrine.orm.naming_strategy.underscore
connection: foxdb
mappings:
FoxBundle: ~
orm:
auto_generate_proxy_classes: "%kernel.debug%"
default_entity_manager: maxem
entity_managers:
maxem:
naming_strategy: doctrine.orm.naming_strategy.underscore
As you can see in your config you are using the UNDERSCORE naming strategy for the orm so that is what converts your field name.
You should do
app/console doctrine:schema:drop
to start off from clean then try changing the naming strategy.
In the end if you want to be sure to have the exact column name you want just add the name parameter to the colum annotation like so:
/**
* #Assert\NotBlank()
* #ORM\Column(type="string" name="fleetNo")
* #ORM\Id
*/
public $fleetNo;
Did any one ever find an solution for this issue?
I'm having the same issue.
My config.yml:
# Doctrine Configuration
doctrine:
dbal:
driver: "%database_server%"
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.root_dir%/data/data.db3"
# 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
#Gedmo Package extension for Symfony and Doctrine
mappings:
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
gedmo_sortable:
type: annotation
prefix: Gedmo\Sortable\Entity
dir: "%kernel.root_dir%/../vendor/gedmo/doctrine-extensions/lib/Gedmo/Sortable/Entity"
alias: GedmoTree
is_bundle: false
[...]
stof_doctrine_extensions:
default_locale: "%locale%"
translation_fallback: true
orm:
default:
timestampable: true
blameable: true
My doctrine_extension.yml is included in the config file:
services:
extension.listener:
class: Omega\HomeBundle\Library\Listener\DoctrineExtensionListener
calls:
- [ setContainer, [#service_container]]
tags:
# loggable hooks user username if one is in security context
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
# Doctrine Extension listeners to handle behaviors
gedmo.listener.tree:
class: Gedmo\Tree\TreeListener
tags:
- { name: doctrine.event_subscriber, connection: default }
calls:
- [ setAnnotationReader, [ #annotation_reader ] ]
gedmo.listener.sortable:
class: Gedmo\Sortable\SortableListener
tags:
- { name: doctrine.event_subscriber, connection: default }
calls:
- [ setAnnotationReader, [ #annotation_reader ] ]
gedmo.listener.timestampable:
class: Gedmo\Timestampable\TimestampableListener
tags:
- { name: doctrine.event_subscriber, connection: default }
calls:
- [ setAnnotationReader, [ #annotation_reader ] ]
gedmo.listener.loggable:
class: Gedmo\Loggable\LoggableListener
tags:
- { name: doctrine.event_subscriber, connection: default }
calls:
- [ setAnnotationReader, [ #annotation_reader ] ]
gedmo.listener.blameable:
class: Gedmo\Blameable\BlameableListener
tags:
- { name: doctrine.event_subscriber, connection: default }
calls:
- [ setAnnotationReader, [ #annotation_reader ] ]
- [ setUserValue, [ #security.token_storage ] ]
I created myself an trait to handle the created, updated, updated_by and createdby fields:
namespace HomeBundle\Traits;
use Doctrine\ORM\Mapping as ORM;
use Omega\UserBundle\Entity\Users;
use Gedmo\Mapping\Annotation as Gedmo;
trait LogableTrait
{
/**
* #var Users
* #Gedmo\Blameable(on="create")
* #ORM\ManyToOne(targetEntity="UserBundle\Entity\Users")
* #ORM\JoinColumn(name="log_created_by", referencedColumnName="id")
*/
protected $CreatedBy;
/**
* #var Users
* #Gedmo\Blameable(on="update")
* #ORM\ManyToOne(targetEntity="UserBundle\Entity\Users")
* #ORM\JoinColumn(name="log_updated_by", referencedColumnName="id")
*/
protected $UpdatedBy;
/**
* #Gedmo\Timestampable(on="create")
* #ORM\Column(name="created", type="datetime")
* #var \DateTime
*/
protected $created;
/**
* #Gedmo\Timestampable(on="create")
* #ORM\Column(name="updated", type="datetime")
* #var \DateTime
*/
protected $updated;
/**
* #return Users
*/
public function getCreatedBy ()
{
return $this->CreatedBy;
}
/**
* #param Users $CreatedBy
*
* #return $this
*/
public function setCreatedBy (Users $CreatedBy )
{
$this->CreatedBy = $CreatedBy;
return $this;
}
/**
* #return Users
*/
public function getUpdatedBy ()
{
return $this->UpdatedBy;
}
/**
* #param Users $UpdatedBy
*
* #return $this
*/
public function setUpdatedBy (Users $UpdatedBy )
{
$this->UpdatedBy = $UpdatedBy;
return $this;
}
}
But everytime that I use this Bundle I get:
The class 'Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage' was not found in the chain configured namespaces Gedmo\Tree\Entity, Gedmo\Sortable\Entity, JMS\JobQueueBundle\Entity, AccountingBundle\Entity, DocumentsBundle\Entity, EavBundle\Entity, HomeBundle\Entity, UserBundle\Entity, CustomerBundle\Entity, Jns\Bundle\XhprofBundle\Entity
I hope some body can help me.
for any one that Is having th same issue like me that the blamable feature is not working:
My solution was to implement the BlamableListener with an different approach:
namespace HomeBundle\Library;
use Doctrine\Common\NotifyPropertyChanged;
use Gedmo\Exception\InvalidArgumentException;
use Gedmo\Timestampable\TimestampableListener;
use Gedmo\Blameable\Mapping\Event\BlameableAdapter;
use Gedmo\Blameable\Mapping\Driver\Annotation;
/**
* The Blameable listener handles the update of
* dates on creation and update.
*
* #author Gediminas Morkevicius <gediminas.morkevicius#gmail.com>
* #license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
class BlameableListener extends TimestampableListener
{
protected $user;
/**
* Get the user value to set on a blameable field
*
* #param object $meta
* #param string $field
*
* #return mixed
*/
public function getUserValue($meta, $field)
{
if ($meta->hasAssociation($field)) {
if (null !== $this->user && ! is_object($this->user)) {
throw new InvalidArgumentException("Blame is reference, user must be an object");
}
$user = $this->user->getToken()->getUser();
if(!is_object($user))
{
return null;
}
return $user;
}
// ok so its not an association, then it is a string
if (is_object($this->user)) {
if (method_exists($this->user, 'getUsername')) {
return (string) $this->user->getUsername();
}
if (method_exists($this->user, '__toString')) {
return $this->user->__toString();
}
throw new InvalidArgumentException("Field expects string, user must be a string, or object should have method getUsername or __toString");
}
return $this->user;
}
/**
* Set a user value to return
*
* #param mixed $user
*/
public function setUserValue($user)
{
$this->user = $user;
}
/**
* {#inheritDoc}
*/
protected function getNamespace()
{
return __NAMESPACE__;
}
/**
* Updates a field
*
* #param object $object
* #param BlameableAdapter $ea
* #param $meta
* #param $field
*/
protected function updateField($object, $ea, $meta, $field)
{
$property = $meta->getReflectionProperty($field);
$oldValue = $property->getValue($object);
$newValue = $this->getUserValue($meta, $field);
//if blame is reference, persist object
if ($meta->hasAssociation($field) && $newValue) {
$ea->getObjectManager()->persist($newValue);
}
$property->setValue($object, $newValue);
if ($object instanceof NotifyPropertyChanged) {
$uow = $ea->getObjectManager()->getUnitOfWork();
$uow->propertyChanged($object, $field, $oldValue, $newValue);
}
}
}
adjust the service for the blamable:
gedmo.listener.blameable:
class: HomeBundle\Library\BlameableListener
tags:
- { name: doctrine.event_subscriber, connection: default }
calls:
- [ setAnnotationReader, [ #annotation_reader ] ]
- [ setUserValue, [ #security.token_storage ] ]
you need to copy the mapping library to the same location as the listener itself. Adjust the namespaces and it works. It seems that some structures changed in symfony 2.7 so the plugin no longer works out of the box.
If you want to update the updated_by field, you must specify the field so that when you update it, do so in updated_by. For example:
/**
* #var \DateTime $updated
*
* #Gedmo\Timestampable(on="update")
* #ORM\Column(type="datetime", nullable=true)
*/
protected $updated;
/**
* #var string $updatedBy
*
* #Gedmo\Blameable(on="update", field="updated")
* #ORM\Column(type="string", nullable=true)
*/
protected $updatedBy;
Pay attention to field="updated"
Just create DoctrineExtensionSubscriber
Manually tag the listeners
Gedmo\Loggable\LoggableListener:
tags:
- { name: doctrine_mongodb.odm.event_subscriber }
Create DoctrineExtensionSubscriber
<?php
namespace App\EventSubscriber;
use Gedmo\Blameable\BlameableListener;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
class DoctrineExtensionSubscriber implements EventSubscriberInterface
{
/**
* #var BlameableListener
*/
private $blameableListener;
/**
* #var TokenStorageInterface
*/
private $tokenStorage;
/**
* #var TranslatableListener
*/
private $translatableListener;
/**
* #var LoggableListener
*/
private $loggableListener;
public function __construct(
BlameableListener $blameableListener,
TokenStorageInterface $tokenStorage,
TranslatableListener $translatableListener,
LoggableListener $loggableListener
) {
$this->blameableListener = $blameableListener;
$this->tokenStorage = $tokenStorage;
$this->translatableListener = $translatableListener;
$this->loggableListener = $loggableListener;
}
public static function getSubscribedEvents()
{
return [
KernelEvents::REQUEST => 'onKernelRequest',
KernelEvents::FINISH_REQUEST => 'onLateKernelRequest'
];
}
public function onKernelRequest(): void
{
if ($this->tokenStorage !== null &&
$this->tokenStorage->getToken() !== null &&
$this->tokenStorage->getToken()->isAuthenticated() === true
) {
$this->blameableListener->setUserValue($this->tokenStorage->getToken()->getUser());
}
}
public function onLateKernelRequest(FinishRequestEvent $event): void
{
$this->translatableListener->setTranslatableLocale($event->getRequest()->getLocale());
}
}
I am trying to just display a list. My Supplier and Property list were displaying until I implemented the product list :(
Now I get this error with the Supplier and Property lists but not for the newly added product list:
Here is my app/config.yml:
imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: services.yml }
parameters:
sylius.locale: "%locale%"
framework:
#esi: ~
translator: { fallbacks: ["%locale%"] }
secret: "%secret%"
router:
resource: "%kernel.root_dir%/config/routing.yml"
strict_requirements: ~
form: ~
csrf_protection: ~
validation: { enable_annotations: true }
templating:
engines: ['twig']
#assets_version: SomeVersionScheme
default_locale: "%locale%"
trusted_hosts: ~
trusted_proxies: ~
session:
storage_id: session.storage.php_bridge
# handler_id set to null will use default session handler from php.ini
handler_id: ~
fragments: ~
http_method_override: true
# Twig Configuration
twig:
debug: "%kernel.debug%"
strict_variables: "%kernel.debug%"
form:
resources:
- 'SonataCoreBundle:Form:datepicker.html.twig'
# Assetic Configuration
assetic:
debug: "%kernel.debug%"
use_controller: false
#java: /usr/bin/java
node: /usr/bin/node
node_paths: [ /usr/lib/node_modules, %kernel.root_dir%/../node_modules ]
filters:
autoprefixer:
bin: %kernel.root_dir%/../node_modules/autoprefixer/autoprefixer
cssrewrite: ~
less:
apply_to: "\.less$"
bin: %kernel.root_dir%/../node_modules/less
uglifycss:
bin: %kernel.root_dir%/../node_modules/uglifycss
uglifyjs:
bin: %kernel.root_dir%/../node_modules/uglifyjs
#closure:
# jar: "%kernel.root_dir%/Resources/java/compiler.jar"
#yui_css:
# jar: "%kernel.root_dir%/Resources/java/yuicompressor-2.4.7.jar"
# Doctrine Configuration
doctrine:
dbal:
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%"
entity_managers:
default:
connection: default
auto_mapping: true
dql:
string_functions:
HS_CONCAT_ADDRESS: AppBundle\DQL\HSConcatAddress
# Swiftmailer Configuration
swiftmailer:
transport: "%mailer_transport%"
host: "%mailer_host%"
username: "%mailer_user%"
password: "%mailer_password%"
spool: { type: memory }
# FOS UserBundle Configuration
fos_user:
registration:
form:
type: hs_user_registration
db_driver: orm
firewall_name: main
user_class: AppBundle\Entity\User
service:
user_manager: app.security.user_manager
# Doctrine migration bundle Configuration
doctrine_migrations:
dir_name: %kernel.root_dir%/DoctrineMigrations
namespace: Application\Migrations
table_name: migration_versions
name: Application Migrations
# Sonata Admin Configuration
sonata_admin:
options:
use_select2: false # disable select2
title: App
title_logo: bundles/sonataadmin/logo_title.png
# Override default template
templates:
show: AppBundle:Admin/Backend:show.html.twig
edit: AppBundle:Admin/Backend:edit.html.twig
layout: AppBundle:Common/Admin:standard_layout.html.twig
security:
# handler: sonata.admin.security.handler.role
#sonata_intl:
# timezone:
# locales:
# en_GB: Europe/London
# default: Europe/London
# Sonata Block Configuration
sonata_block:
default_contexts: [cms]
blocks:
sonata.user.block.menu: # used to display the menu in profile pages
sonata.user.block.account: # used to display menu option (login option)
sonata.admin.block.admin_list:
contexts: [admin]
sonata.admin.block.search_result:
contexts: [admin]
knp_menu:
# use "twig: false" to disable the Twig extension and the TwigRenderer
twig:
template: knp_menu.html.twig
# if true, enables the helper for PHP templates
templating: false
# the renderer to use, list is also available by default
default_renderer: twig
# STOF Doctrine Extensions Configuration
stof_doctrine_extensions:
default_locale: %locale%
orm:
default:
translatable: true
sluggable: true
timestampable: true
a2lix_translation_form:
locale_provider: default # [1]
locales: ["%locale%"] # [1-a]
default_locale: "%locale%" # [1-b]
manager_registry: doctrine # [2]
# Sylius Archetype
sylius_archetype:
classes:
product:
subject: Sylius\Component\Product\Model\Product
attribute: Sylius\Component\Product\Model\Attribute
option: Sylius\Component\Product\Model\Option
archetype:
model: Sylius\Component\Product\Model\Archetype
repository: Sylius\Bundle\ResourceBundle\Doctrine\ORM\TranslatableEntityRepository
translatable:
targetEntity: Sylius\Component\Product\Model\ArchetypeTranslation
archetype_translation:
model: Sylius\Component\Product\Model\ArchetypeTranslation
sylius_product:
driver: doctrine/orm
classes:
product:
model: AppBundle\Entity\Product
controller: AppBundle\Controller\Backend\ProductController
form:
default: AppBundle\Form\Type\ProductType
translatable:
targetEntity: AppBundle\Entity\ProductTranslation
product_translation:
model: AppBundle\Entity\ProductTranslation
form:
default: AppBundle\Form\Type\ProductTranslationType
#sylius_resource:
# resources:
# app.backend:
# driver: doctrine/orm
# object_manager: default
# classes:
# controller: AppBundle\Controller\Backend\ResourceController
# model: AppBundle\Entity\Product
# Sylius Attribute
sylius_attribute:
driver: doctrine/orm
# Sylius Locale
sylius_locale:
driver: doctrine/orm
# Sylius Translation
sylius_translation:
default_mapping:
translatable:
field: translations
currentLocale: currentLocale
fallbackLocale: fallbackLocale
translation:
field: translatable
locale: locale
# Sylius Variation
sylius_variation:
driver: doctrine/orm
classes:
product:
variant:
model: AppBundle\Entity\ProductVariant
form: AppBundle\Form\Type\ProductVariantType
My admin class:
namespace AppBundle\Admin;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Form\FormMapper;
use Symfony\Component\EventDispatcher\Event;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Show\ShowMapper;
use Sonata\AdminBundle\Admin\AdminInterface;
use Sonata\AdminBundle\Route\RouteCollection;
use Sonata\AdminBundle\Form\Type;
use Sonata\AdminBundle\Validator\ErrorElement;
use AppBundle\Entity\Suppliers as Suppliers;
use AppBundle\Form\Type\CreateSupplierForm;
use Symfony\Component\DependencyInjection\ContainerInterface;
class SupplierAdmin extends Admin
{
/**
* {#inheritdoc}
*/
protected $baseRouteName = 'Admin\SupplierAdmin';
/**
* {#inheritdoc}
*/
protected $baseRoutePattern = 'supplier';
/**
* #var ContainerInterface
*/
private $container;
public function setContainer (ContainerInterface $container)
{
$this->container = $container;
}
/**
* #param \Sonata\AdminBundle\Show\ShowMapper $showMapper
*
* #return void
*/
protected function configureShowFields(ShowMapper $showMapper)
{
$showMapper
->with('Supplier Details')
->add('id')
->add('name')
->add('created')
->end();
if ($this->getSubject()->getType() == 'LPE') {
$showMapper->with('Property Expert')
->add('LpeFirstName', null, array('label' => 'First Name'))
->add('LpeLastName', null, array('label' => 'Last Name'))
->add('LpeEmail', null, array('label' => 'Email'))
->add('ContractType', null, array('label' => 'Type'))
->add('regions', 'entity', array(
'class' => 'AppBundle:Regions',
"multiple" => true,
'label' => 'Regions Covered'
))
->end();
}
}
/**
* #param \Sonata\AdminBundle\Datagrid\ListMapper $listMapper
*
* #return void
*/
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
->add('id')
->add('Type')
->addIdentifier('name')
->add('created', 'date', array(
'pattern' => 'dd/MM/Y # H:m',
'locale' => 'en_GB',
'timezone' => 'Europe/London',
))
// add custom action links
->add('_action', 'actions', array(
'actions' => array(
'show' => array(),
'delete' => array()
)
));
}
/**
* #param \Sonata\AdminBundle\Datagrid\DatagridMapper $datagridMapper
*
* #return void
*/
protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
$datagridMapper
->add('type', null, array(),
'choice',
array('choices' => Suppliers::getTypes()))
->add('name');
}
protected function configureRoutes(RouteCollection $collection)
{
parent::configureRoutes($collection);
$collection->add('create', 'create', array(
'_controller' => 'AppBundle:Backend/SupplierAdmin:createSupplier'
)
);
$collection->add('show', $this->getRouterIdParameter() . '/show', array(
'_controller' => 'AppBundle:Backend/SupplierAdmin:show',
)
);
$collection->add('delete', $this->getRouterIdParameter() . '/delete', array(
'_controller' => 'AppBundle:Backend/SupplierAdmin:delete',
)
);
}
/**
* #return array
*/
public function getBatchActions()
{
// Disable all batch actions for now
$actions = array();
return $actions;
}
/**
* {#inheritdoc}
*/
public function createQuery($context = 'list')
{
$query = parent::createQuery($context);
// Default Alias is "o"
$query->orderBy('o.id', 'DESC');
$query->setSortOrder('DESC');
return $query;
}
public function preUpdate($supplier)
{
$supplier->setDeleted(0);
return $supplier;
}
public function preCreate($supplier)
{
$supplier->setDeleted(0);
return $supplier;
}
}
And lastly my Supplier entity:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Suppliers
*
* #ORM\Table(
* name="suppliers",
* indexes={
* #ORM\Index(
* name="supplier_name", columns={"name"}
* )
* })
* #ORM\Entity
* #ORM\HasLifecycleCallbacks()
*/
class Suppliers
{
const TYPE_INTERNAL = 'internal';
const TYPE_EXTERNAL = 'external';
const TYPE_LPE = 'lpe';
protected static $types = array(
self::TYPE_INTERNAL => 'Internal',
self::TYPE_EXTERNAL => 'External',
self::TYPE_LPE => 'LPE'
);
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false, options={"unsigned":true})
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string
*
* #Assert\NotNull()
* #ORM\Column(name="type", type="string", nullable=false, options={"default":"lpe"})
*/
private $type;
/**
* #var string
*
* #Assert\NotNull()
* #ORM\Column(name="name", type="string", nullable=false)
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="created", type="datetime")
*/
private $created;
/**
* #var string
*
* #ORM\Column(name="updated", nullable=true, type="datetime")
*/
private $updated;
/**
* #var string
*
* #ORM\Column(name="deleted", type="boolean", options={"default":0})
*/
private $deleted;
/**
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\Regions")
* #ORM\JoinTable(name="supplier_regions",
* joinColumns={
* #ORM\JoinColumn(
* name="supplier_id",
* referencedColumnName="id"
* )
* },
* inverseJoinColumns={
* #ORM\JoinColumn(
* name="region_id",
* referencedColumnName="postcode"
* )
* }
* )
*/
private $regions;
private $lpe;
public function __construct()
{
$this->regions = new ArrayCollection();
}
public function getRegions()
{
return $this->regions;
}
public function setRegions($regions)
{
$this->regions = $regions;
return $this;
}
public function getLpe()
{
return $this->lpe;
}
public function setLpe($lpe)
{
$this->lpe = $lpe;
return $this;
}
/**
* #return string
*/
public function getLpeFirstName()
{
return $this->lpe->getUser()->getFirstName();
}
/**
* #return string
*/
public function getLpeLastName()
{
return $this->lpe->getUser()->getLastName();
}
/**
* #return string
*/
public function getLpeEmail()
{
return $this->lpe->getUser()->getEmail();
}
public function getContractType()
{
return $this->lpe->getContractType();
}
public function getUser()
{
return $this->lpe->getUser();
}
public function setUser($user)
{
$this->lpe->setUser($user);
return $this;
}
public function setFirstName($name)
{
$this->user->setFirstName($name);
return $this;
}
public function getFirstName()
{
return $this->user->getFirstName();
}
public function setLastName($name)
{
$this->user->setLastName($name);
return $this;
}
public function getLastName()
{
return $this->getUser()->getLastName();
}
public function setEmail($email)
{
$this->getUser()->setEmail($email);
return $this;
}
public function getEmail()
{
return $this->getUser()->getEmail();
}
/**
* #var string
*/
private $entityName;
/**
* Get id
*
* #return integer
*/
public function nullId()
{
return $this->id =null;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set type
*
* #param string $type
* #return User
*/
public function setType($type)
{
$this->type = strtolower($type);
return $this;
}
/**
* Get type
*
* #return string
*/
public function getType()
{
if ($this->type == 'lpe') {
return strtoupper($this->type);
}
return ucwords($this->type);
}
/**
* Set name
*
* #param string $name
* #return User
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set created
*
* #param string $created
* #return $this
*/
public function setCreated($created)
{
if (!empty($created)) {
$this->created = $created;
} else {
$this->created = new \DateTime("now");
}
return $this;
}
/**
* Get created
*
* #return string
*/
public function getCreated()
{
return $this->created;
}
/**
* Set updated
*
* #param string $updated
* #return User
*/
public function setUpdated($updated)
{
$this->updated = $updated;
return $this;
}
/**
* Get updated
*
* #return string
*/
public function getUpdated()
{
return $this->updated;
}
/**
* Set deleted
*
* #param boolean $deleted
* #return User
*/
public function setDeleted($deleted)
{
$this->deleted = $deleted;
return $this;
}
/**
* Get deleted
*
* #return boolean
*/
public function getDeleted()
{
return $this->deleted;
}
/**
* #ORM\PrePersist()
*/
public function onPrePersist()
{
$this->created = new \DateTime();
$this->updated = new \DateTime();
if ($this->deleted === null) {
$this->deleted = 0;
}
if ($this->type === null) {
$this->type = 'lpe';
}
if ($this->name === null) {
$this->name = '';
}
}
/**
* #ORM\PreUpdate()
*/
public function onPreUpdate()
{
$this->created = new \DateTime();
$this->updated = new \DateTime();
if ($this->deleted === null) {
$this->deleted = 0;
}
}
/**
* #return array
*/
public static function getTypes()
{
return self::$types;
}
/**
* Set entityName
*
* #param string $name
* #return User
*/
public function setEntityName($name)
{
$this->entityName = $name;
return $this;
}
public function __toString()
{
if ($this->getUser() === null) {
return 'Supplier' . ($this->id !== null ? ' #' . $this->id.'' : '' );
}
return (string) ($this->id !== null ? '#' . $this->id.' ' : '' ) . $this->getUser()->getEmail();
}
}
Any suggestions? :)
I think it is in your configuration file
doctrine:
[...]
orm:
[...]
mappings:
AppBundle:
type: ~
dir: "Entity"
prefix: "AppBundle\Entity"
is_bundle: ~
If it is not working, look over your namespaces, I think (but not sure) it should be like PROJECT\BUNDLE\Entity and not just BUNDLE\Entity (for both namespace and use statements)
You have to set your doctrine configuration to add your bundle to the ORM :
# Doctrine Configuration
doctrine:
dbal:
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%'
entity_managers:
default:
mappings:
ApplicationSonataUserBundle: ~
SonataUserBundle: ~
FOSUserBundle: ~
**YourBundleNameBundle**: ~
I'm migrating my Symfony 2.0 project to version 2.1rc1. After installing the stof/doctrine-extensions-bundle and the gedmo/doctrine-extensions and test my application I get the following error:
No identifier/primary key specified for Entity "Company\TestBundle\Entity\PageTranslation" sub class of "Gedmo\Translatable\Entity\MappedSuperclass\AbstractTranslation". Every Entity must have an identifier/primary key.
My config.yml looks like this:
# Doctrine Configuration
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%
connection: default
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 # this one is optional and 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 # this one is optional and will default to the name set for the mapping
is_bundle: false
stof_doctrine_extensions:
default_locale: en
translation_fallback: true
orm:
default:
translatable: true
sluggable: true
According to the documentation of StofDoctrineExtensionsBundle this should be fine. The only thing I'm not sure of is the auto_mapping: true option.
The only code I've changed in my project is in my CategoryTranslation class. I've replaced:
use Stof\DoctrineExtensionsBundle\Entity\AbstractTranslation;
by:
use Gedmo\Translatable\Entity\MappedSuperclass\AbstractTranslation;
Because the Stof-bundle doesn't have an AbstractTranslation class anymore.
Can someone tell me how I can fix this?
My PageTranslation entity before:
class PageTranslation extends AbstractTranslation
{
/**
* All required columns are mapped through inherited superclass
*/
}
My PageTranslation entity after generating the entities on the commandline:
class PageTranslation extends AbstractTranslation
{
/**
* All required columns are mapped through inherited superclass
*/
/**
* #var integer $id
*/
private $id;
/**
* #var string $locale
*/
private $locale;
.....etc....
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set locale
*
* #param string $locale
* #return PageTranslation
*/
public function setLocale($locale)
{
$this->locale = $locale;
return $this;
}
/**
* Get locale
*
* #return string
*/
public function getLocale()
{
return $this->locale;
}
..etc....
}
If you are using StofDoctrineExtensions you don't need gedmo/doctrine-extensions. Also isn't necessary to generate anything in PageTranslation