JMS Deserialize ArrayCollection in Object - php

I'm trying to use JMS serializer in my application (not Symfony) and would like to deserialize a JSON object to the Doctrine Entity.
The plain properties are getting properly deserialized, but I can't get the ArrayCollections to work.
This is an excerpt of my product JSON:
{
"id": 2,
"name": "Shirt blue",
"attributeValues": [
{
"id": 4,
"title": "S",
"attributeId": 2
},
{
"id": 7,
"title": "Eterna",
"attributeId": 3
}
]
}
This is my Product entity:
<?php
namespace Vendor\App\Common\Entities;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as JMS;
/**
* #ORM\Entity
* #ORM\HasLifecycleCallbacks
* #ORM\Table(name="product")
* #JMS\ExclusionPolicy("all")
*/
class Product extends AbstractEntity {
/**
* #var int $id
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
* #ORM\Column(name="id", type="integer", nullable=false)
* #JMS\Groups({"search"})
* #JMS\Expose
* #JMS\Type("integer")
*/
protected $id;
/**
* #var string $name
* #ORM\Column(name="name", type="string", nullable=false)
* #JMS\Expose
* #JMS\Groups({"search"})
* #JMS\Type("string")
*/
protected $name;
/**
* #var ArrayCollection $attributeValues
* #ORM\ManyToMany(targetEntity="Vendor\App\Common\Entities\Attribute\Value")
* #ORM\JoinTable(name="products_values",
* joinColumns={#ORM\JoinColumn(name="product_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="value_id", referencedColumnName="id")}
* )
* #JMS\Expose
* #JMS\MaxDepth(2)
* #JMS\Groups({"search"})
* #JMS\Type("ArrayCollection<Vendor\App\Common\Entities\Attribute\Value>")
*/
protected $attributeValues;
public function __construct() {
$this->attributeValues = new ArrayCollection();
}
/**
* #return ArrayCollection
*/
public function getAttributeValues() {
return $this->attributeValues;
}
/**
* #param ArrayCollection $attributeValues
*/
public function setAttributeValues($attributeValues) {
$this->attributeValues = $attributeValues;
}
/**
* #param Value $attributeValue
*/
public function addAttributeValue($attributeValue) {
$this->attributeValues->add($attributeValue);
}
/**
* #param Value $attributeValue
*/
public function removeAttributeValue($attributeValue) {
$this->attributeValues->removeElement($attributeValue);
}
}
This is my Value entity that should be deserialized in the ArrayCollection:
<?php
namespace Vendor\App\Common\Entities\Attribute;
use Vendor\App\Common\Entities\AbstractEntity,
Doctrine\ORM\Mapping as ORM,
JMS\Serializer\Annotation as JMS;
/**
* #ORM\Entity
* #ORM\Table(name="attribute_value")
* #JMS\ExclusionPolicy("all")
*/
class Value extends AbstractEntity {
/**
* #var int $id
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
* #ORM\Column(name="id", type="integer", nullable=false)
* #JMS\Expose
* #JMS\Groups({"search"})
* #JMS\Type("integer")
*/
protected $id;
/**
* #var string $title
* #ORM\Column(name="title", type="string", nullable=false)
* #JMS\Expose
* #JMS\Groups({"search"})
* #JMS\Type("string")
*/
protected $title;
/**
* #var int $attributeId
* #ORM\Column(name="attribute_id", type="integer", nullable=false)
* #JMS\Expose
* #JMS\Groups({"search"})
* #JMS\Type("integer")
*/
protected $attributeId;
/**
* OWNING SIDE
* #var \Vendor\App\Common\Entities\Attribute $attribute
* #ORM\ManyToOne(targetEntity="Vendor\App\Common\Entities\Attribute", inversedBy="values")
* #ORM\JoinColumn(name="attribute_id", referencedColumnName="id")
* #JMS\Expose
* #JMS\Groups({"search"})
* #JMS\Type("Vendor\App\Common\Entities\Attribute")
*/
protected $attribute;
//Getters and setters ...
}
Just trying to simply deserialize the entity:
$serializer = SerializerBuilder::create()->build();
$entity = $serializer->deserialize($sourceJson, Product::class, 'json');
But the attributeValue ArrayCollection stays empty. What am I missing?

