How to map mongo documents with subdocuments in symfony2 - mongodb

I'm trying to create symfony2 application which will access mongoDB collection with the following structure:
{
"_id": ObjectId("5239c1c0359bf908058a5071"),
"param2": "test",
"param3": {
"subparam31": 0,
"subparam32": 0,
"subparam33": 0
},
"param4": 1
}
In symfony 2 I create a .yml, and php class. I correctly map only "_id", "param2" and "param4", but not "subparam31", "subparam32" and "subparam33" of "param3".
I use next file structure for mapping:
Params.mongodb.yml:
Acme\StoreBundle\Document\Params:
db: test
type: document
fields:
id:
id: true
param2:
type: string
param3:
type: mixed
subparam31:
type: float
subparam32:
type: float
subparam33:
type: float
param4:
type: float
Params.php
<?php
namespace Acme\StoreBundle\Document;
class Params
{
protected $param2;
protected $param4;
protected $param3;
protected $subparam31;
protected $subparam32;
protected $subparam33;
}
?>
Where I'm wrong? How to get and set values of subparams?
For accessing param2, param4 and id I use following code in controller which works:
$parameter = $this->get('doctrine_mongodb')
->getRepository('AcmeStoreBundle:Params')
->find($id);
$parameter2 = $parameter->getParam2();
$parameter4 = $parameter->getParam4();
if (!$format) {
throw $this->createNotFoundException('Not found parameter with id -> '.$id);
}
return array(
"parameter2" => $parameter2,
"parameter4" => $parameter4
);
I hope I was clear enough.
Thanks in advance.

I found the solution! In addition to mapping in yml, appropriate annotation in php classes also should be defined.
Here is the content the necessary files:
Params.mongodb.yml
Acme\StoreBundle\Document\Params:
db: test
type: document
embedOne:
param3:
targetDocument: Param3
fields:
id:
id: true
param2:
type: string
param4:
type: float
Param3.mongodb.yml
Acme\StoreBundle\Document\Param3:
db: test
type: embeddedDocument
fields:
subparam31:
type: float
subparam32:
type: float
subparam33:
type: float
Params.php
<?php
namespace Acme\StoreBundle\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations;
/**
* #Doctrine\ODM\MongoDB\Mapping\Annotations\Document
*/
class Params
{
/**
* #Doctrine\ODM\MongoDB\Mapping\Annotations\Id
*/
protected $id;
/**
* #Doctrine\ODM\MongoDB\Mapping\Annotations\String
*/
protected $param2;
/**
* #Doctrine\ODM\MongoDB\Mapping\Annotations\Float
*/
protected $param4;
/**
* #Doctrine\ODM\MongoDB\Mapping\Annotations\EmbedOne(targetDocument="Param3")
*/
protected $param3;
public function __construct($subparam31 = NULL, $subparam32 = NULL, $subparam33 = NULL)
{
$param3 = new Param3($subparam31, $subparam32, $subparam33);
$this->setParam3($param3);
}
/**
* Get id
*
* #return id $id
*/
public function getId()
{
return $this->id;
}
/**
* Set param2
*
* #param string $param2
* #return self
*/
public function setParam2($param2)
{
$this->param2 = $param2;
return $this;
}
/**
* Get param2
*
* #return string $param2
*/
public function getParam2()
{
return $this->param2;
}
/**
* Set param4
*
* #param float $param4
* #return self
*/
public function setParam4($param4)
{
$this->param4 = $param4;
return $this;
}
/**
* Get param4
*
* #return float $param4
*/
public function getParam4()
{
return $this->param4;
}
/**
* Set param3
*
* #param Acme\StoreBundle\Document\Param3 $param3
* #return self
*/
public function setParam3(\Acme\StoreBundle\Document\Param3 $param3)
{
$this->param3 = $param3;
return $this;
}
/**
* Get param3
*
* #return Acme\StoreBundle\Document\Param3 $param3
*/
public function getParam3($toArray = false)
{
if ($toArray) {
if ($this->param3) {
return $this->param3->toArray();
}
}
return $this->param3;
}
public function toArray()
{
return array(
'param3' => $this->getParam3(true)
);
}
}
Param3.php
<?php
namespace Acme\StoreBundle\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations;
/**
* #Doctrine\ODM\MongoDB\Mapping\Annotations\EmbeddedDocument
*/
class Param3
{
/**
* #Doctrine\ODM\MongoDB\Mapping\Annotations\Float
*/
protected $subparam31;
/**
* #Doctrine\ODM\MongoDB\Mapping\Annotations\Float
*/
protected $subparam32;
/**
* #Doctrine\ODM\MongoDB\Mapping\Annotations\Float
*/
protected $subparam33;
public function __construct($subparam31 = NULL, $subparam32 = NULL, $subparam33 = NULL)
{
$this->subparam31 = $subparam31;
$this->subparam32 = $subparam32;
$this->subparam33 = $subparam33;
}
/**
* Set subparam31
*
* #param float $subparam31
* #return self
*/
public function setSubparam31($subparam31)
{
$this->subparam31 = $subparam31;
return $this;
}
/**
* Get subparam31
*
* #return float $subparam31
*/
public function getSubparam31()
{
return $this->subparam31;
}
/**
* Set subparam32
*
* #param float $subparam32
* #return self
*/
public function setSubparam32($subparam32)
{
$this->subparam32 = $subparam32;
return $subparam32;
}
/**
* Get subparam32
*
* #return float $subparam32
*/
public function getSubparam32()
{
return $this->subparam32;
}
/**
* Set subparam33
*
* #param float $subparam33
* #return self
*/
public function setSubparam33($subparam33)
{
$this->subparam33 = $subparam33;
return $this;
}
/**
* Get subparam33
*
* #return float $subparam33
*/
public function getSubparam33()
{
return $this->subparam33;
}
public function toArray()
{
return array(
'subparam31' => $this->getSubparam3(),
'subparam32' => $this->getSubparam32(),
'subparam33' => $this->getSubparam33()
);
}
}
This question helped me.

