JMS Serializer exclude public properties - php

I have a class I want to serialize, but exclude a public property. So far I tried #Exclude but I did not work (see Result).
Any ideas how to solve this problem?
Entity:
class Checkout extends Entity
{
/**
* #Exclude()
*/
public $normalizerCallbacks = [
'a' => 1,
'b' => 2,
];
..........
Serialize:
$checkout = $this->getDoctrine()->getRepository('App:Checkout')->find($id);
$serializer = $this->get('jms_serializer');
$data = $serializer->serialize($checkout, 'json');
Result:
{
normalizer_callbacks: {
a: 1
b: 2
}
}
Edit: Trial 2015-09-10 18 --> Not working
use JMS\Serializer\Annotation as JMS;
/**
* User
*
* #ORM\Table(name="checkout", options={"collate"="utf8_general_ci"})
* #ORM\Entity
*
* #JMS\ExclusionPolicy("none")
*/
class Checkout extends Entity
{
/**
* #JMS\Exclude();
*/
public $normalizerCallbacks = [
...
Edit: Trial 2015-09-11 09 (Update 12) --> Configuration
Add to "jms/serializer-bundle": "^1.0" composer and run update
Add new JMS\SerializerBundle\JMSSerializerBundle() to AppKernel
Add jms_serializer.camel_case_naming_strategy.class: JMS\Serializer\Naming\IdenticalPropertyNamingStrategyto parameters.yml
Then used it as in Serialize

Try whether you included it correctly:
use JMS\Serializer\Annotation as JMS;
and then use it like:
#JMS\Exclude();
in your annotation.
As well make sure your class is annoted with #ExclusionPolicy("none") (see http://jmsyst.com/libs/serializer/master/reference/annotations).
You can as well do it the other way round, specifically #Expose while class is annotated with #ExlucsionPolicy("all").
Make sure to clean your cache before re-testing it.

Related

Adding new form and entities to Symfony does not work

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

Doctrine 2 overriding many to one association

Is it possible to override #ManyToOne(targetEntity)?
I read this Doctrine documentation page, but it doesn't mention how to override targetEntity.
Here's my code:
namespace AppBundle\Model\Order\Entity;
use AppBundle\Model\Base\Entity\Identifier;
use AppBundle\Model\Base\Entity\Product;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\AttributeOverrides;
use Doctrine\ORM\Mapping\AttributeOverride;
/**
* Class OrderItem
*
*
* #ORM\Entity
* #ORM\Table(name="sylius_order_item")
* #ORM\AssociationOverrides({
* #ORM\AssociationOverride(
* name="variant",
* joinColumns=#ORM\JoinColumn(
* name="variant", referencedColumnName="id", nullable=true
* )
* )
* })
*/
class OrderItem extends \Sylius\Component\Core\Model\OrderItem
{
/**
* #var
* #ORM\ManyToOne(targetEntity="AppBundle\Model\Base\Entity\Product")
*/
protected $product;
/**
* #return mixed
*/
public function getProduct()
{
return $this->product;
}
/**
* #param mixed $product
*/
public function setProduct($product)
{
$this->product = $product;
}
}
I was able to to override the definition for the "variant" column and set this column to null, but I can't figure it out how to change the targetEntity.
As described in the doc, you cannot change the type of your association:
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/inheritance-mapping.html#association-override
BUT, you can define a targetEntity as an interface (that's the default sylius conf it seems),
targetEntity="AppBundle\Entity\ProductInterface"
Extends the original one in your Interface file
namespace AppBundle\Entity;
use Sylius\Component\Core\Model\ProductInterface as BaseProductInterface;
interface ProductInterface extends BaseProductInterface {}
And add the mapping in your configuration
doctrine:
orm:
resolve_target_entities:
AppBundle\Entity\ProductInterface: AppBundle\Entity\Product
It's described here: http://symfony.com/doc/current/doctrine/resolve_target_entity.html
Hope it helps
I didn't find a way to override the targetEntity value of an association when using annotations, but it is possible when using PHP mapping (php or staticphp in Symfony).
https://www.doctrine-project.org/projects/doctrine-orm/en/current/reference/php-mapping.html
We can create a function:
function updateAssociationTargetEntity(ClassMetadata $metadata, $association, $targetEntity)
{
if (!isset($metadata->associationMappings[$association])) {
throw new \LogicException("Association $association not defined on $metadata->name");
}
$metadata->associationMappings[$association]['targetEntity'] = $targetEntity;
}
and use it like this:
updateAssociationTargetEntity($metadata, 'product', AppBundle\Model\Base\Entity\Product::class);
That way, when Doctrine loads the metadata for the class AppBundle\Model\Order\Entity\OrderItem, it first loads the parent (\Sylius\Component\Core\Model\OrderItem) metadata, and then it loads the PHP mapping for the child class where we override the association mapping that was set when loading the parent class metadata.

Class 'doctrine.orm.validator.unique' not found

So I am not sure what the issue is here, or how this class even gets loaded. But my model (or as their actually called, entity) looks like this:
<?php
namespace ImageUploader\Models;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* #ORM\Entity
* #ORM\Table(name="users")
* #UniqueEntity(fields="userName")
* #UniqueEntity(fields="email")
*/
class User {
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue
*/
protected $id;
/**
* #ORM\Column(type="string", length=32, nullable=false)
* #Assert\NotBlank()
*/
protected $firstName;
/**
* #ORM\Column(type="string", length=32, nullable=false)
* #Assert\NotBlank()
*/
protected $lastName;
/**
* #ORM\Column(type="string", length=100, unique=true, nullable=false)
* #Assert\NotBlank(
* message = "Username cannot be blank"
* )
*/
protected $userName;
/**
* #ORM\Column(type="string", length=100, unique=true, nullable=false)
* #Assert\NotBlank()
* #Assert\Email(
* message = "The email you entered is invalid.",
* checkMX = true
* )
*/
protected $email;
/**
* #ORM\Column(type="string", length=500, nullable=false)
* #Assert\NotBlank(
* message = "The password field cannot be empty."
* )
*/
protected $password;
/**
* #ORM\Column(type="datetime", nullable=true)
*/
protected $created_at;
/**
* #ORM\Column(type="datetime", nullable=true)
*/
protected $updated_at;
}
In my I have an action called createAction that gets called when a user attempts to sign up. It looks like this:
public static function createAction($params){
$postParams = $params->request()->post();
if ($postParams['password'] !== $postParams['repassword']) {
$flash = new Flash();
$flash->createFlash('error', 'Your passwords do not match.');
$params->redirect('/signup/error');
}
$user = new User();
$user->setFirstName($postParams['firstname'])
->setLastName($postParams['lastname'])
->setUserName($postParams['username'])
->setEmail($postParams['email'])
->setPassword($postParams['password'])
->setCreatedAtTimeStamp();
$validator = Validator::createValidatorBuilder();
$validator->enableAnnotationMapping();
$errors = $validator->getValidator()->validate($user);
var_dump($errors);
}
When this action is called I get the following error:
Fatal error: Class 'doctrine.orm.validator.unique' not found in /var/www/html/image_upload_app/vendor/symfony/validator/ConstraintValidatorFactory.php on line 47
I am not sure how to resolve this issue. My composer file is as such:
{
"require": {
"doctrine/orm": "2.4.*",
"doctrine/migrations": "1.0.*#dev",
"symfony/validator": "2.8.*#dev",
"symfony/doctrine-bridge": "2.8.*#dev",
"slim/slim": "~2.6",
"freya/freya-exception": "0.0.7",
"freya/freya-loader": "0.2.2",
"freya/freya-templates": "0.1.2",
"freya/freya-factory": "0.0.8",
"freya/freya-flash": "0.0.1"
},
"autoload": {
"psr-4": {"": ""}
}
}
So I am not sure if I am missing a package or if I am doing something wrong ....
My bootstrap.php file has the following contents in it:
require_once 'vendor/autoload.php';
$loader = require 'vendor/autoload.php';
\Doctrine\Common\Annotations\AnnotationRegistry::registerLoader(array($loader, 'loadClass'));
use Doctrine\ORM\Tools\Setup;
use Doctrine\ORM\EntityManager;
/**
* Set up Doctrine.
*/
class DoctrineSetup {
/**
* #var array $paths - where the entities live.
*/
protected $paths = array(APP_MODELS);
/**
* #var bool $isDevMode - Are we considered "in development."
*/
protected $isDevMode = false;
/**
* #var array $dbParams - The database paramters.
*/
protected $dbParams = null;
/**
* Constructor to set some core values.
*/
public function __construct(){
if (!file_exists('db_config.ini')) {
throw new \Exception(
'Missing db_config.ini. You can create this from the db_config_sample.ini'
);
}
$this->dbParams = array(
'driver' => 'pdo_mysql',
'user' => parse_ini_file('db_config.ini')['DB_USER'],
'password' => parse_ini_file('db_config.ini')['DB_PASSWORD'],
'dbname' => parse_ini_file('db_config.ini')['DB_NAME']
);
}
/**
* Get the entity manager for use through out the app.
*
* #return EntityManager
*/
public function getEntityManager() {
$config = Setup::createAnnotationMetadataConfiguration($this->paths, $this->isDevMode, null, null, false);
return EntityManager::create($this->dbParams, $config);
}
}
/**
* Function that can be called through out the app.
*
* #return EntityManager
*/
function getEntityManager() {
$ds = new DoctrineSetup();
return $ds->getEntityManager();
}
/**
* Function that returns the conection to the database.
*/
function getConnection() {
$ds = new DoctrineSetup();
return $ds->getEntityManager()->getConnection();
}
Do I need to add something else to it to get this error to go away?
Update 1
So I went ahead and set up the AppKernel as I didn't have one before, and because I don't believe I need a config.yml (at least not yet). Everything seems to be working - kernel wise, but the error still persists.
namespace ImageUploader;
use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\Config\Loader\LoaderInterface;
class AppKernel extends Kernel {
public function registerBundles() {
$bundles = array(
new \Doctrine\Bundle\DoctrineBundle\DoctrineBundle()
);
return $bundles;
}
public function registerContainerConfiguration(LoaderInterface $loader) {}
}
I then started the kernel in the bootstrap file, by adding:
use \ImageUploader\AppKernel;
$kernel = new AppKernel();
$kernel->boot();
Everything, from what I have read, is correct - minus the missing config file that shouldn't be an issue. But I still receive the error in question
How i worked around this:
First, created a custom ConstraintValidatorFactory that'd allow me to add validators
<?php
namespace My\App\Validator;
use Symfony\Component\Validator\ConstraintValidatorFactory as SymfonyConstraintValidatorFactory;
use Symfony\Component\Validator\ConstraintValidatorInterface;
/**
* Class ConstraintValidatorFactory
*
* #package My\App\Validator
*/
class ConstraintValidatorFactory extends SymfonyConstraintValidatorFactory
{
/**
* #param string $className
* #param ConstraintValidatorInterface $validator
*
* #return void
*/
public function addValidator($className, $validator): void
{
$this->validators[$className] = $validator;
}
}
Then i could do:
<?php
use My\App\Validator\ConstraintValidatorFactory;
use Symfony\Component\Validator\Validation;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntityValidator;
$factory = new ConstraintValidatorFactory();
$factory->addValidator('doctrine.orm.validator.unique', new UniqueEntityValidator($registry));
$builder = Validation::createValidatorBuilder();
$builder->setConstraintValidatorFactory($factory);
$builder->enableAnnotationMapping();
$validator = $builder->getValidator();
$violations = $validator->validate($entity);
This worked for me, using symfony components with zend service manager.
Bare in mind that Symfony's UniqueEntityValidator depends on \Doctrine\Common\Persistence\ManagerRegistry.
I use a single EntityManager for my project and had to wrap it in a ManagerRegistry class to make this work.
You are missing the Doctrine bundle, which integrates doctrine into the Symfony framework. Install it with composer require doctrine/doctrine-bundle and then register it in your AppKernel.
Related to Update #1
You still need some configuration and set up the doctrine ORM. Without this configuration, ORM services (like the one missing here) are not loaded.
This is an old question but as I just stumbled upon it and find the chosen answer not entirely satisfying I would like to contribute a bit.
As I understood from the comments this is not about full-stack Symfony but only about the Symfony-validator component.
Because the validator constraint UniqueEntity is based on Doctrine integration and hard-coding class names or the such is not recommended to prevent tight-coupling, Symfony uses a much used pattern called services (see service container).
This allows defining services through configuration which would then prevent hardcoding class names (and its dependencies!) into the Validator codebase. This allows dependencies between both project to be configurable (less compatibility-breaks) and optional.
This 'doctrine.orm.validator.unique' "class" that is being searched for is actually just a reference to an instance of the actual class. For it to be found one must add two things:
A service container, which resolves this service name to the class instance
And the actual configuration of this service, which defines the class to instantiate and its constructor parameters (dependencies).
Looking at your composer.json I think we need the Symfony DependencyInjection component, I don't think you need the AppKernel for this. The following code might work (not tested it) but in any case should give you roughly the idea of what we need:
use Symfony\Component\DependencyInjection\ContainerBuilder;
$container = new ContainerBuilder();
$container
->register('doctrine.orm.validator.unique', 'Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntityValidator')
->addArgument(new Reference('doctrine'));
# register doctrine here in the same way as we just registered the validator
So in conclusion, this answer will probably be a year or two too late for the OP but might be useful to others stumbling upon this. Cheers!
In the first you can get the kernel
After using the kernel to get service validator.
For example : $validator = $kernel->getContainer()->get('validator');

Doctrine 2 association overwrite

I have a question about Doctrine 2 and the ability (or not?) to extend an association between to classes.
Best explained with an example :)
Let's say I have this model (code is not complete):
/**
* #Entity
*/
class User {
/**
* #ManyToMany(targetEntity="Group")
* #var Group[]
*/
protected $groups;
}
/**
* #Entity
*/
class Group {
/**
* #ManyToMany(targetEntity="Role")
* #var Role[]
*/
protected $roles;
}
/**
* #Entity
*/
class Role {
/**
* #ManyToOne(targetEntity="RoleType")
* #var RoleType
*/
protected $type;
}
/**
* #Entity
*/
class RoleType {
public function setCustomDatas(array $params) {
// do some stuff. Default to nothing
}
}
Now I use this model in some projects. Suddenly, in a new project, I need to have a RoleType slightly different, with some other fields in DB and other methods. Of course, it was totally unexpected.
What I do in the "view-controller-but-not-model" code is using services:
// basic configuration
$services['RoleType'] = function() {
return new RoleType();
};
// and then in the script that create a role
$role_type = $services['RoleType'];
$role_type->setCustomDatas($some_params);
During application initialization, I simply add this line to overwrite the default RoleType
$services['RoleType'] = function() {
return new GreatRoleType();
};
Ok, great! I can customize the RoleType call and then load some custom classes that do custom things.
But... now I have my model. The model says that a Role targets a RoleType. And this is hard-written. Right now, to have my custom changes working, I need to extend the Role class this way:
/**
* #Entity
*/
class GreatRole extends Role {
/**
* Changing the targetEntity to load my custom type for the role
* #ManyToOne(targetEntity="GreatRoleType")
* #var RoleType
*/
protected $type;
}
But then, I need to extend the Group class to target GreatRole instead of Role.
And in the end, I need to extend User to target GreatGroup (which targets GreatRole, which targets GreatRoleType).
Is there a way to avoid this cascade of extends? Or is there a best practice out there that is totally different from what I did?
Do I need to use MappedSuperClasses? The doc isn't very explicit...
Thanks for your help!
--------------------------- EDIT ---------------------------
If I try to fetch all the hierarchy from User, that's when I encounter problems:
$query
->from('User', 'u')
->leftJoin('u.groups', 'g')
->leftJoin('g.roles', 'r')
->leftJoin('r.type', 't');
If I want to have a "r.type" = GreatRoleType, I need to redefine each classes.

Using EntityRepository::findBy() with Many-To-Many relations will lead to a E_NOTICE in Doctrine

For a Symfony2 project I had to create a relationship between a blog post and so called platforms.
A platform defines a specific filter based on the domain you use to view the site.
For example: If you join the site by url first-example.com, the site will only provide blog posts, which are connected to this specific platform.
To do so, I created two entities Post and Platform. Afterwards I mapped them together with a Many-To-Many relationship.
I'm trying to retrieve data via this Many-To-Many relationship from the builtin function findBy() in Doctrines' EntityRepository.
// every one of these methods will throw the same error
$posts = $postRepo->findBy(array('platforms' => array($platform)));
$posts = $postRepo->findByPlatforms($platform);
$posts = $postRepo->findByPlatforms(array($platform));
Where $postRepo is the correct Repository for the Post entity and $platform an existing Platform object.
Either way: I end up getting the following error:
ErrorException: Notice: Undefined index: joinColumns in [...]/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php line 1495
[...]/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php:1495
[...]/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php:1452
[...]/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php:1525
[...]/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php:1018
[...]/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php:842
[...]/vendor/doctrine/orm/lib/Doctrine/ORM/EntityRepository.php:157
[...]/src/Foobar/BlogBundle/Tests/ORM/PostTest.php:102
Is it even possible to retrieve related entites in a Many-To-Many relationship this way, or am i forced to write these functions by myself?
The weird thing is: Doctrine will not throw any error like: "It's not possible.", but an internal E_NOTICE. Thats why I tent to think it should be possible, but I'm missing some points here.
Stripped down to the interesting parts, the two Entities look like this.
<?php
namespace Foobar\CommunityBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
// [...] other namespace stuff
/**
* #ORM\Entity(repositoryClass="Foobar\CommunityBundle\Entity\Repository\PlatformRepository")
* #ORM\Table(name="platforms")
*/
class Platform
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
// [...] other field stuff
}
<?php
namespace Foobar\BlogBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
// [...] other namespace stuff
/**
* #ORM\Entity(repositoryClass="Foobar\BlogBundle\Entity\Repository\PostRepository")
* #ORM\Table(name="posts")
*/
class Post implements Likeable, Commentable, Taggable, PlatformAware
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\ManyToMany(targetEntity="Foobar\CommunityBundle\Entity\Platform", cascade={"persist"})
* #ORM\JoinTable(name="map_post_platform",
* joinColumns={#ORM\JoinColumn(name="post_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="platform_id", referencedColumnName="id")}
* )
*/
protected $platforms;
// [...] other fields
/**
* Constructor
*/
public function __construct()
{
// [...]
$this->platforms = new ArrayCollection();
}
}
And of course the composer.json file (as well stripped down to the relevant lines)
{
[...]
"require": {
"php": ">=5.3.3",
"symfony/symfony": "2.1.*",
"doctrine/orm": ">=2.2.3,<2.4-dev",
"doctrine/doctrine-bundle": "1.0.*",
"doctrine/doctrine-fixtures-bundle": "dev-master",
[...]
},
[...]
}
Another way, maybe a bit OO/cleaner without using IDs:
public function getPosts(Platform $platform)
{
$qb = $this->createQueryBuilder("p")
->where(':platform MEMBER OF p.platforms')
->setParameters(array('platform' => $platform))
;
return $qb->getQuery()->getResult();
}
A better method name would be findPostsByPlatform
It is very possible, but the Stock Doctrine Repository does not work this way.
You have two options, depending on your context:
Write a custom method in the Repository.
class PostRepository extends EntityRepository
{
public function getPosts($id)
{
$qb = $this->createQueryBuilder('p');
$qb->join('p.platform', 'f')
->where($qb->expr()->eq('f.id', $id));
return $qb;
}
}
Or use the default getter methods in the platform object.
$posts = $platform->getPosts();
You "stripped down to the interesting parts" so it is not obvious if you have this method but it is normally made on
app/console doctrine:generate:entities
This question seems a problem with a ManyToMany relationship which you want BIDIRECTIONAL (and is now UNIDIRECTRIONAL). Use MappedBy to create bidirectionality :
http://doctrine-orm.readthedocs.org/en/latest/reference/association-mapping.html#many-to-many-bidirectional
Practical :
One of your entities is OWNING SIDE, the other INVERSE SIDE.
In your example entity named Post is owning side, and entity named Platform is inverse side.
OWNING SIDE setup :
Class Post {
...
/**
* #ManyToMany(targetEntity="Platform")
* #JoinTable(name="map_post_platform",
* joinColumns={#JoinColumn(name="post_id", referencedColumnName="id")},
* inverseJoinColumns={#JoinColumn(name="platform_id", referencedColumnName="id", unique=true)} )
**/
protected $platforms;
...
public function Post() {
$this->platforms= new ArrayCollection();
}
...
public function assignToPlatform($platform) {
$this->platforms[] = $platform;
}
...
public function getPlatforms() {
return $this->platforms;
}
}
INVERSE SIDE Setup :
Class Platform {
...
/**
* #ManyToMany(targetEntity="Post", mappedBy="platforms")
**/
protected $posts;
...
public function Platform() {
$this->posts= new ArrayCollection();
}
...
public function getPosts()
{
return $this->posts;
}
}
EXAMPLE retrieving an array of entities, starting from one of the sides :
$post->getPlatforms();
$platform->getPosts();

Categories