I found the solution. JMS has a default naming strategy which converts camelcase to underscore notation.
Default is that the naming strategy either looks for the annotation #SerializedName and if that is not set, it will convert CamelCase to underscore.
So the property just got ignored because it didn't match the expected name. Of course, it would be better if there was an error or a notification which gives a hint here on where to search for the problem (something like unknown property would have been nice).
$serializer = SerializerBuilder::create()->setPropertyNamingStrategy(new IdenticalPropertyNamingStrategy())->build();
Was the solution.

Related

doctrine how to merge incomplete data

I'm creating an REST api with Symfony 4.2 and Doctrine as ORM connected to a MySQL database. I receive data in JSON , deserialize them with JMSSerializer and use the doctrine merge function to attach it. How can I merge the entity I got from the JSON with an already existing entity, updating only the given fields in the JSON?
Event entity
<?php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation\Type;
/**
* Event
*
* #ORM\Table(name="Event", indexes={#ORM\Index(name="Organiser", columns={"Organiser"})})
* #ORM\Entity
*/
class Event
{
/**
* #var int
*
* #ORM\Column(name="ID", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue
* #Type("int")
*/
private $id;
/**
* #var \Invited
*
* #ORM\OneToMany(targetEntity="Invited",mappedBy="event",cascade={"persist","merge","remove"})
* #Type("ArrayCollection<App\Entity\Invited>")
*/
private $guests;
/**
* #var string
*
* #ORM\Column(name="Title", type="string", length=255, nullable=false)
* #Type("string")
*/
private $title;
/**
* #var \DateTime
*
* #ORM\Column(name="StartDate", type="datetime", nullable=false)
* #Type("DateTime")
*/
private $startdate;
/**
* #var \DateTime|null
*
* #ORM\Column(name="EndDate", type="datetime", nullable=true)
* #Type("DateTime")
*/
private $enddate;
/**
* #var string
*
* #ORM\Column(name="Place", type="string", length=255, nullable=false)
* #Type("string")
*/
private $place;
/**
* #var string|null
*
* #ORM\Column(name="ImagePath", type="string", length=255, nullable=true)
* #Type("string")
*/
private $imagepath;
/**
* #var \User
*
* #ORM\ManyToOne(targetEntity="User",cascade={"persist"})
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="Organiser", referencedColumnName="ID")
* })
* #Type("App\Entity\User")
*/
private $organiser;
?>
Deserialisation
$json = $request->getContent();
$serializer = SerializerBuilder::create()->build();
$event = $serializer->deserialize($json,'App\Entity\Event','json');
Merging
$feedback = $this->em->merge($newEvent);
$this->em->flush();
Expected vs Actual results:
If I have an already existing and attached event like:
{
id:1,
title: 'oldTitle',
startDate: oldDate,
place: 'oldPlace',
...
}
And I receive :
{
id:1,
title: 'newTitle'
}
Expected result:
{
id:1,
title: 'newTitle',
startDate: oldDate,
place: 'oldPlace',
...
}
Actual result when looking to the database:
{
id:1,
title: 'newTitle',
startDate: null,
place: null,
...
}
How can I achieve that in a efficient way?

Files storage with doctrine and symfony 3?

I need help for create my entities whit doctrine 2 in my symfony3 app :
I would like my users can posts articles which content is:
title
author
either one unique image (upload file)
or one unique movie ($url)
What do you recommend ?
Should I build my article entity like this ?
class Article
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var integer
*
* #ORM\Column(name="author", type="integer")
*/
private $author;
/**
* #var ?
*
* #ORM\Column(name="image", type="?")
*/
private $image;
/**
* #var string
*
* #ORM\Column(name="url_movie", type="string")
*/
private $url_movie;
/**
* #var integer
*
* #ORM\Column(name="media", type="integer")
*/
private $media;
}
(in controller : if $media = 1 => this is an image, else this is a video)
Or use something like Relation One-To-One with a new entity "media" for example ?
What is the best way for my case ?
Yes, it's normal. Sadly, the discriminator column is meant to be used by Doctrine, database side, therefore it's not accessible in your entity. There's two possible way to achieve what you want:
The first, using the children class name:
/**
* Article
*
* #ORM\Table(name="article")
* #ORM\Entity(repositoryClass="PM\PlatformBundle\Repository\ArticleRepository")
* #ORM\InheritanceType("SINGLE_TABLE")
* #ORM\DiscriminatorColumn(name="media", type="string")
* #ORM\DiscriminatorMap({"article" = "Article", "movie" = "Movie", "image" = "Image"})
*/
class Article
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=255)
*/
private $title;
//...
/**
* Get article type.
*
* #return string
*/
public function getType()
{
// This will return "movie" or "image"
return strtolower(substr(strrchr(get_class($this), "\\"), 1));
}
}
/**
* Movie
*
* #ORM\Entity
*/
class Movie extends Article
{
/**
* #var string
*
* #ORM\Column(name="url", type="text")
*/
private $url;
//getter setter
}
/**
* Image
*
* #ORM\Entity
*/
class Image extends Article
{
/**
* #var string
*
* #ORM\Column(name="path", type="string", length=255)
*/
private $path;
//getter setter
}
The second, by declaring manually the type in your class:
/**
* Article
*
* #ORM\Table(name="article")
* #ORM\Entity(repositoryClass="PM\PlatformBundle\Repository\ArticleRepository")
* #ORM\InheritanceType("SINGLE_TABLE")
* #ORM\DiscriminatorColumn(name="media", type="string")
* #ORM\DiscriminatorMap({"article" = "Article", "movie" = "Movie", "image" = "Image"})
*/
class Article
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=255)
*/
private $title;
/**
* #var string
*/
protected $type;
//...
/**
* Get article type.
*
* #return string
*/
public function getType()
{
return $this->type;
}
}
/**
* Movie
*
* #ORM\Entity
*/
class Movie extends Article
{
/**
* #var string
*
* #ORM\Column(name="url", type="text")
*/
private $url;
public function __construct()
{
$this->type = 'movie';
}
//getter setter
}
/**
* Image
*
* #ORM\Entity
*/
class Image extends Article
{
/**
* #var string
*
* #ORM\Column(name="path", type="string", length=255)
*/
private $path;
public function __construct()
{
$this->type = 'image';
}
//getter setter
}
Personnaly, I have a preference for the first solution. I find it cleaner, and more evolutive (this code will adapt if you have to add a third article type).
Of course, you can also use instanceof to determine which subclass is the Article entity you're manipulating.
I think using a Media entity and handling the media type in the Media entity is the best way.
class Article
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
// ...
/**
* #var Media
*
* #OneToOne(targetEntity="Media")
* #ORM\JoinColumn(name="media_id", referencedColumnName="id")
*/
private $media;
}
class Media
{
const TYPE_IMAGE = 'image';
const TYPE_MOVIE = 'movie';
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(type="string")
*/
private $url;
/**
* #var string
*
* #ORM\Column(type="string")
*/
private $type;
}
An other way to do it could be to use entity inheritance to have differents entities for images and movies - if you need to.
Ok I did a Single Table Inheritance on my article class :
/**
* Article
*
* #ORM\Table(name="article")
* #ORM\Entity(repositoryClass="PM\PlatformBundle\Repository\ArticleRepository")
* #ORM\InheritanceType("SINGLE_TABLE")
* #ORM\DiscriminatorColumn(name="media", type="string")
* #ORM\DiscriminatorMap({"article" = "Article", "movie" = "Movie", "image" = "Image"})
*/
class Article
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=255)
*/
private $title;
//...
}
/**
* Movie
*
* #ORM\Entity
*/
class Movie extends Article
{
/**
* #var string
*
* #ORM\Column(name="url", type="text")
*/
private $url;
//getter setter
}
/**
* Image
*
* #ORM\Entity
*/
class Image extends Article
{
/**
* #var string
*
* #ORM\Column(name="path", type="string", length=255)
*/
private $path;
//getter setter
}
That works great !