I think what you're looking for is an EmbeddedDocument.
Define a separate document for param3 (that includes subparam31, subparam32, and subparam33) set it as the targetDocument in params. So Params.mongodb.yml would look something like:
db: test
type: document
embedOne:
params3:
targetDocument: params3Class
fields:
id:
id: true
param2:
type: string
param4:
type: float

Related

Warning: spl_object_hash() expects parameter 1 to be object, array given Collection forms

i created a collection form for a CV for each user of the web application
and each CV contain many Experiences, Languages, Formation, Competance!
and add a Jquery code to use the data-prototype in the collection form so the user can add multiple experiences and formation etc... to his cv
for now everything is okay my form is well shown but the problem when is submit!
i get this error:
Warning: spl_object_hash() expects parameter 1 to be object, array given
here is my yml for doctrine:
cv.orm.yml:
cyn\UserBundle\Entity\Cv:
type: entity
table: cv
id:
id:
type: integer
generator: { strategy: AUTO }
fields:
expenmois:
type: integer
divers:
type: text
oneToMany:
experience:
targetEntity: Experience
mappedBy: cv
cascade: ["persist", "merge"]
formation:
targetEntity: Formation
mappedBy: cv
cascade: ["persist", "merge"]
competance:
targetEntity: Competance
mappedBy: cv
cascade: ["persist", "merge"]
langue:
targetEntity: Langue
mappedBy: cv
cascade: ["persist", "merge"]
Experience.orm.yml:
cyn\UserBundle\Entity\Experience:
type: entity
table: experience
id:
id:
type: integer
generator: { strategy: AUTO }
fields:
nom_societe:
type: string
length: 255
nullable: false
lieutravail:
type: string
length: 255
nullable: false
poste:
type: string
length: 255
nullable: false
datedebut:
type: date
datefin:
type: date
description:
type: text
manyToOne:
cv:
targetEntity: Cv
inversedBy: experience
joinColumn:
name: cv_id
referencedColumnName: id
formation.orm.yml:
cyn\UserBundle\Entity\Formation:
type: entity
table: formation
id:
id:
type: integer
generator: { strategy: AUTO }
fields:
etablissement:
type: string
length: 255
nullable: false
datedebut:
type: date
datefin:
type: date
manyToOne:
cv:
targetEntity: Cv
inversedBy: formation
joinColumn:
name: cv_id
referencedColumnName: id
competance.orm.yml:
cyn\UserBundle\Entity\Competance:
type: entity
table: competance
id:
id:
type: integer
generator: { strategy: AUTO }
fields:
domaine:
type: string
length: 255
details:
type: string
length: 255
manyToOne:
cv:
targetEntity: Cv
inversedBy: competance
joinColumn:
name: cv_id
referencedColumnName: id
langue.orm.yml
cyn\UserBundle\Entity\Langue:
type: entity
table: langue
id:
id:
type: integer
generator: { strategy: AUTO }
fields:
langue:
type: string
length: 255
niveau:
type: string
length: 255
manyToOne:
cv:
targetEntity: Cv
inversedBy: langue
joinColumn:
name: cv_id
referencedColumnName: id
and this is my collection form type:
<?php
namespace cyn\UserBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use cyn\UserBundle\Entity\Cv;
use cyn\UserBundle\Entity\Experience;
use cyn\UserBundle\Entity\Competance;
use cyn\UserBundle\Entity\Langue;
use cyn\UserBundle\Entity\Formation;
class CvType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('expEnMois', 'text');
$builder->add('divers', 'textarea');
$builder->add('experience', 'collection',array(
'type'=> new ExperienceType(),
'allow_add'=>true,
'allow_delete' => true )
);
$builder->add('Enregistrer', 'submit');
}
public function getDefaultOptions(array $options)
{
return array(
'data_class' => 'cyn\UserBundle\Entity\Cv',
);
}
public function getName()
{
return 'cv';
}
}
and this is my controller for add:
<?php
namespace cyn\UserBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Doctrine\Common\Collections\Collection;
use cyn\UserBundle\Form\Type\CvType;
use cyn\UserBundle\Entity\Cv;
use cyn\UserBundle\Entity\Competance;
use cyn\UserBundle\Entity\Langue;
use cyn\UserBundle\Entity\Experience;
use cyn\UserBundle\Entity\Formation;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class CvController extends Controller
{
public function addAction()
{
$cv = new Cv();
$exp = new Experience();
$exp->setCv($cv);
$form = $this->get('form.factory')->create(new CvType(), $cv);
$request = $this->getRequest();
if ('POST' === $request->getMethod()) {
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($cv);
$em->flush();
$this->get('session')->getFlashBag()->add('notice', 'Félicitations, votre cv a bien été enregistré.' );
}
}
return $this->render('cynUserBundle:Default:ajoutercv.html.twig', array(
'form' => $form->createView(),
));
}
}
my cv entity:
<?php
namespace cyn\UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Cv
*/
class Cv
{
/**
* #var integer
*/
private $id;
/**
* #var integer
*/
private $expenmois;
/**
* #var string
*/
private $divers;
/**
* #var \Doctrine\Common\Collections\Collection
*/
private $experience;
/**
* #var \Doctrine\Common\Collections\Collection
*/
private $formation;
/**
* #var \Doctrine\Common\Collections\Collection
*/
private $competance;
/**
* #var \Doctrine\Common\Collections\Collection
*/
private $langue;
/**
* Constructor
*/
public function __construct()
{
$this->experience = new \Doctrine\Common\Collections\ArrayCollection();
$this->formation = new \Doctrine\Common\Collections\ArrayCollection();
$this->competance = new \Doctrine\Common\Collections\ArrayCollection();
$this->langue = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set expenmois
*
* #param integer $expenmois
* #return Cv
*/
public function setExpenmois($expenmois)
{
$this->expenmois = $expenmois;
return $this;
}
/**
* Get expenmois
*
* #return integer
*/
public function getExpenmois()
{
return $this->expenmois;
}
/**
* Set divers
*
* #param string $divers
* #return Cv
*/
public function setDivers($divers)
{
$this->divers = $divers;
return $this;
}
/**
* Get divers
*
* #return string
*/
public function getDivers()
{
return $this->divers;
}
/**
* Add experience
*
* #param \cyn\UserBundle\Entity\Experience $experience
* #return Cv
*/
public function addExperience(\cyn\UserBundle\Entity\Experience $experience)
{
$this->experience[] = $experience;
return $this;
}
/**
* Remove experience
*
* #param \cyn\UserBundle\Entity\Experience $experience
*/
public function removeExperience(\cyn\UserBundle\Entity\Experience $experience)
{
$this->experience->removeElement($experience);
}
/**
* Get experience
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getExperience()
{
return $this->experience;
}
/**
* Add formation
*
* #param \cyn\UserBundle\Entity\Formation $formation
* #return Cv
*/
public function addFormation(\cyn\UserBundle\Entity\Formation $formation)
{
$this->formation[] = $formation;
return $this;
}
/**
* Remove formation
*
* #param \cyn\UserBundle\Entity\Formation $formation
*/
public function removeFormation(\cyn\UserBundle\Entity\Formation $formation)
{
$this->formation->removeElement($formation);
}
/**
* Get formation
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getFormation()
{
return $this->formation;
}
/**
* Add competance
*
* #param \cyn\UserBundle\Entity\Competance $competance
* #return Cv
*/
public function addCompetance(\cyn\UserBundle\Entity\Competance $competance)
{
$this->competance[] = $competance;
return $this;
}
/**
* Remove competance
*
* #param \cyn\UserBundle\Entity\Competance $competance
*/
public function removeCompetance(\cyn\UserBundle\Entity\Competance $competance)
{
$this->competance->removeElement($competance);
}
/**
* Get competance
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getCompetance()
{
return $this->competance;
}
/**
* Add langue
*
* #param \cyn\UserBundle\Entity\Langue $langue
* #return Cv
*/
public function addLangue(\cyn\UserBundle\Entity\Langue $langue)
{
$this->langue[] = $langue;
return $this;
}
/**
* Remove langue
*
* #param \cyn\UserBundle\Entity\Langue $langue
*/
public function removeLangue(\cyn\UserBundle\Entity\Langue $langue)
{
$this->langue->removeElement($langue);
}
/**
* Get langue
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getLangue()
{
return $this->langue;
}
}
and here is one of my others entitys experience.php:
<?php
namespace cyn\UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Experience
*/
class Experience
{
/**
* #var integer
*/
private $id;
/**
* #var string
*/
private $nom_societe;
/**
* #var string
*/
private $lieutravail;
/**
* #var string
*/
private $poste;
/**
* #var \DateTime
*/
private $datedebut;
/**
* #var \DateTime
*/
private $datefin;
/**
* #var string
*/
private $description;
/**
* #var \cyn\UserBundle\Entity\Cv
*/
private $cv;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set nom_societe
*
* #param string $nomSociete
* #return Experience
*/
public function setNomSociete($nomSociete)
{
$this->nom_societe = $nomSociete;
return $this;
}
/**
* Get nom_societe
*
* #return string
*/
public function getNomSociete()
{
return $this->nom_societe;
}
/**
* Set lieutravail
*
* #param string $lieutravail
* #return Experience
*/
public function setLieutravail($lieutravail)
{
$this->lieutravail = $lieutravail;
return $this;
}
/**
* Get lieutravail
*
* #return string
*/
public function getLieutravail()
{
return $this->lieutravail;
}
/**
* Set poste
*
* #param string $poste
* #return Experience
*/
public function setPoste($poste)
{
$this->poste = $poste;
return $this;
}
/**
* Get poste
*
* #return string
*/
public function getPoste()
{
return $this->poste;
}
/**
* Set datedebut
*
* #param \DateTime $datedebut
* #return Experience
*/
public function setDatedebut($datedebut)
{
$this->datedebut = $datedebut;
return $this;
}
/**
* Get datedebut
*
* #return \DateTime
*/
public function getDatedebut()
{
return $this->datedebut;
}
/**
* Set datefin
*
* #param \DateTime $datefin
* #return Experience
*/
public function setDatefin($datefin)
{
$this->datefin = $datefin;
return $this;
}
/**
* Get datefin
*
* #return \DateTime
*/
public function getDatefin()
{
return $this->datefin;
}
/**
* Set description
*
* #param string $description
* #return Experience
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set cv
*
* #param \cyn\UserBundle\Entity\Cv $cv
* #return Experience
*/
public function setCv(\cyn\UserBundle\Entity\Cv $cv = null)
{
$this->cv = $cv;
return $this;
}
/**
* Get cv
*
* #return \cyn\UserBundle\Entity\Cv
*/
public function getCv()
{
return $this->cv;
}
}
experiencetype.php:
<?php
namespace cyn\UserBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use cyn\UserBundle\Entity\Experience;
class ExperienceType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('nomsociete', 'text');
$builder->add('lieutravail', 'text');
$builder->add('poste', 'text');
$builder->add('datedebut','birthday');
$builder->add('datefin', 'birthday');
$builder->add('description', 'text');
}
public function getDefaultOptions(array $options)
{
return array(
'data_class' => 'cyn\UserBundle\Entity\Experience',
);
}
public function getName()
{
return 'experience';
}
}
please help me i've been 1 week and i cannot solve this problem
This error indicates that the object contains the fields that do not exist in the entity. When using a custom form types, you must use a data transformer, or change them by hand in preUpdate. Check your objects for the content of external fields that appear after using your custom types.
echo "<pre>";
\Doctrine\Common\Util\Debug::dump();
echo "</pre>";
die;
Use this code in preUpdate function.

