Doctrine One To Many add column check - symfony

I have two Entities
User
<?php
namespace AppBundle\Entity;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity
* #ORM\Table(name="users")
*/
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(name="first_name", type="text", nullable=true)
*/
protected $firstName;
/**
* #ORM\Column(name="last_name", type="text", nullable=true)
*/
protected $lastName;
/**
* #ORM\Column(type="bigint", nullable=true)
*/
protected $phone;
/**
* #ORM\Column(name="birth_date", type="date", nullable=true)
*/
protected $birthDate;
/**
* #ORM\Column(type="text", nullable=true)
*/
protected $gender;
/**
* #ORM\Column(name="location_country", type="text", nullable=true)
*/
protected $locationCountry;
/**
* #ORM\Column(name="location_city", type="text", nullable=true)
*/
protected $locationCity;
/**
* #ORM\Column( type="text", nullable=true)
*/
protected $avatar;
/**
* #ORM\Column(name="wall_image", type="text", nullable=true)
*/
protected $wallImage;
/**
* #ORM\Column( type="text", nullable=true)
*/
protected $about;
/**
* #ORM\OneToMany(targetEntity="Follower", mappedBy="user")
*/
protected $followers;
/**
* #ORM\OneToMany(targetEntity="Follower", mappedBy="follower")
*/
protected $followings;
/**
* Is followed. Used when checking is followed by another user.
*/
protected $isFollowed = false;
/**
* #ORM\OneToMany(targetEntity="Photo", mappedBy="user")
* #ORM\OrderBy({"id" = "DESC"})
*/
protected $photos;
public function getFirstName()
{
return $this->firstName;
}
public function getLastName()
{
return $this->lastName;
}
public function getPhone()
{
return $this->phone;
}
public function getBirthDate()
{
return $this->birthDate;
}
public function getGender()
{
return $this->gender;
}
public function getLocationCountry()
{
return $this->locationCountry;
}
public function getLocationCity()
{
return $this->locationCity;
}
public function getAvatar()
{
return $this->avatar;
}
public function getAvatarImage()
{
return $this->getAvatarPath().$this->avatar;
}
public function getWallImage()
{
return $this->wallImage;
}
public function getAbout()
{
return $this->about;
}
public function getAvatarPath()
{
return '/web/uploads/avatars/'.$this->id.'/';
}
public function getWallImagePath()
{
return '/web/uploads/wall/'.$this->id.'/';
}
public function getFollowers()
{
return $this->followers;
}
public function getFollowings()
{
return $this->followings;
}
public function getFollowersCount()
{
//print_r($this->followers->toArray());
}
public function getPhotos()
{
return $this->photos;
}
public function isFollowed()
{
return $this->isFollowed;
}
public function setFirstName($value)
{
$this->firstName = $value;
}
public function setLastName($value)
{
$this->lastName = $value;
}
public function setPhone($value)
{
$this->phone = $value;
}
public function setBirthDate($value)
{
$this->birthDate = $value;
}
public function setGender($value)
{
$this->gender = $value;
}
public function setLocationCountry($value)
{
$this->locationCountry = $value;
}
public function setLocationCity($value)
{
$this->locationCity = $value;
}
public function setAvatar($path)
{
$this->avatar = $path;
}
public function setWallImage($path)
{
$this->wallImage = $path;
}
public function setAbout($about)
{
$this->about = $about;
}
public function setFollowed($isFollowed)
{
$this->isFollowed = $isFollowed;
}
}
Photo
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity
* #ORM\Table(name="photos")
*/
class Photo
{
const
CATEGORY_PHOTOGRAPHY = 1,
CATEGORY_PAINTING = 2,
CATEGORY_3D = 3;
/*
* Flow photos limit
*/
const FLOW_PHOTOS_LIMIT = 15;
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\ManyToOne(targetEntity="User", inversedBy="photos")
*/
protected $user;
/**
* #ORM\Column(type="text", nullable=true)
*/
protected $title;
/**
* #ORM\Column(type="text", nullable=true)
*/
protected $description;
/**
* #ORM\Column(type="text")
*/
protected $name;
/**
* #ORM\ManyToOne(targetEntity="PhotoCategory")
*/
protected $category;
/**
* #ORM\Column(name="creation_date", type="datetime")
*/
protected $creationDate;
/**
* #ORM\Column(name="edit_date", type="datetime", nullable=true)
*/
protected $editDate;
/**
* #ORM\Column(name="is_moderated", type="boolean")
*/
protected $isModerated = false;
/**
* #ORM\Column(name="is_active", type="boolean")
*/
protected $isActive = true;
/**
* #ORM\OneToMany(targetEntity="Comment", mappedBy="photo")
* #ORM\OrderBy({"id" = "DESC"})
*/
protected $comments;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set user
*
* #param User $user
*
* #return Photo
*/
public function setUser($user)
{
$this->user = $user;
return $this;
}
/**
* Get user
*
* #return User $user
*/
public function getUser()
{
return $this->user;
}
/**
* Get category
*
* #return Category $category
*/
public function getCategory()
{
return $this->category;
}
/**
* Set title
*
* #param string $title
*
* #return Photo
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* #return string
*/
public function getTitle()
{
return $this->title;
}
/**
* Get creationDate
*
* #return \DateTime
*/
public function getCreationDate()
{
return $this->creationDate;
}
/**
* Get editDate
*
* #return \DateTime
*/
public function getEditDate()
{
return $this->editDate;
}
/**
* Get is active
*
* #return integer
*/
public function isActive()
{
return $this->isActive;
}
/**
* Get is moderated
*
* #return integer
*/
public function isModerated()
{
return $this->isModerated;
}
/*
* Get image
*
* #return string
*/
public function getImage()
{
return $this->getWebDirectory().$this->getName();
}
/*
* Get image directory
*
* #return string
*/
public function getDirectory()
{
return __DIR__.'/../../../web/uploads/photos/'.$this->getUser()->getId().'/'.$this->creationDate->format('Y-m-d').'/';
}
/*
* Get image web directory
*
* #return string
*/
public function getWebDirectory()
{
return '/web/uploads/photos/'.$this->getUser()->getId().'/'.$this->creationDate->format('Y-m-d').'/';
}
/*
* Get comments
*/
public function getComments()
{
return $this->comments;
}
/**
* Set description
*
* #param string $description
*
* #return Photo
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set name
*
* #param string $name
*
* #return Photo
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set creationDate
*
* #param \DateTime $creationDate
*/
public function setCreationDate(\DateTime $creationDate)
{
$this->creationDate = $creationDate;
}
/**
* Set editDate
*
* #param \DateTime $editDate
*/
public function setEditDate(\DateTime $editDate)
{
$this->editDate = $editDate;
}
/**
* Set active
*/
public function setActive($active)
{
$this->isActive = $active;
}
/**
* Set category
*/
public function setCategory($category)
{
$this->category = $category;
}
/**
* Set moderated
*/
public function setModerated($moderated)
{
$this->isModerated = $moderated;
}
}
As you see, i have isActive in Photo, which is telling is photo deleted or not. So, i get all users photos via User->getPhotos() which is one-to-many. But it return all users photos. How should be done, so it returns all photos which have isActive = true?
thank you