Zend Framework 2 Doctrine2 leftJoin creating a separate SELECT query

Does anyone know why the Doctrine query below creates a separate join for the StandardDedescribed entity?
As you can see below this query pulls the information from the master entity 'EquipmentUK' and two related tables: 'SchemaInfo' and 'StandardDescribed'. It works well for the SchemaInfo, but creates another query for StandardDescribed. The relations in the Entities seem to be coded extactly the same, so I don't understand why it behaves differently for StandardDescribed?
$qb->select('e')
->from('\Lookup\Entity\Fullhistory\EquipmentUK', 'e')
->leftJoin(
'\Lookup\Entity\Fullhistory\SchemaInfo',
'si',
Expr\Join::WITH,
'e.schema_id = si.schema_id AND si.parent_schema_id != si.schema_id'
)
->leftJoin(
'\Lookup\Entity\Intelligence\StandardDescribedUK',
'sd',
Expr\Join::WITH,
'e.schema_id = sd.schema_id'
)
->where($qb->expr()->eq('e.vehicle_id', '?1'))
->setParameter(1, $jatoid);
Here are the Entities:
EquipmentUK:
namespace Lookup\Entity\Fullhistory;
use Doctrine\ORM\Mapping as ORM;
/**
* EquipmentUK
*
* #ORM\Table(name="equipment",
* uniqueConstraints={
* #ORM\UniqueConstraint(name="search_idx", columns={"vehicle_id", "option_id", "record_id", "schema_id"})
* }
* )
* #ORM\Entity
*/
class EquipmentUK
{
/**
* #var integer
*
* #ORM\Id
* #ORM\Column(type="integer")
*/
private $vehicle_id;
/**
* #var integer
*
* #ORM\Id
* #ORM\Column(type="integer")
*/
private $schema_id;
/**
* #var integer
*
* #ORM\Id
* #ORM\Column(type="integer")
*/
private $option_id;
/**
* #var integer
*
* #ORM\Id
* #ORM\Column(type="integer")
*/
private $record_id;
/**
* #var string
*
* #ORM\Column(type="string")
*/
private $location;
/**
* #ORM\ManyToOne(targetEntity="Lookup\Entity\Fullhistory\SchemaInfo", cascade={"all"}, fetch="EAGER")
* #ORM\JoinColumn(name="schema_id", referencedColumnName="schema_id")
*/
private $schemaInfo;
/**
* #ORM\ManyToOne(targetEntity="Lookup\Entity\Intelligence\StandardDescribedUK", cascade={"all"}, fetch="EAGER")
* #ORM\JoinColumn(name="schema_id", referencedColumnName="schema_id")
*/
private $standardDescribed;
/**
* #var string
*
* #ORM\Column(type="string")
*/
private $data_value;
public function getVehicleId()
{
return $this->vehicle_id;
}
public function getSchemaId()
{
return $this->schema_id;
}
public function getOptionId()
{
return $this->option_id;
}
public function getRecordId()
{
return $this->record_id;
}
public function getLocation()
{
return $this->location;
}
public function getSchemaInfo()
{
return $this->schemaInfo;
}
public function getStandardDescribed()
{
return $this->standardDescribed;
}
public function getDataValue()
{
return $this->data_value;
}
}
SchemaInfo:
namespace Lookup\Entity\Fullhistory;
use Doctrine\ORM\Mapping as ORM;
/**
* SchemaInfo
*
* #ORM\Table(name="schema_info")
* #ORM\Entity
*/
class SchemaInfo
{
/**
* #var integer
*
* #ORM\Column(name="schema_id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $schema_id;
/**
* #var integer
*
* #ORM\Column(name="parent_schema_id", type="integer", nullable=true)
*/
private $parent_schema_id;
/**
* #var integer
*
* #ORM\Column(name="location_schema_id", type="integer", nullable=true)
*/
private $locationSchemaId;
/**
* #var integer
*
* #ORM\Column(name="scale_of_data", type="smallint", nullable=true)
*/
private $scaleOfData;
/**
* #var integer
*
* #ORM\Column(name="data_type", type="smallint", nullable=true)
*/
private $dataType;
public function getSchemaId()
{
return $this->schema_id;
}
public function getParentSchemaId()
{
return $this->parent_schema_id;
}
}
StandardDescribedUK
namespace Lookup\Entity\Intelligence;
use Doctrine\ORM\Mapping as ORM;
/**
* StandardDescribedUK
*
* #ORM\Table(name="jato_uk_intelligence.standard_described")
* #ORM\Entity
*/
class StandardDescribedUK
{
/**
* #var integer
*
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $schema_id;
/**
* #var string
*
* #ORM\Column(name="category", type="string", nullable=true)
*/
private $category;
public function getCategory()
{
return $this->category;
}
}
Your joins should use Doctrine's own relational schema: your EquipmentUK has declared its relation with SchemaInfo via the property $schemaInfo, and it has also declared its relation with StandardDescribedUK via $standardDescribed. So:
$qb->select('e')
->from('\Lookup\Entity\Fullhistory\EquipmentUK', 'e')
->leftJoin(
'e.schemaInfo',
'si'
//we don't need that third param as the relation is already known
)
->leftJoin(
'e.standardDescribed',
'sd'
//same here, no need for explicit relation
)
->where($qb->expr()->eq('e.vehicle_id', ':vehicle'))
//this here is a restriction, should be in WHERE instead of ON
->andWhere($qb->expr()->neq('si.parent_schema_id', 'si.schema_id'))
->setParameter('vehicle', $jatoid);
Hope this helps!

