I have an api in symfony2, in which adding and deleting items is not issue, however, updating doesn't throw me any errors however the relevent row in my database does not get updated!
My Controller method:
/*
* #Route("/complete/uid/{storeUid}",
* name = "media_complete"
* )
*
* #Method({"GET"})
*
* #param String $storeUid - the uid for the store that has completed downloading
*
* #return Response
*/
public function downloadCompleteAction($storeUid)
{
$response = $this->getNewJsonResponse();
$em = $this->getDoctrine()->getManager();
$repo = $em->getRepository("SimplySmartUHDProBundle:Machine");
try {
//get the machine from the db
$machine = $repo->findOneBy(array(
"uid" => $storeUid
));
//set it as download completed
$machine->setStatus(Machine::STATUS_DOWNLOAD_COMPLETE);
$em->persist($machine);
$em->flush();
$response->setStatusCode(200);
} catch (\Exception $e) {
//if there is an error, catch the exception set the status to 500 and return json with the exception error
$error = array("message" => $e->getMessage());
$response->setContent(json_encode($error));
$response->setStatusCode(500);
}
return $response;
}
My Entity:
namespace SimplySmart\UHDProBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use SimplySmart\UHDProBundle\Entity\Store;
/**
* Machine
*
* #ORM\Table(name="Machines", uniqueConstraints={#ORM\UniqueConstraint(name="UID", columns={"UID"})})
* #ORM\Entity
*/
class Machine
{
const STATUS_NO_FEED = 0;
const STATUS_REQUIRES_DOWNLOAD = 1;
const STATUS_DOWNLOAD_IN_PROGRESS = 2;
const STATUS_DOWNLOAD_COMPLETE = 3;
/**
* Array of available statuses
*
* #var array
*/
static public $statuses = array(
self::STATUS_NO_FEED,
self::STATUS_REQUIRES_DOWNLOAD,
self::STATUS_DOWNLOAD_IN_PROGRESS,
self::STATUS_DOWNLOAD_COMPLETE
);
/**
* #var string
*
* #ORM\Column(name="UID", type="string", length=50, nullable=false)
*/
private $uid;
/**
* #var string
*
* #ORM\Column(name="StoreCode", type="string", length=10, nullable=false)
*/
private $storecode;
/**
* #var string
*
* #ORM\Column(name="Description", type="string", length=100, nullable=true)
*/
private $description;
/**
* #var boolean
*
* #ORM\Column(name="Status", type="boolean", nullable=false)
*/
private $status;
/**
* #var boolean
*
* #ORM\Column(name="OnlineStatus", type="boolean", nullable=false)
*/
private $onlinestatus;
/**
* #var string
*
* #ORM\Column(name="Version", type="string", length=10, nullable=false)
*/
private $version;
/**
* #var \DateTime
*
* #ORM\Column(name="Timestamp", type="datetime", nullable=false)
*/
private $timestamp;
/**
* #ORM\ManyToOne(targetEntity="SimplySmart\UHDProBundle\Entity\Store", inversedBy="machines")
* #ORM\JoinColumn(name="StoreCode", referencedColumnName="Code")
*/
protected $store;
/**
* #ORM\ManyToMany(targetEntity="SimplySmart\UHDProBundle\Entity\Feed", inversedBy="machines")
* #ORM\JoinTable(joinColumns={#ORM\JoinColumn(name="machine_id", referencedColumnName="MachID")},
* inverseJoinColumns={#ORM\JoinColumn(name="feed_id", referencedColumnName="FeedID")}
* )
*
*/
protected $feeds;
/**
* #var integer
*
* #ORM\Column(name="MachID", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $machid;
/**
*
*/
public function __construct()
{
$this->feeds = new ArrayCollection();
}
/**
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* #param string $description
*
* #return $this
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* #return string
*/
public function getFeedtype()
{
return $this->feedtype;
}
/**
* #param string $feedtype
*
* #return $this
*/
public function setFeedtype($feedtype)
{
$this->feedtype = $feedtype;
return $this;
}
/**
* #return int
*/
public function getMachid()
{
return $this->machid;
}
/**
* #param int $machid
*
* #return $this
*/
public function setMachid($machid)
{
$this->machid = $machid;
return $this;
}
/**
* #return boolean
*/
public function isOnlinestatus()
{
return $this->onlinestatus;
}
/**
* #param boolean $onlinestatus
*
* #return $this
*/
public function setOnlinestatus($onlinestatus)
{
$this->onlinestatus = $onlinestatus;
return $this;
}
/**
* #return boolean
*/
public function isStatus()
{
return $this->status;
}
/**
* #param boolean $status
*
* #throws \Exception if invalid status is given
*
* #return $this
*/
public function setStatus($status)
{
if (in_array($status, self::$statuses)) {
$this->status = $status;
} else {
throw new \Exception("invalid status given");
}
return $this;
}
/**
* #return string
*/
public function getStorecode()
{
return $this->storecode;
}
/**
* #param string $storecode
*
* #return $this
*/
public function setStorecode($storecode)
{
$this->storecode = $storecode;
return $this;
}
/**
* #return \DateTime
*/
public function getTimestamp()
{
return $this->timestamp;
}
/**
* #param \DateTime $timestamp
*
* #return $this
*/
public function setTimestamp($timestamp)
{
$this->timestamp = $timestamp;
return $this;
}
/**
* #return string
*/
public function getUid()
{
return $this->uid;
}
/**
* #param string $uid
*
* #return $this
*/
public function setUid($uid)
{
$this->uid = $uid;
return $this;
}
/**
* #return string
*/
public function getVersion()
{
return $this->version;
}
/**
* #param string $version
*
* #return $this
*/
public function setVersion($version)
{
$this->version = $version;
return $this;
}
/**
* Get status
*
* #return boolean
*/
public function getStatus()
{
return $this->status;
}
/**
* Get onlinestatus
*
* #return boolean
*/
public function getOnlinestatus()
{
return $this->onlinestatus;
}
/**
* Set store
*
* #param \SimplySmart\UHDProBundle\Entity\Store $store
* #return Machine
*/
public function setStore(\SimplySmart\UHDProBundle\Entity\Store $store = null)
{
$this->store = $store;
return $this;
}
/**
* Get store
*
* #return \SimplySmart\UHDProBundle\Entity\Store
*/
public function getStore()
{
return $this->store;
}
/**
* Method to generate and set a new UID
*
* #return $this
*/
public function generateNewUid()
{
$date = new \DateTime("UTC");
$uid = "U";
$uid .= $date->format("U");
$uid .= 'R'.rand(0,100);
$this->setUid($uid);
return $this;
}
/**
* Add feeds
*
* #param \SimplySmart\UHDProBundle\Entity\Feed $feeds
* #return Machine
*/
public function addFeed(\SimplySmart\UHDProBundle\Entity\Feed $feeds)
{
$this->feeds[] = $feeds;
return $this;
}
/**
* Remove feeds
*
* #param \SimplySmart\UHDProBundle\Entity\Feed $feeds
*/
public function removeFeed(\SimplySmart\UHDProBundle\Entity\Feed $feeds)
{
$this->feeds->removeElement($feeds);
}
/**
* Get feeds
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getFeeds()
{
return $this->feeds;
}
}
I am fully aware that when updating an entity I shouldn't need to use $em->persist($machine), however removing this doesn't seem to make any difference.
The part that is really grinding my gears, is that when I go on the profiler, it appears as it is ran all the queries as expected!
Just realised that I've been a complete idiot and my issue is that status is set as a boolean field in my entity, so it was updating, but always setting it as 1!
Related
I'm working in symfony 3.3:
I need to add the #Groups annotation to the slug field (created using ORMBehaviors\Sluggable\Sluggable) so I can pass this field through other entities that I will specify in the Groups.
How can I do this?
this is the entity 'foo':
/**
* #var int
*
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*
* #Groups({"advertisingSpace"})
*/
private $id;
/**
* #var string
*
* #ORM\Column(type="string", length=4)
*
* #Groups({"advertisingSpace"})
*/
private $code;
/**
* #var string
*
* #ORM\Column(type="string", length=255)
*
* #Groups({"advertisingSpace"})
*/
private $description;
/**
* #Vich\UploadableField(mapping="advertisingspacecategory_icon", fileNameProperty="icon")
*
* #var File
*/
private $iconFile;
/**
* #var string
*
* #ORM\Column(type="string", length=255)
*
* #Groups({"advertisingSpace"})
*/
private $icon;
/**
* #var array
*
* #ORM\OneToMany(
* targetEntity="AppBundle\Entity\AdvertisingSpace",
* mappedBy="category"
* )
*/
private $advertisingSpaces;
/**
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* #return string
*/
public function getIcon()
{
return $this->icon;
}
/**
* #param string $icon
*
* #return AdvertisingSpaceCategory
*/
public function setIcon($icon)
{
$this->icon = $icon;
return $this;
}
/**
* #param File|\Symfony\Component\HttpFoundation\File\UploadedFile $iconFile
*
* #return AdvertisingSpaceCategory
*/
public function setIconFile(File $iconFile = null)
{
$this->iconFile = $iconFile;
if ($iconFile) {
$this->updatedAt = new \DateTimeImmutable();
}
return $this;
}
/**
* #return File|null
*/
public function getIconFile()
{
return $this->iconFile;
}
/**
* #param int $id
*
* #return AdvertisingSpaceCategory
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* #return string
*/
public function getCode()
{
return $this->code;
}
/**
* #param string $code
*
* #return AdvertisingSpaceCategory
*/
public function setCode($code)
{
$this->code = $code;
return $this;
}
/**
* #return array
*/
public function getAdvertisingSpaces()
{
return $this->advertisingSpaces;
}
/**
* #param array $advertisingSpaces
*
* #return AdvertisingSpaceCategory
*/
public function setAdvertisingSpaces($advertisingSpaces)
{
$this->advertisingSpaces = $advertisingSpaces;
return $this;
}
/**
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* #param string $description
*
* #return $this
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* #return array
*/
public function getSluggableFields()
{
return [ 'slug' ];
}
/**
* #param string $values
*
* #return string
*/
public function generateSlugValue($values)
{
return implode('-', $values);
}
not having the private slug declaration as I can attribute the #groups annotation to?
You should install the JMS Serializer Bundle and use the #VirtualProperty annotation on your own getSlug() method like the following
/**
* #VirtualProperty
* #Groups({"advertisingSpace"})
*/
public function getSlug()
{
return parent::getSlug();
}
I solved it anyway by creating a new string variable (Eg "SlugName"):
/**
* #var string
*
* #Groups({"advertisingSpace"})
*/
private $slugName;
where I inserted the Groups annotation and which returns the original 'slug' field from its getter:
/**
* # return string
*/
public function getSlugName(): string
{
return $this->slug;
}
I have below query in MySQL:
SELECT * FROM (orders)
INNER JOIN links ON orders.ref_id = links.id
INNER JOIN users ON links.user_id = users.id
WHERE links.user_id=2
And three entities in Symfony: order, link, user.
How can I write this in Doctrine Query Builder?
$repo = $em->getRepository('OrderBundle:Order');
$queryBuilder=$repo->createQueryBuilder('o');
$query = $queryBuilder
->select('o, l, u')
->innerJoin('c.ref_id', 'l')
->innerJoin('l.user_id', 'u')
->where('u.id=1')
->getQuery();
This doesn't work. I got below error:
[Semantical Error] line 0, col 84 near 'u WHERE u.id': Error: Class OrderBundle\Entity\Order has no association named user_id
I trying for two hours and this make me angry... Thanks in advance.
My order entity:
<?php
// src/OrderBundle/Entity/Order.php
namespace OrderBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints\DateTime;
/**
* #ORM\Entity
* #ORM\Table(name="orders")
*/
class Order
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\ManyToOne(targetEntity="OrderBundle\Entity\Order")
* #ORM\JoinColumn(name="ref_id", referencedColumnName="id")
*/
protected $ref_id;
/**
* #ORM\Column(type="datetime")
*/
protected $date_created;
/**
* #ORM\Column(type="string", length=60)
*/
protected $email;
/**
* #ORM\Column(type="string", length=60)
*/
protected $email2;
/**
* #ORM\Column(type="integer")
*/
protected $service;
/**
* #ORM\Column(type="string", length=20)
*/
protected $fromlang;
/**
* #ORM\Column(type="string", length=20)
*/
protected $tolang;
/**
* #ORM\Column(type="boolean")
*/
protected $academic;
/**
* #ORM\Column(type="string", length=40)
*/
protected $discipline;
/**
* #ORM\Column(type="text")
*/
protected $notes;
/**
* #ORM\Column(type="string")
*/
protected $file;
/**
* #ORM\Column(type="integer")
*/
protected $status;
/**
* #ORM\Column(type="integer")
*/
protected $cost;
/**
* #ORM\Column(type="string", length=2)
*/
protected $site;
public function __construct()
{
$this->date_created = new DateTime();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set dateCreated
*
* #param \DateTime $dateCreated
*
* #return Order
*/
public function setDateCreated($dateCreated)
{
$this->date_created = $dateCreated;
return $this;
}
/**
* Get dateCreated
*
* #return \DateTime
*/
public function getDateCreated()
{
return $this->date_created;
}
/**
* Set email
*
* #param string $email
*
* #return Order
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get email
*
* #return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Set email2
*
* #param string $email2
*
* #return Order
*/
public function setEmail2($email2)
{
$this->email2 = $email2;
return $this;
}
/**
* Get email2
*
* #return string
*/
public function getEmail2()
{
return $this->email2;
}
/**
* Set refId
*
* #param integer $refId
*
* #return Order
*/
public function setRefId($refId)
{
$this->ref_id = $refId;
return $this;
}
/**
* Get refId
*
* #return integer
*/
public function getRefId()
{
return $this->ref_id;
}
/**
* Set service
*
* #param integer $service
*
* #return Order
*/
public function setService($service)
{
$this->service = $service;
return $this;
}
/**
* Get service
*
* #return integer
*/
public function getService()
{
return $this->service;
}
/**
* Set fromlang
*
* #param string $fromlang
*
* #return Order
*/
public function setFromlang($fromlang)
{
$this->fromlang = $fromlang;
return $this;
}
/**
* Get fromlang
*
* #return string
*/
public function getFromlang()
{
return $this->fromlang;
}
/**
* Set tolang
*
* #param string $tolang
*
* #return Order
*/
public function setTolang($tolang)
{
$this->tolang = $tolang;
return $this;
}
/**
* Get tolang
*
* #return string
*/
public function getTolang()
{
return $this->tolang;
}
/**
* Set academic
*
* #param boolean $academic
*
* #return Order
*/
public function setAcademic($academic)
{
$this->academic = $academic;
return $this;
}
/**
* Get academic
*
* #return boolean
*/
public function getAcademic()
{
return $this->academic;
}
/**
* Set discipline
*
* #param string $discipline
*
* #return Order
*/
public function setDiscipline($discipline)
{
$this->discipline = $discipline;
return $this;
}
/**
* Get discipline
*
* #return string
*/
public function getDiscipline()
{
return $this->discipline;
}
/**
* Set notes
*
* #param string $notes
*
* #return Order
*/
public function setNotes($notes)
{
$this->notes = $notes;
return $this;
}
/**
* Get notes
*
* #return string
*/
public function getNotes()
{
return $this->notes;
}
/**
* Set file
*
* #param string $file
*
* #return Order
*/
public function setFile($file)
{
$this->file = $file;
return $this;
}
/**
* Get file
*
* #return string
*/
public function getFile()
{
return $this->file;
}
/**
* Set status
*
* #param integer $status
*
* #return Order
*/
public function setStatus($status)
{
$this->status = $status;
return $this;
}
/**
* Get status
*
* #return integer
*/
public function getStatus()
{
return $this->status;
}
/**
* Set cost
*
* #param integer $cost
*
* #return Order
*/
public function setCost($cost)
{
$this->cost = $cost;
return $this;
}
/**
* Get cost
*
* #return \cost
*/
public function getCost()
{
return $this->cost;
}
/**
* Set site
*
* #param string $site
*
* #return Order
*/
public function setSite($site)
{
$this->site = $site;
return $this;
}
/**
* Get site
*
* #return string
*/
public function getSite()
{
return $this->site;
}
}
In editAction method of controller I tried to edit existed entities in class table inheritance.
But after form submit I get error:
Neither the property "id" nor one of the methods
"addId()"/"removeId()", "setId()", "id()", "__set()" or "__call()"
exist and have public access in class "AdBundle\Entity\AdFlat".
Why AdFlat entity not extended of AdBase entity?
Base entity:
<?php
namespace AdBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* AdBase
*
* #ORM\Table(name="ad_base")
* #ORM\Entity(repositoryClass="AdBundle\Repository\AdBaseRepository")
* #ORM\HasLifecycleCallbacks()
* #ORM\InheritanceType("JOINED")
* #ORM\DiscriminatorColumn(name="discr", type="string")
* #ORM\DiscriminatorMap({
"flat" = "AdFlat"
* })
*/
abstract class AdBase
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
*
* #ORM\Column(name="author", type="string", length=255)
*/
private $author;
/**
* #ORM\ManyToOne(targetEntity="AdBundle\Entity\AdCategory")
*/
private $category;
/**
* #ORM\Column(type="string")
* #Assert\NotBlank(message="Field Location should not be blank")
*/
private $location;
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=255)
* #Assert\NotBlank(message="Not specified Title")
*/
private $title;
/**
* #var string
*
* #ORM\Column(name="description", type="text", nullable=true)
* #Assert\NotBlank(message="Not specified Description")
*/
private $description;
/**
* #ORM\OneToMany(targetEntity="AdBundle\Entity\AdPhoto", mappedBy="ad")
*/
private $photos;
/**
* #ORM\Column(type="float")
* #Assert\NotBlank()
*/
private $price;
/**
* #ORM\ManyToOne(targetEntity="AdBundle\Entity\AdPriceType")
*/
private $priceType;
/**
* #var \DateTime
*
* #ORM\Column(name="createdAt", type="datetime")
*/
private $createdAt;
/**
* #var string
*
* #ORM\Column(name="updatedAt", type="datetime")
*/
private $updatedAt;
/**
* #var bool
*
* #ORM\Column(name="visible", type="boolean")
*/
private $visible = false;
/**
* #ORM\Column(type="boolean")
*/
private $active = true;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set author
*
* #param string $author
*
* #return AdBase
*/
public function setAuthor($author)
{
$this->author = $author;
return $this;
}
/**
* Get author
*
* #return string
*/
public function getAuthor()
{
return $this->author;
}
/**
* #return mixed
*/
public function getCategory()
{
return $this->category;
}
/**
* #param mixed $category
*/
public function setCategory($category)
{
$this->category = $category;
}
/**
* #return mixed
*/
public function getLocation()
{
return $this->location;
}
/**
* #param mixed $location
*/
public function setLocation($location)
{
$this->location = $location;
}
/**
* Set title
*
* #param string $title
*
* #return AdBase
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* #return string
*/
public function getTitle()
{
return $this->title;
}
/**
* Set description
*
* #param string $description
*
* #return AdBase
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set photos
*
* #param string $photos
*
* #return AdBase
*/
public function setPhotos($photos)
{
$this->photos = $photos;
return $this;
}
/**
* Get photos
*
* #return string
*/
public function getPhotos()
{
return $this->photos;
}
/**
* #return mixed
*/
public function getPrice()
{
return $this->price;
}
/**
* #param mixed $price
*/
public function setPrice($price)
{
$this->price = $price;
}
/**
* #return mixed
*/
public function getPriceType()
{
return $this->priceType;
}
/**
* #param mixed $priceType
*/
public function setPriceType($priceType)
{
$this->priceType = $priceType;
}
/**
* Set createdAt
*
* #param \DateTime $createdAt
*
* #return AdBase
*/
public function setCreatedAt($createdAt)
{
$this->createdAt = $createdAt;
return $this;
}
/**
* Get createdAt
*
* #return \DateTime
*/
public function getCreatedAt()
{
return $this->createdAt;
}
/**
* Set updatedAt
*
* #param string $updatedAt
*
* #return AdBase
*/
public function setUpdatedAt($updatedAt)
{
$this->updatedAt = $updatedAt;
return $this;
}
/**
* Get updatedAt
*
* #return string
*/
public function getUpdatedAt()
{
return $this->updatedAt;
}
/**
* Set visible
*
* #param boolean $visible
*
* #return AdBase
*/
public function setVisible($visible)
{
$this->visible = $visible;
return $this;
}
/**
* Get visible
*
* #return bool
*/
public function getVisible()
{
return $this->visible;
}
/**
* #return mixed
*/
public function getActive()
{
return $this->active;
}
/**
* #param mixed $active
*/
public function setActive($active)
{
$this->active = $active;
}
/**
* #ORM\PrePersist()
*/
public function prePersist()
{
$this->author = 'voodoo';
$this->createdAt = new \DateTime('now', new \DateTimeZone('UTC'));
$this->updatedAt = new \DateTime('now', new \DateTimeZone('UTC'));
$this->location = 'Donetsk';
}
/**
* #ORM\PreUpdate()
*/
public function preUpdate()
{
$this->updatedAt = new \DateTime('now', new \DateTimeZone('UTC'));
}
}
Extended entity:
<?php
namespace AdBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* AdFlat
*
* #ORM\Table(name="ad_flat")
* #ORM\Entity(repositoryClass="AdBundle\Repository\AdFlatRepository")
*/
class AdFlat extends AdBase
{
/**
* #var integer
*
* #ORM\Column(type="integer")
* #Assert\NotBlank(message="ad_flat.rooms.not_blank")
*/
private $rooms;
/**
* #var float
*
* #ORM\Column(name="square", type="float", nullable=true)
*/
private $square;
/**
* #var float
*
* #ORM\Column(name="liveSquare", type="float", nullable=true)
*/
private $liveSquare;
/**
* #var float
*
* #ORM\Column(type="float", nullable=true)
*/
private $kitchenSquare;
/**
* #var int
*
* #ORM\Column(name="floor", type="integer")
*/
private $floor;
/**
* #var int
*
* #ORM\Column(name="floors", type="integer")
*/
private $floors;
/**
* #var string
*
* #ORM\ManyToOne(targetEntity="AdBundle\Entity\AdWallType")
*/
private $wallType;
/**
* #ORM\ManyToOne(targetEntity="AdBundle\Entity\AdWCType")
*/
private $wcType;
/**
* #return mixed
*/
public function getRooms()
{
return $this->rooms;
}
/**
* #param mixed $rooms
*/
public function setRooms($rooms)
{
$this->rooms = $rooms;
}
/**
* Set square
*
* #param float $square
*
* #return AdFlat
*/
public function setSquare($square)
{
$this->square = $square;
return $this;
}
/**
* Get square
*
* #return float
*/
public function getSquare()
{
return $this->square;
}
/**
* Set liveSquare
*
* #param float $liveSquare
*
* #return AdFlat
*/
public function setLiveSquare($liveSquare)
{
$this->liveSquare = $liveSquare;
return $this;
}
/**
* Get liveSquare
*
* #return float
*/
public function getLiveSquare()
{
return $this->liveSquare;
}
/**
* #return float
*/
public function getKitchenSquare()
{
return $this->kitchenSquare;
}
/**
* #param float $kitchenSquare
*/
public function setKitchenSquare($kitchenSquare)
{
$this->kitchenSquare = $kitchenSquare;
}
/**
* Set floor
*
* #param integer $floor
*
* #return AdFlat
*/
public function setFloor($floor)
{
$this->floor = $floor;
return $this;
}
/**
* Get floor
*
* #return int
*/
public function getFloor()
{
return $this->floor;
}
/**
* Set floors
*
* #param integer $floors
*
* #return AdFlat
*/
public function setFloors($floors)
{
$this->floors = $floors;
return $this;
}
/**
* Get floors
*
* #return int
*/
public function getFloors()
{
return $this->floors;
}
/**
* Set wallType
*
* #param string $wallType
*
* #return AdFlat
*/
public function setWallType($wallType)
{
$this->wallType = $wallType;
return $this;
}
/**
* Get wallType
*
* #return string
*/
public function getWallType()
{
return $this->wallType;
}
/**
* Set wcType
*
* #param string $wcType
*
* #return AdFlat
*/
public function setWcType($wcType)
{
$this->wcType = $wcType;
return $this;
}
/**
* Get wcType
*
* #return string
*/
public function getWcType()
{
return $this->wcType;
}
}
In controller:
public function editAction(Request $request)
{
$adId = $request->get('id');
if (!$adId) {
return $this->renderError('Unknown Ad');
}
$adEntity = $this->getDoctrine()->getRepository('AdBundle:AdBase')->find($adId);
if (null === $adEntity) {
return $this->renderError('Unknown Ad');
}
$reflection = new \ReflectionClass($adEntity);
$adForm = $this->getForm($reflection->getShortName());
$form = $this->createForm($adForm, $adEntity);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($adEntity);
$em->flush();
return $this->redirectToRoute('ad_bundle_ad_view', array(
'id' => $adEntity->getId()
));
}
return $this->render('AdBundle:Ad:edit-ad-flat.html.twig', array(
'form' => $form->createView()
));
}
private function renderError($message = '')
{
return $this->render('::error.html.twig', array(
'error' => $message
));
}
private function getEntity($className)
{
$entityName = 'AdBundle\Entity\\' . $className;
return new $entityName();
}
private function getForm($className)
{
$formName = 'AdBundle\Form\Type\\' . $className . 'Type';
return new $formName();
}
The error message simply states that you are missing a way to set the entity's $id property. It doesn't tell you anything about the class not extending the base class. However, your base class only defines a getter method for the $id property but no setter method.
Doctrine Entities work as POPOs (Plain Old PHP Objects). To achieve extending correctly you need to work with the MappedSuperClass here is an example
class Accounts extends AbstractType
{
private $em;
private $accountrepo = null;
private $choices = array();
public function __construct()
{
}
public function setAccountRepository($repo)
{
$this->accountrepo = $repo;
return $this;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults([
'choices' => $this->getChoices(),
'attr' => [
'data-dojo-type' => 'dijit/form/FilteringSelect',
],
'data_class' => 'Far\MT\AccountBundle\Entity\Account'
]);
}
public function getParent()
{
return 'choice';
}
public function getName()
{
return 'Accounts';
}
public function getChoices()
{
if ( count($this->choices) > 0 ) {
return $this->choices;
}
$this->choices[0] = "";
foreach ($this->accountrepo->findAll() as $account) {
$this->choices[$account->getId()] = $account->getName() . " (" .
$account->getCurrency().") ";
}
return $this->choices;
}
}
Using the code above I get the error:
Notice: Object of class
Proxies__CG__\Far\MT\AccountBundle\Entity\Account could not be
converted to int in
/workspace/tools/vendorsymfony2/symfony/symfony/src/Symfony/Component/Form/Extension/Core/ChoiceList/ChoiceList.php
line 457
This only happens when I edit the record, I'm using this Type has a ChoiceList type in order to have the db values filtered and placed on the "combobox".
Any sugestions on what I can be doing wrong?
EDIT
use Doctrine\ORM\Mapping as ORM;
/**
* Movement
*
* #ORM\Entity(repositoryClass="Far\MT\AccountBundle\Entity\MovementRepository")
* #ORM\Table(name="movement")
*/
class Movement
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var \Date
*
* #ORM\Column(name="date", type="date")
*/
private $date;
/**
* #var string
*
* #ORM\ManyToOne(targetEntity="MovementType")
* #ORM\JoinColumn(name="movementtype", referencedColumnName="id", unique=false)
*/
private $Type;
/**
* #var float
*
* #ORM\Column(name="value", type="float")
*/
private $value;
/**
* #var Account
*
* #ORM\ManyToOne(targetEntity="Account", cascade={"persist"})
* #ORM\JoinColumn(name="fromaccount", referencedColumnName="id", unique=false)
*/
private $fromAccount;
/**
* #var Account
*
* #ORM\ManyToOne(targetEntity="Account", cascade={"persist"})
* #ORM\JoinColumn(name="toaccount", referencedColumnName="id", unique=false)
*/
private $toAccount;
/**
* #var string
*
* #ORM\ManyToOne(targetEntity="ExpenseType", cascade={"persist"})
* #ORM\JoinColumn(name="expensetype", referencedColumnName="id",
* nullable=true, unique=false)
*/
private $ExpenseType;
/**
* #var string
*
* #ORM\ManyToOne(targetEntity="Holder", cascade={"persist"})
* #ORM\JoinColumn(name="holder", referencedColumnName="id", unique=false)
*/
private $orderHolder;
/**
* #var string
*
* #ORM\Column(name="description", type="string", length=254)
*/
private $description;
/**
* #var float
*
* #ORM\Column(name="xrate", type="float", nullable=true)
*/
private $xrate = null;
public function getDescription()
{
return $this->description;
}
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set Account
*
* #param string $account
* #return Movement
*/
public function setAccount($account)
{
$this->Account = $account;
return $this;
}
/**
* Get Account
*
* #return string
*/
public function getAccount()
{
return $this->Account;
}
/**
* Set date
*
* #param \DateTime $date
* #return Movement
*/
public function setDate($date)
{
$this->date = $date;
return $this;
}
/**
* Get date
*
* #return \DateTime
*/
public function getDate()
{
return $this->date;
}
/**
* Set Type
*
* #param string $type
* #return Movement
*/
public function setType($type)
{
$this->Type = $type;
return $this;
}
/**
* Get Type
*
* #return string
*/
public function getType()
{
return $this->Type;
}
/**
* Set value
*
* #param float $value
* #return Movement
*/
public function setValue($value)
{
$this->value = $value;
return $this;
}
/**
* Get value
*
* #return float
*/
public function getValue()
{
return $this->value;
}
/**
* Set fromAccount
*
* #param string $fromAccount
* #return Movement
*/
public function setFromAccount($fromAccount)
{
$this->fromAccount = $fromAccount;
return $this;
}
/**
* Get fromAccount
*
* #return string
*/
public function getFromAccount()
{
return $this->fromAccount;
}
/**
* Set toAccount
*
* #param string $toAccount
* #return Movement
*/
public function setToAccount($toAccount)
{
$this->toAccount = $toAccount;
return $this;
}
/**
* Get toAccount
*
* #return string
*/
public function getToAccount()
{
return $this->toAccount;
}
/**
* Set ExpenseType
*
* #param string $expenseType
* #return Movement
*/
public function setExpenseType($expenseType)
{
$this->ExpenseType = $expenseType;
return $this;
}
/**
* Get ExpenseType
*
* #return string
*/
public function getExpenseType()
{
return $this->ExpenseType;
}
/**
* Set orderHolder
*
* #param string $orderHolder
* #return Movement
*/
public function setOrderHolder($orderHolder)
{
$this->orderHolder = $orderHolder;
return $this;
}
/**
* Get orderHolder
*
* #return string
*/
public function getOrderHolder()
{
return $this->orderHolder;
}
/**
* Set exchange rate for movement
*
* #param float $xrate
*/
public function setXrate($xrate)
{
$this->xrate = (double)$xrate;
return $this;
}
/**
* Return movement exchange rate
*
* #return float
*/
public function getXrate()
{
return $this->xrate;
}
}
Entity Account
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Account
*
* #ORM\Table(name="account")
*
* #ORM\Entity(repositoryClass="Far\MT\AccountBundle\Entity\AccountRepository")
*/
class Account
{
public function __construct()
{
$this->holders = new ArrayCollection();
$this->pocketAccounts = new ArrayCollection();
}
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="code", type="string", length=40)
*/
private $code;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="currency", type="string", length=20)
*/
private $currency;
/**
* #var Far\MT\AccountBundle\Entity\Holder
*
* #ORM\ManyToMany(targetEntity="Holder", inversedBy="Accounts")
* #ORM\JoinTable(name="account_holder",
* joinColumns={#ORM\JoinColumn(name="account_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="holder_id",
* referencedColumnName="id")}
* )
*
*/
private $holders;
/**
* #var Far\MT\AccountBundle\Entity\Account
*
* #ORM\OneToMany(targetEntity="Account", mappedBy="parentAccount")
*/
private $pocketAccounts;
/**
*
* #ORM\ManyToOne(targetEntity="Account", inversedBy="pocketAccounts", cascade={"persist"})
* #ORM\JoinColumn(name="parent_id", referencedColumnName="id")
*/
private $parentAccount;
/**
* Specifies the account type has string
*
* #var String
*
* #ORM\Column(name="accounttype", type="string", length=40)
*/
private $accountType;
/**
* Total value of available money this should not account money that is
* pending transaction
*
* #var double
*
* #ORM\Column(name="totalavailable", type="float")
*/
private $totalAvailable = 0;
/**
* Total value of accounted money this takes into account money that has
* pending transaction
*
* #var double
*
* #ORM\Column(name="totalaccounted", type="float")
*/
private $totalAccounted = 0;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set code
*
* #param string $code
* #return Account
*/
public function setCode($code)
{
$this->code = str_replace(" ", "", strtoupper(trim($code)));
return $this;
}
/**
* Get code
*
* #return string
*/
public function getCode()
{
return $this->code;
}
/**
* Set name
*
* #param string $name
* #return Account
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set currency
*
* #param string $currency
* #return Account
*/
public function setCurrency($currency)
{
$this->currency = $currency;
return $this;
}
/**
* Get currency
*
* #return string
*/
public function getCurrency()
{
return $this->currency;
}
/**
* Set holders
*
* #param null|Doctrine\Common\Collections\ArrayCollection $holders
* #return Account
*/
public function setHolders($holders)
{
if ($holders === null) {
$this->holders = new ArrayCollection();
} else {
$this->holders = $holders;
}
return $this;
}
/**
* Get holders
*
* #return string
*/
public function getHolders()
{
return $this->holders;
}
/**
*
* Get Pocket accounts
*
* #return \Doctrine\Common\Collections\ArrayCollection()
*/
public function getPocketAccounts()
{
return $this->pocketAccounts;
}
public function setPocketAccounts($PocketAccounts)
{
$this->pocketAccounts = $PocketAccounts;
return $this;
}
/**
* Get Parent Account
*
* #return \Far\MT\AccountBundle\Entity\Account
*
*/
public function getParentAccount()
{
return $this->parentAccount;
}
public function setParentAccount($ParentAccount)
{
$this->parentAccount = ($ParentAccount);
return $this;
}
/**
* does this account has a parent
*
* #return boolean
*/
public function hasParentAccount()
{
return ($this->parentAccount !== null);
}
public function setAccountType($accountType)
{
$this->accountType = $accountType;
return $this;
}
public function getAccountType()
{
return $this->accountType;
}
public function getTotalAccounted()
{
return $this->totalAccounted;
}
public function setTotalAccounted($total)
{
$this->totalAccounted = $total;
return $this;
}
public function getTotalAvailable()
{
return $this->totalAvailable;
}
public function setTotalAvailable($total)
{
$this->totalAvailable = $total;
return $this;
}
public function __toString()
{
return 'Account';
}
}
Please note that what is updated is the Movement entity witch contains the Account in fromAccount and toAccount.
Not knowing the answer he pointed out to me that I did not understand the data_class parameter.
'data_class' => 'Far\MT\AccountBundle\Entity\Account'
18:37 < ocramius> netcrash: no, sorry, can't help since I don't know
what data_class does (not a sf2 form user)
I was missing a Data Transformer, data_class (specifying the Entity was working not sure the reason why...), I placed a DataTransformer and it solved the issue.
See bellow.
use Far\MT\AccountBundle\Form\DataTransformer\AccountToIdTransformer;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class Accounts extends AbstractType
{
/**
*
* #var EntityManager
*/
private $em;
private $accountrepo = null;
private $choices = array();
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$transformer = new AccountToIdTransformer($this->em);
$builder->addModelTransformer($transformer);
}
public function setAccountRepository($repo)
{
$this->accountrepo = $repo;
return $this;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults([
'choices' => $this->getChoices(),
'attr' => [
'data-dojo-type' => 'dijit/form/FilteringSelect',
]
]);
}
public function getParent()
{
return 'choice';
}
public function getName()
{
return 'Accounts';
}
public function getChoices()
{
if ( count($this->choices) > 0 ) {
return $this->choices;
}
$this->choices[0] = "";
foreach ($this->accountrepo->findAll() as $account) {
$this->choices[$account->getId()] = $account->getName() . " (" .
$account->getCurrency().") ";
}
return $this->choices;
}
}
And the data transformer:
/**
* This is a transformer for the Account AbstractType
*
* #link http://symfony.com/doc/master/cookbook/form/data_transformers.html
*
* #author andref
*/
class AccountToIdTransformer implements DataTransformerInterface
{
/**
* #var ObjectManager
*/
private $om;
/**
*
* #param ObjectManager $om
*/
public function __construct($om)
{
$this->om = $om;
}
/**
* Transforms an object (issue) to a int (Id).
*
* #param Account|null $account
* #return string
*/
public function transform($account)
{
if (null === $account) {
return "";
}
return $account->getId();
}
/**
* Transforms a int (Id) to an object (Account).
*
* #param int $Id
*
* #return Account|null
*
* #throws TransformationFailedException if object (Account) is not found.
*/
public function reverseTransform($id)
{
if (!$id) {
return null;
}
$Account = $this->om
->getRepository('FarMTAccountBundle:Account')
->findOneBy(array('id' => $id))
;
if (null === $Account) {
throw new TransformationFailedException(sprintf(
'An Account with Id "%s" does not exist!',
$id
));
}
return $Account;
}
}
i'm receiving the following error message upon persisting and flushing an object with its associations:
Catchable Fatal Error: Argument 1 passed to
Doctrine\Common\Collections\ArrayCollection::__construct() must be of
the type array, object given, called in
.../vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php on line 519 and defined in
.../vendor/doctrine/common/lib/Doctrine/Common/Collections/ArrayCollection.php line 48
what i have is a single table inheritance with this as the base object:
use Doctrine\ORM\Mapping as ORM;
/**
* ObjectData
*
* #ORM\Table(name="object_data")
* #ORM\Entity(repositoryClass="Edexp\CoreBundle\Entity\ObjectDataRepository")
* #ORM\InheritanceType("SINGLE_TABLE")
* #ORM\DiscriminatorColumn(name="entity_name", type="string")
* #ORM\DiscriminatorMap({
* "request" = "Edexp\MessageBundle\Entity\RequestData"
* })
* #ORM\HasLifecycleCallbacks
*/
class ObjectData
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var \DateTime
*
* #ORM\Column(name="created_at", type="datetime")
*/
private $created_at;
/**
* #var User
*
* #ORM\OneToMany(targetEntity="User", mappedBy="data")
*/
private $user;
/**
* #var string
*
* #ORM\Column(name="`key`", type="string", length=255)
*/
private $key;
/**
* #var string
*
* #ORM\Column(name="data", type="blob")
*/
private $data;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set created_at
*
* #param \DateTime $createdAt
* #return ObjectData
*/
public function setCreatedAt($createdAt)
{
$this->created_at = $createdAt;
return $this;
}
/**
* Get created_at
*
* #return \DateTime
*/
public function getCreatedAt()
{
return $this->created_at;
}
/**
* Set user
*
* #param User $user
* #return ObjectData
*/
public function setUser($user)
{
$this->user = $user;
return $this;
}
/**
* Get user
*
* #return User
*/
public function getUser()
{
return $this->user;
}
/**
* Set key
*
* #param string $key
* #return ObjectData
*/
public function setKey($key)
{
$this->key = $key;
return $this;
}
/**
* Get key
*
* #return string
*/
public function getKey()
{
return $this->key;
}
/**
* Set data
*
* #param string $data
* #return ObjectData
*/
public function setData($data)
{
$this->data = $data;
return $this;
}
/**
* Get data
*
* #return string
*/
public function getData()
{
return $this->data;
}
/**
* #ORM\PrePersist
*/
public function prepareForPersist()
{
$this->created_at = new \DateTime();
}
}
and an additional object that inherits from ObjectData:
use Doctrine\ORM\Mapping as ORM;
use MyProject\CoreBundle\Entity\ObjectData;
/**
* RequestData
*
* #ORM\Entity()
*/
class RequestData extends ObjectData
{
/**
* var Request $request
*
* #ORM\ManyToOne(targetEntity="Request", inversedBy="data")
* #ORM\JoinColumn(name="object_id", referencedColumnName="id")
*/
private $request;
/**
* Set request
*
* #param Request $request
* #return RequestData
*/
public function setRequest($request)
{
$this->request = $request;
return $this;
}
/**
* Get request
*
* #return Request
*/
public function getRequest()
{
return $this->request;
}
}
and here's the object that utilizes the RequestData entity:
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* Request
*
* #ORM\Table(name="requests")
* #ORM\Entity(repositoryClass="RequestRepository")
* #ORM\HasLifecycleCallbacks()
*/
class Request
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var Message $message
*
* #ORM\ManyToOne(targetEntity="Message", inversedBy="requests")
*/
private $message;
/**
* #var RequestType $type
*
* #ORM\ManyToOne(targetEntity="RequestType")
* #ORM\JoinColumn(name="type_id", referencedColumnName="id")
*/
private $type;
/**
* #var ArrayCollection $data
*
* #ORM\OneToMany(
* targetEntity="RequestData",
* mappedBy="request",
* cascade={"persist","remove"}
* )
*/
private $data;
/**
* #var datetime $created_at
*
* #ORM\Column(name="created_at", type="datetime")
*/
private $created_at;
/**
* #var text $comment
*
* #ORM\Column(name="comment", type="text")
*/
private $comment;
/**
* #var ArrayCollection $responses
*
* #ORM\OneToMany(
* targetEntity="Response",
* mappedBy="request",
* cascade={"persist","remove"}
* )
*/
private $responses;
public function __construct()
{
$this->data = new ArrayCollection();
$this->responses = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set message
*
* #param Message $message
*/
public function setMessage($message)
{
$this->message = $message;
}
/**
* Get message
*
* #return Message
*/
public function getMessage()
{
return $this->message;
}
/**
* Set type
*
* #param RequestType $type
*/
public function setType($type)
{
$this->type = $type;
}
/**
* Get type
*
* #return RequestType
*/
public function getType()
{
return $this->type;
}
/**
* Set created_at
*
* #param datetime $createdAt
*/
public function setCreatedAt($createdAt)
{
$this->created_at = $createdAt;
}
/**
* Get created_at
*
* #return datetime
*/
public function getCreatedAt()
{
return $this->created_at;
}
/**
* Set comment
*
* #param text $comment
*/
public function setComment($comment)
{
$this->comment = $comment;
}
/**
* Get comment
*
* #return text
*/
public function getComment()
{
return $this->comment;
}
/**
* Add response
*
* #param Response $response
*/
public function addResponse($response)
{
foreach ( $this->responses as $r ) {
if ( $r->getUser() == $response->getUser() )
return;
}
$this->responses->add($response);
}
/**
* Get responses
*
* #return ArrayCollection
*/
public function getResponses()
{
return $this->responses;
}
public function hasResponse($user)
{
foreach ( $this->responses as $r ) {
if ( $r->getUser() == $user )
return $r;
}
return null;
}
public function addData($data)
{
$data->setRequest($this);
$this->data->add($data);
}
public function getData()
{
return $this->data;
}
/**
* #ORM\PrePersist
*/
public function prePersist()
{
$this->created_at = new \DateTime();
}
}
and finally the code that results in an error:
use MyProject\MessageBundle\Entity\Request as MyRequest;
$data = new RequestData();
$data->setUser($user);
$data->setKey('user_id');
$data->setData(6);
$req = new MyRequest();
$req->setMessage($message);
$req->setComment('bla');
$req->setType($doctrine->getRepository('MessageBundle:RequestType')->find(1));
$req->addData($data);
$em->persist($req);
$em->flush();
any suggestions as to what might be wrong here?
cheers
so here's what i had to do in order to make it work.
i had to change the association in ObjectData from:
#ORM\OneToMany(targetEntity="User", mappedBy="data")
to
#ORM\ManyToOne(targetEntity="User", inversedBy="data")
added the data field to the User entity accordingly.
/**
* #var ArrayCollection $data
*
* #ORM\OneToMany(targetEntity="ObjectData", mappedBy="user")
*/
private $data;
and voila, it worked.
Try:
$req->addData(array($data));
Explanation:
arrayCollection constructor type hints an array as its parameter, so you need to always pass it an array.