Getter always return NULL

I'm on mongodb doctrine in symfony2 and this is Jackass oops , this is my document
<?php
// srcng/NearBundle/Document/Cities.php
namespace ng\NearBundle\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
/**
* #MongoDB\Document(collection="cities") *
*/
class Cities
{
/**
* #MongoDB\Id
*/
protected $id;
/**
* #MongoDB\string
*/
protected $country;
/**
* #MongoDB\string
*/
protected $name;
/**
* #MongoDB\string
*/
protected $tokens;
/**
* #MongoDB\float
*/
protected $latitude;
/**
* #MongoDB\float
*/
protected $longitude;
/**
* Get id
*
* #return id $id
*/
public function getId()
{
return $this->id;
}
/**
* Set country
*
* #param string $country
* #return self
*/
public function setCountry($country)
{
$this->country = $country;
return $this;
}
/**
* Get country
*
* #return string $country
*/
public function getCountry()
{
return $this->country;
}
/**
* Set name
*
* #param string $name
* #return self
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string $name
*/
public function getName()
{
return $this->name;
}
/**
* Set tokens
*
* #param string $tokens
* #return self
*/
public function setTokens($tokens)
{
$this->tokens = $tokens;
return $this;
}
/**
* Get tokens
*
* #return string $tokens
*/
public function getTokens()
{
return $this->tokens;
}
/**
* Set latitude
*
* #param float $latitude
* #return self
*/
public function setLatitude($latitude)
{
$this->latitude = $latitude;
return $this;
}
/**
* Get latitude
*
* #return float $latitude
*/
public function getLatitude()
{
return $this->latitude;
}
/**
* Set longitude
*
* #param float $longitude
* #return self
*/
public function setLongitude($longitude)
{
$this->longitude = $longitude;
return $this;
}
/**
* Get longitude
*
* #return float $longitude
*/
public function getLongitude()
{
return $this->longitude;
}
}
in my controller when I run a query I get this :
object(ng\NearBundle\Document\Cities)#226 (6) {
["id":protected]=>
string(24) "52e95b6f69eb53d8877f44b5"
["country":protected]=>
NULL
["name":protected]=>
string(4) "Yuma"
["tokens":protected]=>
string(132) "Juma,YUM,Yuma,you ma,yuma,ywma, aryzwna,ywmh,Јума,Юма,יומה,یوما، آریزونا,ዩማᥠአሪዞና,ユマ,尤馬"
["latitude":protected]=>
string(8) "32.72532"
["longitude":protected]=>
string(9) "-114.6244"
}
country is always null
a MongoDB document example :
{
"_id" : ObjectId("52e95b6469eb53d8877eec0c"),
"name" : "'Ali Sabieh",
"tokens" : "Ali Sabie,Ali Sabiet,Ali Sabih,Ali Sabiè,Ali-Sabie,`Ali Sabieh,`Ali Sabih,Али-Сабие,‘Ali Sabieh,‘Ali Sabîẖ",
"country" : "DJ",
"latitude" : 11.15583,
"longitude" : 42.7125
}
what you think is the problem here?
The problem was the Memcached, it cached the models and didn't recognized the new field country !