you can try the filter method to query inside entities
$user->getPhotos()->filter(
function($photo) {
return $photo->isActive();
}
);

There are a number of ways you can do this.
Cosmin provided one for you, which will result in Doctrine loading each photo, and then PHP code checking to see whether or not it is active. This will work in the most number of situations, but will potentially be slow inefficient.
Yet another solution, is to use "criteria":
$exp = new \Doctrine\ORM\Query\Expr();
$activePhotos = $user->getPhotos()->matching(
new \Doctrine\Common\Collections\Criteria(
$exp->eq('active', true)
)
);
This will do something similar to the filter that Cosmin suggested, but allow for Doctrine to filter at the database level.

You can create a method inside the User entity, using the code of #Cosmin Ordean :) Something like this
public function getActivePhotos() {
return $this->getPhotos()->filter(
function($photo) {
return $photo->isActive();
}
);
}

Related

Symfony 4 Fos Rest : Error 415 Unsupported Media Type

Impossible to create a new event, I always get 415 error
I test with postman, if I test the same endpoint with ParamConverter annotation, I can reach the function.
So the error should come from configuration
Here is my controller
<?php
namespace App\Controller;
use App\Entity\Event;
use FOS\RestBundle\Controller\AbstractFOSRestController;
use FOS\RestBundle\View\View;
use Symfony\Component\HttpFoundation\Response;
use FOS\RestBundle\Controller\Annotations as Rest;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Component\Validator\ConstraintViolationListInterface;
/**
* Event controller.
* #Route("/api", name="api_")
*/
class EventController extends AbstractFOSRestController
{
/**
* Create New Event
* #Rest\Post("/event/create")
* #param Event $event
* #param ConstraintViolationListInterface $violations
* #ParamConverter("event", converter="fos_rest.request_body")
* #throws
* #return View
*/
public function createAction(Event $event, ConstraintViolationListInterface $violations)
{
if (count($violations)) {
return View::create($violations, Response::HTTP_BAD_REQUEST);
}
$em = $this->getDoctrine()->getManager();
$em->persist($event);
$em->flush();
return View::create($event, Response::HTTP_OK);
}
}
This is Fost Rest configuration, I checked the documentation and it should be ok
# Read the documentation: https://symfony.com/doc/master/bundles/FOSRestBundle/index.html
fos_rest:
routing_loader:
default_format: json
include_format: false
body_listener: true
format_listener:
rules:
- { path: '^/', priorities: ['json'], fallback_format: json, prefer_extension: false }
param_fetcher_listener: true
access_denied_listener:
json: true
view:
view_response_listener: 'force'
formats:
json: true
body_converter:
enabled: true
validate: true
validation_errors_argument: violations
And to finish, event entity
<?php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints\DateTime;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity
* #ORM\Table(name="event")
*/
class Event
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\User")
*
*/
protected $organizer;
/**
* #ORM\Column(type="text")
* #Assert\NotBlank
*/
protected $title;
/**
* #ORM\Column(type="text")
*/
protected $description;
/**
* #ORM\Column(type="text")
*/
protected $address;
/**
* #ORM\Column(type="text")
*/
protected $city;
/**
* #ORM\Column(type="text")
*/
protected $postCode;
/**
* #ORM\Column(type="text")
*/
protected $coverPicture;
/**
* #ORM\Column(type="float")
*/
protected $price;
/**
* #ORM\Column(type="integer")
*/
protected $maxAttendees;
/**
* #ORM\Column(type="datetime")
*/
protected $dateFrom;
/**
* #ORM\Column(type="datetime")
*/
protected $dateTo;
/**
* #ORM\Column(type="integer")
*/
protected $status;
/**
* #ORM\Column(type="boolean")
*/
protected $featured;
/**
* List of attendees
* #ORM\ManyToMany(targetEntity="User")
* #ORM\JoinTable(name="event_atendees",
* joinColumns={#ORM\JoinColumn(name="event_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="attendee_id", referencedColumnName="id")}
* )
*/
protected $attendees;
public function __construct()
{
$this->attendees = new ArrayCollection();
}
/**
* #return int
*/
public function getId() : int
{
return $this->id;
}
/**
* #param int $id
* #return Event
*/
public function setId(int $id)
{
$this->id = $id;
return $this;
}
/**
* #return User
*/
public function getOrganizer() : User
{
return $this->organizer;
}
/**
* #param User $organizer
* #return Event
*/
public function setOrganizer(User $organizer)
{
$this->organizer = $organizer;
return $this;
}
/**
* #return string
*/
public function getTitle() : string
{
return $this->title;
}
/**
* #param string $title
* #return Event
*/
public function setTitle(string $title)
{
$this->title = $title;
return $this;
}
/**
* #return string
*/
public function getDescription() : string
{
return $this->description;
}
/**
* #param string $description
* #return Event
*/
public function setDescription(string $description)
{
$this->description = $description;
return $this;
}
/**
* #return string
*/
public function getAddress() : string
{
return $this->address;
}
/**
* #param string $address
* #return Event
*/
public function setAddress(string $address)
{
$this->address = $address;
return $this;
}
/**
* #return string
*/
public function getCity() : string
{
return $this->city;
}
/**
* #param string $city
* #return Event
*/
public function setCity(string $city)
{
$this->city = $city;
return $this;
}
/**
* #return string
*/
public function getPostCode() : string
{
return $this->postCode;
}
/**
* #param string $postCode
* #return Event
*/
public function setPostCode(string $postCode)
{
$this->postCode = $postCode;
return $this;
}
/**
* #return string
*/
public function getCoverPicture() : string
{
return $this->coverPicture;
}
/**
* #param string $coverPicture
* #return Event
*/
public function setCoverPicture(string $coverPicture)
{
$this->coverPicture = $coverPicture;
return $this;
}
/**
* #return float
*/
public function getPrice() : float
{
return $this->price;
}
/**
* #param float $price
* #return Event
*/
public function setPrice(float $price)
{
$this->price = $price;
return $this;
}
/**
* #return int
*/
public function getMaxAttendees() : int
{
return $this->maxAttendees;
}
/**
* #param int $maxAttendees
* #return Event
*/
public function setMaxAttendees(int $maxAttendees)
{
$this->maxAttendees = $maxAttendees;
return $this;
}
/**
* #return DateTime
*/
public function getDateFrom() : DateTime
{
return $this->dateFrom;
}
/**
* #param DateTime $dateFrom
* #return Event
*/
public function setDateFrom(DateTime $dateFrom)
{
$this->dateFrom = $dateFrom;
return $this;
}
/**
* #return DateTime
*/
public function getDateTo() : DateTime
{
return $this->dateTo;
}
/**
* #param DateTime $dateTo
* #return Event
*/
public function setDateTo(DateTime $dateTo)
{
$this->dateTo = $dateTo;
return $this;
}
/**
* #return int
*/
public function getStatus() : int
{
return $this->status;
}
/**
* #param int $status
* #return Event
*/
public function setStatus(int $status)
{
$this->status = $status;
return $this;
}
/**
* #return bool
*/
public function getFeatured() : bool
{
return $this->featured;
}
/**
* #param bool $featured
* #return Event
*/
public function setFeatured(bool $featured)
{
$this->featured = $featured;
return $this;
}
/**
* #return User[]
*/
public function getAttendees() : ArrayCollection
{
return $this->attendees;
}
/**
* #param User[] $attendees
* #return Event
*/
public function setAttendees($attendees)
{
$this->attendees = $attendees;
return $this;
}
/**
* #param User $attendee
*/
public function addAttendee(User $attendee) {
$this->attendees->add($attendee);
}
/**
* #param User $attendee
*/
public function removeAttendee(User $attendee) {
$this->attendees->removeElement($attendee);
}
}
Is somebody have an idea ?