Join tables via doctrine find

I'm trying to use the EntityManager to load all fields from a table as well as its associations, here's my (test) scenario: I have the entity user and the entity user_post, and the user can have several user_post.
user:
use Doctrine\ORM\Mapping as ORM;
/** #ORM\Entity */
class user
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="bigint")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
public $id;
/**
* #ORM\OneToMany(targetEntity="user_post", mappedBy="id_user", cascade={"persist", "remove"}, orphanRemoval=TRUE, fetch="EAGER")
*/
public $posts;
/**
* #var string $author
*
* #ORM\Column(name="author", type="string", length=100, nullable=false)
*/
public $author;
/**
* #var text $content
*
* #ORM\Column(name="content", type="text", nullable=false)
*/
public $content;
/**
* #var text $createdAt
*
* #ORM\Column(name="created_at", type="text", nullable=false)
*/
public $createdAt;
public function __construct() {
$this->posts = new ArrayCollection();
}
}
user_post:
use Doctrine\ORM\Mapping as ORM;
/** #ORM\Entity */
class user_post
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="bigint")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
public $id;
/**
* #var integer $id_user
*
* #ORM\ManyToOne(targetEntity="user", inversedBy="posts")
* #ORM\JoinColumn(name="id_user", referencedColumnName="id", nullable=FALSE)
*/
public $id_user;
/**
* #var text $content
*
* #ORM\Column(name="content", type="text", nullable=false)
*/
public $content;
}
I'm using public variables to be easier to debug.
Now, I'm trying:
$user = $doctrine->em->find('user', 2);
I get the user object ok, however instead the user_post object it returns:
Doctrine\ORM\PersistentCollection Object ( [snapshot:Doctrine\ORM\PersistentCollection:private] => Array ( [0] => user_post Object ( [id] => 1 [id_user] => user Object *RECURSION*
And doesn't return the actual data. Also it returns a giant array.
Is there a way to get all the data with the find function?
Your $posts property is mapped as a OneToMany, which means that a user will have many user_post.
Therefore $posts is hydrated as a collection of user_post objects, which contains the objects you expect:
$user = $doctrine->em->find('user', 2);
foreach ($user->posts as $post) {
echo $post->content;
}

Doctrine2 Association Persistence

I've been playing around with Zend and Doctrine incorporated into it for the past week or so. I've gotten the hang of basic inserts and selects, and can also use DQL to select from joined tables. The problem I'm having is persisting associated entities. Error I'm getting is this: (path)htdocs\vendor\doctrine\common\lib\Doctrine\Common\Persistence\Mapping\MappingException.php:96 with the message 'Class "" does not exist'.
My code is below...
Here is the main entity (the one on the "many" side)
namespace Project\Entity;
use Doctrine\ORM\Mapping as ORM;
use Zend\InputFilter\Factory as InputFactory;
/**
* ClientUser
*
* #ORM\Table()
* #ORM\Entity
*/
class ClientUser extends SystemUser
{
/**
* #var integer
*
* #ORM\OneToOne(targetEntity="SystemUser", cascade={"persist", "remove"})
* #ORM\JoinColumn(name="id", referencedColumnName="id")
*/
private $id;
/**
* #var integer
*
* #ORM\ManyToOne(targetEntity="Client", cascade={"persist", "remove"})
* #ORM\JoinColumn(name="client", referencedColumnName="id")
*/
private $client;
protected $_inputFilter;
//Other stuff here...
}
Here is the "Client" associated entity...
namespace Project\Entity;
use Doctrine\ORM\Mapping as ORM;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\Factory as InputFactory;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFilterInterface;
/**
* Client
*
* #ORM\Table()
* #ORM\Entity
*/
class Client implements InputFilterAwareInterface
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="client_name", type="string", length=255)
*/
private $clientName;
/**
* #var integer
*
* #ORM\Column(name="loggable_hours", type="integer")
*/
private $loggableHours;
/**
* #var float
*
* #ORM\Column(name="normal_rate", type="decimal", scale=2)
*/
private $normalRate;
/**
* #var float
*
* #ORM\Column(name="critical_rate", type="decimal", scale=2)
*/
private $criticalRate;
/**
* #var string
*
* #ORM\Column(name="start_date", type="string")
*/
private $startDate;
/**
* #var boolean
*
* #ORM\Column(name="enabled", type="boolean")
*/
private $enabled;
/**
* #var integer
*
* #ORM\Column(name="critical_hours", type="integer")
*/
private $criticalHours;
/**
*
* #var type
*/
protected $_inputFilter;
//Other stuff (getters,setters, etc)
}
The ClientUser has a one-to-one relationship with the following:
namespace Project\Entity;
use Doctrine\ORM\Mapping as ORM;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\Factory as InputFactory;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFilterInterface;
/**
* SystemUser
*
* #ORM\Table()
* #ORM\Entity
* #ORM\InheritanceType("JOINED")
* #ORM\DiscriminatorColumn(name="user_type", type="integer")
* #ORM\DiscriminatorMap({1 = "DeveloperUser", 2 = "ClientUser"})
*
*/
class SystemUser implements InputFilterAwareInterface {
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="username", type="string", length=100, unique=true)
*/
private $username;
/**
* #var string
*
* #ORM\Column(name="password", type="string", length=255)
*/
private $password;
/**
* #var string
*
* #ORM\Column(name="user_first_name", type="string", length=255)
*/
private $userFirstName;
/**
* #var string
*
* #ORM\Column(name="user_surname", type="string", length=255)
*/
private $userSurname;
/**
* #ORM\Column(type="string", length=32)
*/
private $salt;
/**
* #var \DateTime
*
* #ORM\Column(name="last_login", type="datetime")
*/
private $lastLogin = '0000-00-00 00:00:00';
/**
* #var bool
*
* #ORM\Column(name="enabled", type="boolean", options={"default" = 1})
*/
private $enabled = 1;
/**
* For the input filter...
*
* #var InputFilter
*/
protected $_inputFilter;
//The rest...
}
I have absolutely no idea what could be wrong here... Just for completeness, here is the controller "add" action...
public function addAction() {
//To add clients
$form = new ClientUserForm($this->getServiceLocator()
->get('Doctrine\ORM\EntityManager'));
$form->get('submit')->setValue('Add');
$request = $this->getRequest();
if ($request->isPost()) {
$clientUser = new ClientUser();
$form->setInputFilter($clientUser->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
$clientUser->populate($form->getData());
/**
*This bottom line is where I get the exception!
*/
$this->getEntityManager()->persist($clientUser);
$this->getEntityManager()->flush();
//Redirect
return $this->redirect()->toRoute('client_user');
}
}
return array ('form' => $form);
}
Any help would be awesome! If I just knew which class "" is supposed to be, I'd probably be in a better place than I am now!
Thanks ladies and gents, you guys rock!
EDIT-
Forgot to add these 2 PHP warnings...
Warning: spl_object_hash() expects parameter 1 to be object, integer given in (path)\htdocs\vendor\doctrine\orm\lib\Doctrine\ORM\UnitOfWork.php on line 1588
Warning: get_class() expects parameter 1 to be object, integer given in (path)\vendor\doctrine\orm\lib\Doctrine\ORM\UnitOfWork.php on line 1596
Im not sure of what could be happening, but i find something that i dont understand. When you states the inheritance, you use:
* #ORM\DiscriminatorColumn(name="user_type", type="integer")
* #ORM\DiscriminatorMap({1 = "DeveloperUser", 2 = "ClientUser"})
but
there isnt a class called DeveloperUser
and also
are you sure that in the database, all user_type are just 1 or 2? (no null, not 0, etc)

Categories