Error provide a default value

I'm trying to play with MongoDB. But I've got some problems.
# src/Controller/DefaultController.php
public function editCategoryAction(Category $category) {
echo $category->getName();
die();
}
With "entity" this is ok but not with MongoDB.
It displays this error message :
Controller "Site\StoreBundle\Controller\DefaultController::editCategoryAction()" requires that you provide a value for the "$category" argument (because there is no default value or because there is a non optional argument after this one).
My Category Document :
namespace Site\StoreBundle\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
/**
* #MongoDB\Document
*/
class Category
{
/**
* #MongoDB\Id
*/
protected $id;
/**
* #MongoDB\String
*/
protected $name;
/**
* #MongoDB\ReferenceMany(targetDocument="Product")
*/
private $products = array();
public function __contructor() {
$this->products = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return id $id
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return self
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string $name
*/
public function getName()
{
return $this->name;
}
public function getProducts() {
return $this->products;
}
public function __construct()
{
$this->products = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add product
*
* #param Site\StoreBundle\Document\Product $product
*/
public function addProduct(\Site\StoreBundle\Document\Product $product)
{
$this->products[] = $product;
}
/**
* Remove product
*
* #param Site\StoreBundle\Document\Product $product
*/
public function removeProduct(\Site\StoreBundle\Document\Product $product)
{
$this->products->removeElement($product);
}
}
My Route
editCategory:
path: /editCategory/{id}
defaults: { _controller: SiteStoreBundle:Default:editCategory }
How can I solve this ?
Edit:
I found this article : http://php-and-symfony.matthiasnoback.nl/2012/10/symfony2-mongodb-odm-adding-the-missing-paramconverter/
I changed my src/Site/StoreBundle/Resources/config/services.yml to this :
parameters:
# site_store.example.class: Site\StoreBundle\Example
services:
doctrine_mongo_db_param_converter:
class: Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\DoctrineParamConverter
arguments: ['#doctrine_mongodb']
But same error :/
I think you missed to tag your service:
services:
doctrine_mongo_db_param_converter:
class: Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\DoctrineParamConverter
arguments: ['#doctrine_mongodb']
tags:
- { name: request.param_converter, priority: -2, converter: doctrine_mongo_db_param_converter}

Symfony2 Mongodb Doctrine Error spl_object_hash()

I get
Warning: spl_object_hash() expects parameter 1 to be object, boolean given in /Path/vendor/doctrine-mongodb-odm/lib/Doctrine/ODM/MongoDB/UnitOfWork.php line 1504
error when I try to do $dm->flush();
I persist object like this
$eve = new Event();
$eve->setEvent($event);
Here $event is array which gets converted to object using the setEvent() function.
The event class is given below.
<?php
namespace CE\MainBundle\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
/**
* #MongoDB\Document(collection="events")
* #MongoDB\Index(keys={"coordinates"="2d"})
*/
Class Event{
/**
* #MongoDB\Id
*/
protected $id;
/**
* #MongoDB\String
* #MongoDB\Index(unique=true,order="asc")
*/
protected $eid;
/**
* #MongoDB\Int
*/
protected $start_time;
/**
* #MongoDB\Int
*/
protected $end_time;
/**
* #MongoDB\String
*/
protected $title;
/**
* #MongoDB\String
*/
protected $description;
/**
* #MongoDB\String
*/
protected $host;
/**
* #MongoDB\String
*/
protected $location;
/**
* #MongoDB\String
*/
protected $pic_square;
/**
* #MongoDB\EmbedOne(targetDocument="Coordinates")
*/
protected $coordinates=array();
/**
* #MongoDB\Int
* #MongoDB\Index(order="asc")
*/
protected $city_id;
/**
* #MongoDB\String
*/
protected $city_name;
/**
* #MongoDB\String
*/
protected $country;
/**
* #MongoDB\String
*/
protected $timezone;
/**
* #MongoDB\String
*/
protected $owner;
/**
* #MongoDB\Collection
* #MongoDB\Index(order="asc")
*/
protected $tags = array();
/**
* #MongoDB\EmbedOne(targetDocument="Event_status")
*/
protected $event_status = array();
/**
* Get id
*
* #return id $id
*/
public function getId()
{
return $this->id;
}
/**
* Set eid
*
* #param string $eid
*/
public function setEid($eid)
{
$this->eid = $eid;
}
/**
* Get eid
*
* #return string $eid
*/
public function getEid()
{
return $this->eid;
}
/**
* Set start_time
*
* #param int $startTime
*/
public function setStartTime($startTime)
{
$this->start_time = $startTime;
}
/**
* Get start_time
*
* #return int $startTime
*/
public function getStartTime()
{
return $this->start_time;
}
/**
* Set end_time
*
* #param int $endTime
*/
public function setEndTime($endTime)
{
$this->end_time = $endTime;
}
/**
* Get end_time
*
* #return int $endTime
*/
public function getEndTime()
{
return $this->end_time;
}
/**
* Set title
*
* #param string $title
*/
public function setTitle($title)
{
$this->title = $title;
}
/**
* Get title
*
* #return string $title
*/
public function getTitle()
{
return $this->title;
}
/**
* Set description
*
* #param string $description
*/
public function setDescription($description)
{
$this->description = $description;
}
/**
* Get description
*
* #return string $description
*/
public function getDescription()
{
return $this->description;
}
/**
* Set host
*
* #param string $host
*/
public function setHost($host)
{
$this->host = $host;
}
/**
* Get host
*
* #return string $host
*/
public function getHost()
{
return $this->host;
}
/**
* Set location
*
* #param string $location
*/
public function setLocation($location)
{
$this->location = $location;
}
/**
* Get location
*
* #return string $location
*/
public function getLocation()
{
return $this->location;
}
/**
* Set pic_square
*
* #param string $picSquare
*/
public function setPicSquare($picSquare)
{
$this->pic_square = $picSquare;
}
/**
* Get pic_square
*
* #return string $picSquare
*/
public function getPicSquare()
{
return $this->pic_square;
}
/**
* Set coordinates
*
* #param CE\MainBundle\Document\coordinates $coordinates
*/
public function setCoordinates(\CE\MainBundle\Document\Coordinates $coordinates)
{
$this->coordinates = $coordinates;
}
/**
* Get coordinates
*
* #return CE\MainBundle\Document\coordinates $coordinates
*/
public function getCoordinates()
{
return $this->coordinates;
}
/**
* Set city_id
*
* #param int $cityId
*/
public function setCityId($cityId)
{
$this->city_id = $cityId;
}
/**
* Get city_id
*
* #return int $cityId
*/
public function getCityId()
{
return $this->city_id;
}
/**
* Set city_name
*
* #param string $cityName
*/
public function setCityName($cityName)
{
$this->city_name = $cityName;
}
/**
* Get city_name
*
* #return string $cityName
*/
public function getCityName()
{
return $this->city_name;
}
/**
* Set country
*
* #param string $country
*/
public function setCountry($country)
{
$this->country = $country;
}
/**
* Get country
*
* #return string $country
*/
public function getCountry()
{
return $this->country;
}
/**
* Set timezone
*
* #param string $timezone
*/
public function setTimezone($timezone)
{
$this->timezone = $timezone;
}
/**
* Get timezone
*
* #return string $timezone
*/
public function getTimezone()
{
return $this->timezone;
}
/**
* Set owner
*
* #param int $owner
*/
public function setOwner($owner)
{
$this->owner = $owner;
}
/**
* Get owner
*
* #return int $owner
*/
public function getOwner()
{
return $this->owner;
}
/**
* Set tags
*
* #param collection $tags
*/
public function setTags($tags)
{
$this->tags = $tags;
}
/**
* Get tags
*
* #return collection $tags
*/
public function getTags()
{
return $this->tags;
}
/**
* Set event_status
*
* #param CE\MainBundle\Document\event_status $eventStatus
*/
public function setEventStatus(\CE\MainBundle\Document\Event_status $eventStatus)
{
$this->event_status = $eventStatus;
}
/**
* Get event_status
*
* #return CE\MainBundle\Document\event_status $eventStatus
*/
public function getEventStatus()
{
return $this->event_status;
}
public function setEvent($event){
$this->eid = $event['eid'];
$this->start_time = $event['start_time'];
$this->end_time = $event['end_time'];
$this->description = $event['description'];
$this->host = $event['host'];
$this->location = $event['location'];
$this->pic_square = $event['pic_square'];
$this->city_id = (int)$event['city_id'];
$this->city_name = $event['city_name'];
$this->country = $event['country'];
$this->timezone = $event['timezone'];
$this->owner = $event['owner'];
$this->title = $event['title'];
$this->tags = $event['tags'];
$loc=new Coordinates();
$loc->setLongitude($event['coordinates']['longitude']);
$loc->setLatitude($event['coordinates']['latitude']);
$this->coordinates = $loc;
$stat = new Event_status();
$stat->setAttendCount($event['event_status']['attend_count']);
$stat->setAttendList($event['event_status']['attend_list']);
$stat->setClickCount($event['event_status']['click_count']);
$this->event_status = $stat;
}
}
/**
* #MongoDB\EmbeddedDocument
*/
Class Coordinates{
/**
* #MongoDB\Float
*/
protected $longitude;
/**
* #MongoDB\Float
*/
protected $latitude;
/**
* Set longitude
*
* #param float $longitude
*/
public function setLongitude($longitude)
{
$this->longitude = $longitude;
}
/**
* Get longitude
*
* #return float $longitude
*/
public function getLongitude()
{
return $this->longitude;
}
/**
* Set latitude
*
* #param float $latitude
*/
public function setLatitude($latitude)
{
$this->latitude = $latitude;
}
/**
* Get latitude
*
* #return float $latitude
*/
public function getLatitude()
{
return $this->latitude;
}
}
/**
* #MongoDB\EmbeddedDocument
*/
Class Event_status{
/**
* #MongoDB\Int
*/
protected $attend_count;
/**
* #MongoDB\Int
* #MongoDB\Index(order="desc")
*/
protected $click_count;
/**
* #MongoDB\Collection
*/
protected $attend_list = array();
/**
* Set attend_count
*
* #param int $attendCount
*/
public function setAttendCount($attendCount)
{
$this->attend_count = $attendCount;
}
/**
* Get attend_count
*
* #return int $attendCount
*/
public function getAttendCount()
{
return $this->attend_count;
}
/**
* Set click_count
*
* #param int $clickCount
*/
public function setClickCount($clickCount)
{
$this->click_count = $clickCount;
}
/**
* Get click_count
*
* #return int $clickCount
*/
public function getClickCount()
{
return $this->click_count;
}
public function incClickCount($i){
$this->click_count = $this->click_count + $i;
}
/**
* Set attend_list
*
* #param collection $attendList
*/
public function setAttendList($attendList)
{
$this->attend_list = $attendList;
}
/**
* Get attend_list
*
* #return collection $attendList
*/
public function getAttendList()
{
return $this->attend_list;
}
}
And I am trying to persist following object
object(CE\MainBundle\Document\Event)#302 (17) {
["id":protected]=>
NULL
["eid":protected]=>
string(15) "116189838391483"
["start_time":protected]=>
int(1356069600)
["end_time":protected]=>
int(1356080400)
["title":protected]=>
string(38) "Sex on December 20, 2012 Just In Case"
["description":protected]=>
string(322) "Spread the word
Maps : http://maps.google.nl/maps?f=q&source=s_q&hl=nl&q=Vondelpark,+1071+AA+Oud-Zuid,+Amsterd%C3%A3,+Amsterdam,+Noord-Holland&sll=52.469397,5.509644&sspn=5.134105,16.907959&ie=UTF8&geocode=FR_rHgMdG0pKAA&split=0&hq=&hnear=1071+AA+Amsterdam,+Noord-Holland&ll=52.360231,4.873273&spn=0.010051,0.033023&z=16
"
["host":protected]=>
string(19) "Sébastien Carvalho"
["location":protected]=>
string(21) "Amsterdam, VondelPark"
["pic_square":protected]=>
string(89) "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-snc4/71137_116189838391483_7509117_q.jpg"
["coordinates":protected]=>
object(CE\MainBundle\Document\Coordinates)#344 (2) {
["longitude":protected]=>
float(4.88969)
["latitude":protected]=>
float(52.37403)
}
["city_id":protected]=>
int(2759794)
["city_name":protected]=>
string(9) "Amsterdam"
["country":protected]=>
string(11) "Netherlands"
["timezone":protected]=>
string(16) "Europe/Amsterdam"
["owner":protected]=>
string(10) "1345873725"
["tags":protected]=>
array(39) {
[0]=>
string(3) "sex"
[1]=>
string(6) "decemb"
[2]=>
string(4) "just"
[3]=>
string(4) "case"
[4]=>
string(6) "spread"
[5]=>
string(4) "word"
[6]=>
string(3) "map"
[7]=>
string(1) ":"
[8]=>
string(5) "http:"
[9]=>
string(5) "googl"
[10]=>
string(2) "nl"
[11]=>
string(1) "f"
[12]=>
string(1) "q"
[13]=>
string(5) "sourc"
[14]=>
string(0) ""
[15]=>
string(2) "hl"
[16]=>
string(10) "vondelpark"
[17]=>
string(2) "aa"
[18]=>
string(3) "oud"
[19]=>
string(4) "zuid"
[20]=>
string(7) "amsterd"
[21]=>
string(2) "c3"
[22]=>
string(2) "a3"
[23]=>
string(9) "amsterdam"
[24]=>
string(5) "noord"
[25]=>
string(7) "holland"
[26]=>
string(3) "sll"
[27]=>
string(4) "sspn"
[28]=>
string(2) "ie"
[29]=>
string(4) "utf8"
[30]=>
string(6) "geocod"
[31]=>
string(2) "fr"
[32]=>
string(11) "rhgmdg0pkaa"
[33]=>
string(5) "split"
[34]=>
string(2) "hq"
[35]=>
string(5) "hnear"
[36]=>
string(2) "ll"
[37]=>
string(3) "spn"
[38]=>
string(1) "z"
}
["event_status":protected]=>
object(CE\MainBundle\Document\Event_status)#305 (3) {
["attend_count":protected]=>
int(0)
["click_count":protected]=>
int(0)
["attend_list":protected]=>
array(0) {
}
}
}
Please tell me where is the error?