No relation between messages and messages_translation

I'm trying to get a multilingual site up with A2lix-i18 & a2lix-form, but I've seem to hit a bump.
I'm able to persist the records, but the translatable_id never gets set.
Any ideas on how this could be occuring?
<?php
//Message.php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="messages")
*/
class Message
{
use \A2lix\I18nDoctrineBundle\Doctrine\ORM\Util\Translatable;
/**
* #ORM\Column(type="guid")
* #ORM\Id
* #ORM\GeneratedValue(strategy="UUID")
*/
protected $id;
/**
* #ORM\Column(type="datetime")
*/
protected $created;
/**
* #ORM\OneToOne(targetEntity="User")
* #ORM\JoinColumn(name="author_id", referencedColumnName="id")
*/
protected $author;
/**
*/
protected $translations;
public function getTranslations(){
return $this->translations;
}
public function addTranslation($translation){
$this->translations[] = $translation;
}
public function __construct(){
$this->created = new \DateTime();
$this->translations = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return guid
*/
public function getId()
{
return $this->id;
}
public function getCreated()
{
return $this->created;
}
public function setCreated($created)
{
$this->created = $created;
return $this;
}
/**
* Set author
*
* #param \AppBundle\Entity\User $author
* #return Message
*/
public function setAuthor(\AppBundle\Entity\User $author = null)
{
$this->author = $author;
return $this;
}
/**
* Get author
*
* #return \AppBundle\Entity\User
*/
public function getAuthor()
{
return $this->author;
}
public function setTranslatable($translatable)
{
$this->translatable = $translatable;
}
}
-
//MessageTranslation.php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
*/
class MessageTranslation implements \A2lix\I18nDoctrineBundle\Doctrine\Interfaces\ManyLocalesInterface
{
use \A2lix\I18nDoctrineBundle\Doctrine\ORM\Util\Translation;
/**
* #ORM\Column(type="text")
*/
protected $message;
/**
* Set message
*
* #param string $message
* #return MessageTranslation
*/
public function setMessage($message)
{
$this->message = $message;
return $this;
}
/**
* Get message
*
* #return string
*/
public function getMessage()
{
return $this->message;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
public function setId($id){
$this->id = $id;
}
/**
* Set locale
*
* #param string $locale
* #return MessageTranslation
*/
public function setLocales($locales)
{
$this->locales = $locales;
return $this;
}
/**
* Get locale
*
* #return string
*/
public function getLocales()
{
return $this->locales;
}
public function setTranslatable($translatable)
{
$this->translatable = $translatable;
}
public function getTranslatable()
{
return $this->translatable;
}
}
I was overriding the default addTranslation and removeTranslation functions. Solved now

Definition of association cause Entity gets invalid

I'm working on a project but all the time I'm seeing this mappings problems:
The association PL\OrderBundle\Entity\Order#company refers to the
inverse side field PL\CompanyBundle\Entity\Company#id which is not
defined as association.
The association PL\OrderBundle\Entity\Order#company refers to the inverse side field
PL\CompanyBundle\Entity\Company#id which does not exist.
The association PL\OrderBundle\Entity\Order#medias refers to the owning
side field Application\Sonata\MediaBundle\Entity\Media#orders which
does not exist.
For more than I read and read Doctrine Docs I don't know how to fix them, what is wrong? any help? Here are the related entities:
PL\OrderBundle\Entity\Order.php
<?php
namespace PL\OrderBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="tb_order")
*/
class Order {
/**
* #ORM\Id
* #ORM\Column(type="string", length=15, unique=true, nullable=false)
*/
protected $no_order;
/**
* #ORM\ManyToOne(targetEntity="PL\CompanyBundle\Entity\Company", inversedBy="id")
*/
protected $company;
/**
* #ORM\Column(type="string", length=15, unique=true)
*/
protected $business_case;
/**
* #ORM\Column(type="integer", length=1)
*/
protected $charge_status;
/**
* #ORM\Column(type="datetime")
*/
protected $eta;
/**
* #ORM\Column(type="datetime")
*/
protected $etd;
/**
* #ORM\Column(type="integer", length=1)
*/
protected $transport_media;
/**
* #ORM\Column(type="integer", length=1)
*/
protected $incoterm;
/**
* #ORM\Column(type="string", length=250)
*/
protected $comments;
/**
* #ORM\ManyToMany(targetEntity="Application\Sonata\MediaBundle\Entity\Media", mappedBy="orders")
*/
protected $medias;
public function __construct() {
$this->medias = new \Doctrine\Common\Collections\ArrayCollection();
}
public function setNoOrder($no_order) {
$this->no_order = $no_order;
}
public function getNoOrder() {
return $this->no_order;
}
public function setCompany(\PL\CompanyBundle\Entity\Company $company) {
$this->company = $company;
}
public function getCompany() {
return $this->company;
}
public function setBusinessCase($business_case) {
$this->business_case = $business_case;
}
public function getBusinessCase() {
return $this->business_case;
}
public function setChargeStatus($charge_status) {
$this->charge_status = $charge_status;
}
public function getChargeStatus() {
return $this->charge_status;
}
public function setETA($eta) {
$this->eta = $eta;
}
public function getETA() {
return $this->eta;
}
public function setETD($etd) {
$this->etd = $etd;
}
public function getETD() {
return $this->etd;
}
public function setTransportMedia($transport_media) {
$this->transport_media = $transport_media;
}
public function getTransportMedia() {
return $this->transport_media;
}
public function setIncoterm($incoterm) {
$this->incoterm = $incoterm;
}
public function getIncoterm() {
return $this->incoterm;
}
public function setComments($comments) {
$this->comments = $comments;
}
public function getComments() {
return $this->comments;
}
public function setMedias(\Application\Sonata\MediaBundle\Entity\Media $media) {
$this->medias[] = $media;
}
public function addMedia(\Application\Sonata\MediaBundle\Entity\Media $media) {
$this->medias[] = $media;
}
public function getMedias() {
return $this->medias;
}
}
\PL\CompanyBundle\Entity\Company.php
<?php
namespace PL\CompanyBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* #ORM\Entity
* #ORM\Table(name="company")
*/
class Company {
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=30, unique=true, nullable=false)
*/
protected $name;
/**
* #Gedmo\Timestampable(on="create")
* #ORM\Column(name="register_date", type="datetime")
*/
protected $created_on;
/**
* #ORM\Column(type="string", length=45)
*/
protected $country;
/**
* #ORM\ManyToMany(targetEntity="Application\Sonata\UserBundle\Entity\User", mappedBy="companies")
*/
protected $users;
public function __construct() {
$this->users = new \Doctrine\Common\Collections\ArrayCollection();
}
public function getId() {
return $this->id;
}
public function setName($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
public function setCountry($country) {
$this->country = $country;
}
public function getCountry() {
return $this->country;
}
public function setCreatedOn($created_on) {
$this->created_on = $created_on;
}
public function getCreatedOn() {
return $this->created_on;
}
public function __toString() {
return $this->name;
}
}
\Application\Sonata\MediaBundle\Entity\Media.php
<?php
namespace Application\Sonata\MediaBundle\Entity;
use Sonata\MediaBundle\Entity\BaseMedia as BaseMedia;
use Doctrine\ORM\Mapping as ORM;
class Media extends BaseMedia {
/**
* #var integer $id
*/
protected $id;
/**
* #ORM\ManyToMany(targetEntity="PL\OrderBundle\Entity\Order", inversedBy="medias")
* #ORM\JoinTable(name="order_has_media__media",
* joinColumns={#ORM\JoinColumn(name="media__media_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="order_no_order", referencedColumnName="no_order")}
* )
*/
protected $orders;
public function __construct() {
$this->orders = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer $id
*/
public function getId() {
return $this->id;
}
public function setOrders(\PL\OrderBundle\Entity\Order $order) {
$this->orders[] = $order;
}
public function getOrders() {
return $this->orders;
}
}
for starters, When using bi-directional ManyToOnes and OneToManys you must have inversedBy and a matching mappedBy. in your example:
/**
* #ORM\ManyToOne(targetEntity="PL\CompanyBundle\Entity\Company", inversedBy="id")
*/
protected $company;
the inversedBy you have is basically telling doctrine that the id field (which is your primary key) of your company is a foreign key to your order entity, which is incorrect. you need to have in orders:
/**
* #ORM\ManyToOne(targetEntity="PL\CompanyBundle\Entity\Company", inversedBy="orders")
*/
protected $company;
in company:
/**
* #ORM\OneToMany(targetEntity="PL\OrderBundle\Entity\Order", mappedBy="company")
*/
private $orders;
just follow the docs:
http://docs.doctrine-project.org/en/2.0.x/reference/association-mapping.html

Symfony2 or Doctrine2 isn't unserializing values

I serialize some values when I send to DB, now I need to unserialize them in order to iterate over them. In my entity I have this:
public function getValuesText() {
return $this->values_text;
}
and then in the template I show as:
{{ element.getValuesText }}
But I get this raw result:
a:3:{i:1;s:7:"Value 1";i:2;s:7:"Value 2";i:3;s:7:"Value 3";}
And I don't know how to iterate over it to get key, values, what is failing?
UPDATE: Include mapping information
Here is:
<?php
namespace ProductBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use ProductBundle\DBAL\Types\StatusType;
use ProductBundle\DBAL\Types\FieldType;
use Fresh\Bundle\DoctrineEnumBundle\Validator\Constraints as DoctrineAssert;
/**
* #ORM\Entity
* #ORM\Table(name="product_detail")
* #Gedmo\SoftDeleteable(fieldName="deletedAt")
*/
class ProductDetail {
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\ManyToOne(targetEntity="ProductDetail")
* #ORM\JoinColumn(name="parent", referencedColumnName="id")
*/
protected $parent;
/**
* #ORM\Column(type="string", length=255)
*/
protected $description;
/**
* #ORM\Column(type="string", length=255)
*/
protected $label;
/**
* #var string $field_type
* #DoctrineAssert\Enum(entity="ProductBundle\DBAL\Types\FieldType")
* #ORM\Column(name="field_type", type="FieldType", nullable=false)
*/
protected $field_type;
/**
* #ORM\Column(name="values_text", type="array")
*/
protected $values_text;
/**
* #ORM\Column(type="string", length=255)
*/
protected $measure_unit;
/**
* #var string $status
* #DoctrineAssert\Enum(entity="ProductBundle\DBAL\Types\StatusType")
* #ORM\Column(name="status", type="StatusType", nullable=false)
*/
protected $status;
/**
* #Gedmo\Timestampable(on="create")
* #ORM\Column(name="created", type="datetime")
*/
protected $created;
/**
* #Gedmo\Timestampable(on="update")
* #ORM\Column(name="modified", type="datetime")
*/
protected $modified;
/**
* #ORM\Column(name="deletedAt", type="datetime", nullable=true)
*/
protected $deletedAt;
/**
* #ORM\ManyToMany(targetEntity="CategoryBundle\Entity\Category", inversedBy="pd_category", cascade={"persist"})
* #ORM\JoinTable(name="product_detail_has_category",
* joinColumns={#ORM\JoinColumn(name="detail", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="category", referencedColumnName="id")}
* )
*/
protected $category;
/**
* #ORM\ManyToMany(targetEntity="ProductBundle\Entity\DetailGroup", inversedBy="productDetail", cascade={"persist"})
* #ORM\JoinTable(name="detail_group_has_product_detail",
* joinColumns={#ORM\JoinColumn(name="detail", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="kgroup", referencedColumnName="id")}
* )
*/
protected $detail_group;
/**
* #ORM\Column(name="to_product", type="boolean")
*/
protected $to_product;
public function __construct() {
$this->detail_group = new \Doctrine\Common\Collections\ArrayCollection();
$this->category = new \Doctrine\Common\Collections\ArrayCollection();
}
public function getId() {
return $this->id;
}
public function setParent(ProductDetail $parent = null) {
$this->parent = $parent;
}
public function getParent() {
return $this->parent;
}
public function setDescription($description) {
$this->description = $description;
}
public function getDescription() {
return $this->description;
}
public function setLabel($label) {
$this->label = $label;
}
public function getLabel() {
return $this->label;
}
public function setFieldType($field_type) {
$this->field_type = $field_type;
}
public function getFieldType() {
return $this->field_type;
}
public function setValuesText($values_text) {
$this->values_text = $values_text;
}
public function getValuesText() {
return $this->values_text;
}
public function setMeasureUnit($measure_unit) {
$this->measure_unit = $measure_unit;
}
public function getMeasureUnit() {
return $this->measure_unit;
}
public function setStatus($status) {
$this->status = $status;
}
public function getStatus() {
return $this->status;
}
public function setCreated($param) {
$this->created = $param;
return true;
}
public function getCreated() {
return $this->created;
}
public function setModified($param) {
$this->modified = $param;
return true;
}
public function getModified() {
return $this->modified;
}
public function setCategory(\CategoryBundle\Entity\Category $category) {
$this->category[] = $category;
}
public function getCategory() {
return $this->category;
}
public function setDetailGroup(\ProductBundle\Entity\DetailGroup $detailGroup) {
$this->detail_group[] = $detailGroup;
}
public function getDetailGroup() {
return $this->detail_group;
}
public function getDeletedAt() {
return $this->deletedAt;
}
public function setDeletedAt($deletedAt) {
$this->deletedAt = $deletedAt;
}
public function setToProduct($to_product) {
$this->to_product = $to_product;
}
public function getToProduct() {
return $this->to_product;
}
}
Ok, after read and check my code I realize where the problem was:
Doctrine DBAL takes care for serialize/unserialize by using type="array" check here for more info
I made a mistake when I insert values since I was doing a unwanted serialize since as I said before Doctrine take care of this. See below:
Incorrect:
$entity->setValuesText(serialize($form->get('values_text')->getData()));
Correct:
$entity->setValuesText($form->get('values_text')->getData());
That's all, hope is helpful for someone else
Doctrine 2 DBAL ArrayType doesn't check for an array and serialize every type of parameter.
Control your database, that value should be a serialized string starting with s:
Ref: https://github.com/doctrine/dbal/blob/master/lib/Doctrine/DBAL/Types/ArrayType.php

update schema: doesn't work on a child entity

This is an entity that inherits a BaseUser:
namespace Dolphine\UserBundle\Entity;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="fos_user")
*/
class User extends BaseUser
{
/**
* #var string
*
* #ORM\Column(name="firstname", type="string", length=255)
*/
protected $firstname;
/**
* #var string
*
* #ORM\Column(name="lastname", type="string", length=255)
*/
protected $lastname;
/**
* #var string
*
* #ORM\Column(name="facebookId", type="string", length=255)
*/
protected $facebookId;
public function serialize()
{
return serialize(array($this->facebookId, parent::serialize()));
}
public function unserialize($data)
{
list($this->facebookId, $parentData) = unserialize($data);
parent::unserialize($parentData);
}
/**
* #return string
*/
public function getFirstname()
{
return $this->firstname;
}
/**
* #param string $firstname
*/
public function setFirstname($firstname)
{
$this->firstname = $firstname;
}
/**
* #return string
*/
public function getLastname()
{
return $this->lastname;
}
/**
* #param string $lastname
*/
public function setLastname($lastname)
{
$this->lastname = $lastname;
}
/**
* Get the full name of the user (first + last name)
* #return string
*/
public function getFullName()
{
return $this->getFirstname() . ' ' . $this->getLastname();
}
/**
* #param string $facebookId
* #return void
*/
public function setFacebookId($facebookId)
{
$this->facebookId = $facebookId;
$this->setUsername($facebookId);
}
/**
* #return string
*/
public function getFacebookId()
{
return $this->facebookId;
}
/**
* #param Array
*/
public function setFBData($fbdata)
{
if (isset($fbdata['id'])) {
$this->setFacebookId($fbdata['id']);
$this->addRole('ROLE_FACEBOOK');
}
if (isset($fbdata['first_name'])) {
$this->setFirstname($fbdata['first_name']);
}
if (isset($fbdata['last_name'])) {
$this->setLastname($fbdata['last_name']);
}
if (isset($fbdata['email'])) {
$this->setEmail($fbdata['email']);
}
}
}
After running schema:update --force I get "no changes available for entities", yet my DB table "fos_user" doesn't contain the given fields above.
It appears I had configuration of the bundle set to yml instead of annotations.

Resources