I have a Message entity and a User one. I want to make users be able to send messages to others. I already can send and receive messages, everything is working fine, but in order to select the receiver of a message, a default drop-down with all the users is made.
What I want to do is change the drop-down to a text field and make an AJAX to the database and retrieve a list of users that are found matching the keyword inserted in the textfield. And when clicking upon one of them, the user is introduced in the textfield.
The problem that I am facing is that I don't know how to pass an entity instead of plaintext because I get this error
Argument 1 passed to PrivateMessageBundle\Entity\Message::setReceiver() must be an instance of CrudBundle\Entity\User, string given
Another question, is there a bundle or plugin that does this easier and I can modify? Or do I have to do it myself everytime for every ajax field?
I'm building the form like so
$builder
->add('title')
->add('content','textarea')
->add('receiver','text');
By default, receiver is a drop-down select and automatically selects the User entity, but once I change it to text it doesn't.
Here's also relevant parts of my entities, if you need them:
class Message
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=50)
*/
protected $title;
/**
* #ORM\ManyToOne(targetEntity="CrudBundle\Entity\User")
* #ORM\JoinColumn(referencedColumnName="id")
*/
protected $receiver;
/**
* #ORM\ManyToOne(targetEntity="CrudBundle\Entity\User")
* #ORM\JoinColumn(referencedColumnName="id")
*/
protected $sender;
/**
* #var string
*
* #ORM\Column(name="content", type="string", length=2000)
*/
protected $content;
And my User class, extending FOSUserBundle's BaseUser class.
class User extends BaseUser implements AuthorInterface
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
I think there are two ways to solve this problem.
1) add a custum formfield with the mapped = FALSE attribute.
->add('ajaxsearch', null, array('mapped' => false))
2) use a data-transformer.
Related
I have read the official docs and many questions here. I also tried blindly few things without results. Please do not focus on "why I need it" but whether this is possible:
I have these 2 entities:
/**
* #ORM\Entity
*/
class Payout
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private ?int $id;
/**
* #ORM\ManyToMany(targetEntity="App\Entity\BalanceLog")
* #ORM\JoinTable(name="payouts_balance_logs",
* joinColumns={#ORM\JoinColumn(name="payout_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="balance_log_id", referencedColumnName="id", unique=true)}
* )
*/
private Collection $balance_logs;
}
/**
* #ORM\Entity
*/
class BalanceLog
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private ?int $id;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Payout")
*/
private ?Payout $payout;
}
One BalanceLog CAN (but does not have to) point to a Payout. And every Payout has at least one BalanceLog. This all is achieved with payouts_balance_logs table, where balance_log_id is unique (meaning a single balance log can point to only one payout)
I can easily make a bi-directional ManyToMany relationship, but then I have BalanceLog::$payouts collection, not a single object.
I can also make it bi-directional OneToMany/ManyToOne without using JoinTable, but then EVERY BalanceLog will need its nullable payout_id column.
I think that what I want has to be common and achievable. Please help, thanks!
My goal is to create Term Tables for translations in Symfony3 and Doctrine.
One Table (TERMS) should contain a Primary Key Id and the Term.
The second Table (TermLink) should contain the Link between Term and its translation which is also a Term, like: TermId | TranslationId - Those are foreign keys of the of the same primary key - Term ID Field.
There are multiple approaches to achieve this that are described: Doctrine Documentation but none of them fits my needs.
Here are my actual Entities that I would like to implement:
Term Table:
/**
* Translation Term
*
* #ORM\Table(name="translation_term")
* #ORM\Entity‚
*/
class TranslTerm
{
/**
* #var int
*
* #ORM\Column(name="term_id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $termId;
/**
* #var string
*
* #ORM\Column(name="term", type="string", length=128)
*/
private $term;
}
Link Table:
/**
* Translation Link - One To Many/JoinTable -
*
* #ORM\Table(name="translation_link")
* #ORM\Entity‚
*/
class TranslLink
{
private $id;
private $termId;
private $translationId;
}
Any help would be appreciated, thank you in advance.
Firstly look here: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html OR https://symfony.com/doc/current/doctrine/associations.html
Secondly here's something that should be a good start:
class TranslLink
{
private $id;
/**
* #ORM\ManyToOne(targetEntity="Terms", mappedBy="trans_link")
*/
private $termId;
/**
* #ORM\ManyToOne(targetEntity="Translations", mappedBy="trans_link")
*/
private $translationId;
}
PUBLIC HEALTH WARNING about the above:
straight outta the top of my head, will not work out the box and might be off. But the principle of what you want should be able to be derived from there.
in my entity Class i have added some new attributes and i want to update schema of my database. So when i run php app/console doctrine:schema:update --force im getting this error every time
[Doctrine\DBAL\Schema\SchemaException]
The table with name 'postgres.day' already exists.
and my database won't update. So does anyone know how to solve this problem?
I have read the other question with that problem but it didn't helped me. So can anyone explain me whats going on, or how to solve this? Thanks.
<?php
namespace DashboardBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* RadniNalog
*
* #ORM\Table()
* #ORM\Entity
*/
class RadniNalog
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="time_from", type="string", length=255)
*/
private $time_from;
/**
* #var string
*
* #ORM\Column(name="time_to", type="string", length=255)
*/
private $time_to;
/**
* #var string
*
* #ORM\Column(name="full_date_time", type="string", length=255)
*/
private $full_date_time;
}
it can cause this error message if you want to use a table name which is already used by one of the installed bundles.
In your case the conflicting table name is: day.
#ORM\Table no name provided within your annotation, which is required. See: Doctrine ORM | 21. Annotations Reference
#ORM\Table(name="radniNalog")
Either don't add the annotation if you want the default behaviour of Doctrine or add it correctly with the required options.
I currently have to Entities in my application:
Page
Block
A Page can have many Blocks, which are shared across many Pages, so it is quite obvious that the relation is a ManyToMany. However, I need to be able to add the same Block twice (or more) to the same Page. Doctrine creates the "page_block" join table automatically, but with page_id and block_id both as Primary Keys, therefore adding a duplicate throws an error.
Is it possible, without adding an additional Entity, to tell doctrine to allow duplicates on the Page--Block relation ?
Well, I'm not sure about that behavior in doctrine, but if that is the case, then you can do something that I almost always do. Represent the ManyToMany relation as two OneToMany-ManyToOne. You must create your own PageBlock entity and configure it's foreign keys.
class Page{
/**
* #var array
*
* #ORM\OneToMany(targetEntity="PageBlock", mappedBy="page", cascade={"all"})
*/
private $pageBlocks;
}
class Block{
/**
* #var array
*
* #ORM\OneToMany(targetEntity="PageBlock", mappedBy="block", cascade={"all"})
*/
private $pageBlocks;
}
class PageBlock{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var \stdClass
*
* #ORM\ManyToOne(targetEntity="Page", inversedBy="pageBlocks")
* #ORM\JoinColumn(name="id_page", referencedColumnName="id")
*/
private $page;
/**
* #var \stdClass
*
* #ORM\ManyToOne(targetEntity="Block", inversedBy="pageBlocks")
* #ORM\JoinColumn(name="id_block", referencedColumnName="id")
*/
private $block;
}
As you can see the primary key remains as ID, so problem resolved. I say almost always do because this is how I do it if I need an extra attribute in the relation(almost always it happens). I suspect that could be a way of do it with the ManyToMany annotation, but there is no difference with this approach.
Hope this help you.
I have an Entity Employee
class Employee
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\OneToMany(targetEntity="WorkHour", mappedBy="employee", cascade={"persist", "remove"})
*/
private $workHours;
}
and WorkHour
class WorkHour
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var Profile
*
* #ORM\ManyToOne(targetEntity="Employee", inversedBy="workHours")
* #ORM\JoinColumn(name="employee_id", referencedColumnName="id")
*/
protected $profile;
/**
* #var integer
*
* #ORM\Column(name="weekday", type="smallint")
*/
private $weekday;
/**
* #var \DateTime
*
* #ORM\Column(name="hour_from", type="time")
*/
private $hourFrom;
/**
* #var \DateTime
*
* #ORM\Column(name="hour_to", type="time")
*/
private $hourTo;
}
Now I'm confused when I'm going to add addWorkHour(), removeWorkHour() methods.
Usually one-to-many relation you can add as many relations as you want, but in my case, one employee can have only up-to-7 workHours, and for a specified weekday (from 0 to 6) can have only one (or no) record.
So I think what I need is something methods like,
public function setWorkHourByWeekday($hour_from, $hour_to, $weekday);
public function getWorkHourByWeekday($weekday);
And after set workhours for an employee, when you persist that employee,
I want doctrine delete those workhours that are no longer exist, update those workhours that are changed, and create new workhours that not exist before.
How can I implement this? Should I write these logic in class Employee or its Repository, or a WorkHourManager class?
I think WorkDay is a probably better name for your entity, so i'll use that :).
$workdays= $employee->getWorkDays();
$workdays->clear(); // Clear existing workdays
// Add new workdays
foreach(...) {
$workday = new WorkDay();
$workday ->setWeekday(0); // You could use a constant like `WorkDay::MONDAY`
$workday ->setStart('09:00');
$workday ->setEnd('17:00');
$workdays->add($workday);
}
Set orphanRemoval=true on $workHours to remove WorkHours without an Employee.
The setWeekday method in your Workday entity should throw an exception when an invalid weekday is supplied (other than 0-6). You could also use a Weekday value object in combination with Doctrine embeddables.
I'd go for a service or manager class in this case.
My advice is not to drop old workhours, maybe you don't needed now, but this data could be useful in the future. So, will be better just add workHours to the Employee and make a report the get the last workHours for today. About validations, there is a lot of ways of doing that. If you are working with forms and the rules are complex maybe you need read http://symfony.com/doc/current/cookbook/validation/custom_constraint.html , but maybe you can find alternatives in the action controller or the entity class itself.