Symfony 2 Embedded forms using one to many db relationship

I'm have a problem embedding forms from different entities in one form, my form is being displayed with firstname [input] lastname [input] address - but the address has no input next to it.
Basically I want to create a form where the user can add first name, last name, address1, address2, city, country ect and submit it it as one, although it's different tables.
The main form is no problem the only issue I'm having is with the second embedded form. Any help would be greatly appreciated.
Here is my code:
Member class:
namespace Pomc\MembersBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Pomc\MembersBundle\Entity\Member
*/
class Member
{
/**
* #var integer $id
*/
private $id;
/**
* #var string $firstName
*/
private $firstName;
/**
* #var string $lastName
*/
private $lastName;
/**
* #var Pomc\MembersBundle\Entity\Address
*/
private $address;
/**
* #var Pomc\MembersBundle\Entity\Telephone
*/
private $telephone;
public function __construct()
{
$this->address = new \Doctrine\Common\Collections\ArrayCollection();
$this->telephone = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set firstName
*
* #param string $firstName
*/
public function setFirstName($firstName)
{
$this->firstName = $firstName;
}
/**
* Get firstName
*
* #return string
*/
public function getFirstName()
{
return $this->firstName;
}
/**
* Set lastName
*
* #param string $lastName
*/
public function setLastName($lastName)
{
$this->lastName = $lastName;
}
/**
* Get lastName
*
* #return string
*/
public function getLastName()
{
return $this->lastName;
}
/**
* Add address
*
* #param Pomc\MembersBundle\Entity\Address $address
*/
public function addAddress(\Pomc\MembersBundle\Entity\Address $address)
{
$this->address[] = $address;
}
/**
* Get address
*
* #return Doctrine\Common\Collections\Collection
*/
public function getAddress()
{
return $this->address;
}
/**
* Add telephone
*
* #param Pomc\MembersBundle\Entity\Telephone $telephone
*/
public function addTelephone(\Pomc\MembersBundle\Entity\Telephone $telephone)
{
$this->telephone[] = $telephone;
}
/**
* Get telephone
*
* #return Doctrine\Common\Collections\Collection
*/
public function getTelephone()
{
return $this->telephone;
}
}
Here is the address class:
namespace Pomc\MembersBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Pomc\MembersBundle\Entity\Address
*/
class Address
{
/**
* #var integer $id
*/
private $id;
/**
* #var string $addressType
*/
private $addressType;
/**
* #var string $firstLine
*/
private $firstLine;
/**
* #var string $secondLine
*/
private $secondLine;
/**
* #var string $city
*/
private $city;
/**
* #var string $postCode
*/
private $postCode;
/**
* #var string $country
*/
private $country;
/**
* #var Pomc\MembersBundle\Entity\Member
*/
private $member;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set addressType
*
* #param string $addressType
*/
public function setAddressType($addressType)
{
$this->addressType = $addressType;
}
/**
* Get addressType
*
* #return string
*/
public function getAddressType()
{
return $this->addressType;
}
/**
* Set firstLine
*
* #param string $firstLine
*/
public function setFirstLine($firstLine)
{
$this->firstLine = $firstLine;
}
/**
* Get firstLine
*
* #return string
*/
public function getFirstLine()
{
return $this->firstLine;
}
/**
* Set secondLine
*
* #param string $secondLine
*/
public function setSecondLine($secondLine)
{
$this->secondLine = $secondLine;
}
/**
* Get secondLine
*
* #return string
*/
public function getSecondLine()
{
return $this->secondLine;
}
/**
* Set city
*
* #param string $city
*/
public function setCity($city)
{
$this->city = $city;
}
/**
* Get city
*
* #return string
*/
public function getCity()
{
return $this->city;
}
/**
* Set postCode
*
* #param string $postCode
*/
public function setPostCode($postCode)
{
$this->postCode = $postCode;
}
/**
* Get postCode
*
* #return string
*/
public function getPostCode()
{
return $this->postCode;
}
/**
* Set country
*
* #param string $country
*/
public function setCountry($country)
{
$this->country = $country;
}
/**
* Get country
*
* #return string
*/
public function getCountry()
{
return $this->country;
}
/**
* Set member
*
* #param Pomc\MembersBundle\Entity\Member $member
*/
public function setMember(\Pomc\MembersBundle\Entity\Member $member)
{
$this->member = $member;
}
/**
* Get member
*
* #return Pomc\MembersBundle\Entity\Member
*/
public function getMember()
{
return $this->member;
}
}
Here is the memberform:
namespace Pomc\MembersBundle\Form\Type;
use \Symfony\Component\Form\AbstractType;
use \Symfony\Component\Form\FormBuilder;
class MemberType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('firstName');
$builder->add('lastName');
$builder->add('address','collection', array( 'type' => new AddressType(),
'allow_add' => true,
'prototype' => true,
'by_reference' => false,
));
}
public function getDefaultOptions(array $options)
{
return array('data_class' => 'Pomc\MembersBundle\Entity\Member');
}
/**
* Returns the name of this type.
*
* #return string The name of this type
*/
function getName()
{
return 'member';
}
}
Here is the address form:
namespace Pomc\MembersBundle\Form\Type;
use \Symfony\Component\Form\AbstractType;
use \Symfony\Component\Form\FormBuilder;
class AddressType extends AbstractType
{
public function buildForm(Formbuilder $builder, array $options)
{
$builder->add('firstLine');
}
public function getDefaultOptions(array $options)
{
return array('data_class' => 'Pomc\MembersBundle\Entity\Address');
}
/**
* Returns the name of this type.
*
* #return string The name of this type
*/
function getName()
{
return 'address';
}
function getIdentifier()
{
return 'address';
}
}
Here is the controller:
namespace Pomc\MembersBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use \Pomc\MembersBundle\Entity\Member;
use \Symfony\Component\HttpFoundation\Request;
use \Pomc\MembersBundle\Form\Type\MemberType;
class DefaultController extends Controller
{
public function indexAction($name)
{
return $this->render('PomcMembersBundle:Default:index.html.twig', array('name' => $name));
}
public function newAction(Request $request)
{
$member = new Member();
$form = $this->get('form.factory')->create(new MemberType());
if($request->getMethod() == 'POST')
{
$form->bindRequest($request);
if($form->isValid())
{
$em = $this->getDoctrine()->getEntityManager();
$em->persist($member);
$em->flush();
}
}
return $this->render('PomcMembersBundle:Default:new.html.twig', array( 'form'=> $form->createView(),));
}
}
Here is the template:
<form action="{{ path('member_new') }}" method="post" {{ form_enctype(form)}}>
{{ form_widget(form) }}
<div>
{{ form_row(form.address)}}
</div>
<input type="submit" />
</form>
Been a long time user of this site, but this is my first question.
Thank you
Oh I faced the same problem, but I found the solution, hope this will help you :-)
You're forgetting to add an Address object to the member entity.
In your action you'll need to do the following:
$member = new Member();
$member->addAddress(new Address());
$form = $this->createForm(new MemberType(), $member);
And then in your template:
{% for address in form.address %}
{{ form_widget(address.firstLine) }}
{% endfor %}
Btw your 'firstline' widget doesn't relate to an entity property.
Btw if you called addAddress two times, you would of course get two 'firstline' widgets in your form.
Hope this works. best of luck.
Llewellyn, do you mean something like thid:
public function editAction($id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('imBundle:Inspecciones')->find($id);
$entity_valores = $em->getRepository('imBundle:ValoresInspecciones')->findByInspecciones($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Inspecciones entity.');
}
$entity->setValoresInspecciones($entity_valores);
$editForm = $this->createEditForm($entity);
$deleteForm = $this->createDeleteForm($id);
return $this->render('imBundle:Inspecciones:edit.html.twig', array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}