I want to join two tables (games and ownership). From there, I want to print those Games which user has assigned to him in Ownership. For example: user (id: 2) has two games (id: 1 and id:2). I want to print only these two.
My controller is as follows:
function getGameAction($id) {
$game = $this->getDoctrine()
->getRepository('GameShelfGamesBundle:Game')
->find($id);
return new Response($game->getOwnership()->getName());
}
Entities: Ownership and Game.
For now, I only get an error:
Fatal error: Call to undefined method Proxies__CG__\GameShelf\UsersBundle\Entity\Ownership::getName() in D:!!XAMPP\htdocs\Symfony\src\GameShelf\GamesBundle\Controller\DefaultController.php on line 50
Look at error message - you don't have either any getOwnership method or even relation with ownership table.
For first you need in you game entity declare relation with ownership:
/*
* #ORM\ManyToOne(targetEntity="Namespace\To\Ownership", inversedBy="games")
* #ORM\JoinColumn(name="ownership_id", referencedColumnName="id")
*/
private $ownership;
And in your Ownership entity:
/**
* #ORM\OneToMany(targetEntity="Namespace\To\Game", mappedBy="ownership")
*/
private $games;
Then run console command to generate setters and getters and everything should goes fine.
You just forgot to add a variable named "name" in your Ownership-Entity. Therefore you don't have any getters and setters automatically generated.
Try to put all your variables at the beginning of your code #Cyprian oversaw your relation because of that.
If you just look at the errormessage you should instantly see where your error is coming from.
Related
I have a member of my entity is an arrayCollection. With a classic form builder is working fine, I can select multiple items and persist it. But when I try to update an object in controller I get the error : "Call to a member function setFaavailability() on array".
A resume of my entity :
/**
* #ORM\ManyToOne(targetEntity="App\Entity\FaAvailability",
inversedBy="faavailability")
* #ORM\JoinColumn(nullable=true)
* #ORM\Column(type="array")
*/
public $faavailability;
/**
* #return mixed
*/
public function getFaavailability()
{
return $this->faavailability;
}
/**
* #param mixed $faavailability
*/
public function setFaavailability($faavailability)
{
$this->faavailability = $faavailability;
}
In my controler :
$varFaavailability = $animal->faperson->getFaavailability();
foreach($varFaavailability as $availability){
if($availability->getName() == $animal->typepet->getName()){
$varFaavailability->removeElement($availability);
$faPerson = $em->getRepository(FaPerson::class) >findById($animal->faperson->getId());
$faPerson->setFaavailability($varFaavailability);
$em->persist($faPerson);
$em->flush();
}
}
Any ideas ?
If I remember well, when you set a field as an ArrayCollection it means that you have a oneToMany relationship between two entities.
From your code, I can tell you that you are trying to persist the data in the wrong entity. You usually add the owning_entity_id(1-to-N) in each item(1-to-N) and persist it. In your code, you are trying to set all the references at once, which is never going to happen. Delete the setFaavailability() or redefine the entities' relationships.
You should never try to mass-add foreign key relationships in one super duper setter function. Cycle through all the items and set the reference to the "parent" entity.
The problem is in this part: $faPerson = $em->getRepository(FaPerson::class)->findById($animal->faperson->getId());
The findBy* methods will try to find multiple entities and return them in a Collection.
If you're looking for a single person, you can use findOneById instead. Or (assuming id is configured as identifier in Doctrine) you can even use the find method: $faPerson = $em->getRepository(FaPerson::class)->find($animal->faperson->getId());
some general comments:
In Doctrine you never have to work with the IDs. Use the entity
objects! You only need to findById if you get the ID from a request parameter for example.
You should reconsider the naming of your variables to make it clear if it is a collection ($availabilities) or a single one ($availability).
Always use the getter/setter methods instead of the fields (typepet vs getTypepet()).
Call flush() one at the end to update all entities in one single transaction.
I've renamned the variables below as I understood them. However I am still not sure what $animal->faperson->getFaavailabilities() returns, since at the beginning you wanto to loop through the results and later set it to a single one via setFaavailability()?
//Should be a Doctrine ArrayCollection
$varFaavailabilities = $animal->faperson->getFaavailabilities();
foreach($varFaavailability as $availability){
if($availability->getName() == $animal->getTypepet()->getName()) {
//Why do you want to remove an element from the current loop?
$varFaavailability->removeElement($availability);
//No need to use Id
$faPerson = $animal->getFaperson();
//A single one?
$faPerson->setFaavailability($availability);
//More than one? addFaavailability should exist.
$faPerson->addFaavailability($availability);
$em->persist($faPerson);
}
}
$em->flush();
I need to create a custom FE user with some custom fields.
Also, it needs to be assignable through the frontend to different user groups.
You can find my first approach here. Didn't work out that well.
Second approach was to create another extension and follow the guide which is shown here.
First thing I did was to add \TYPO3\CMS\Extbase\Domain\Model\FrontendUser into the Extend existing model class-field for my CustomFEU-model.
Then I created another model which I named FEgroup and I mapped it to the table fe_groups. After that, I connected an n:m relation to the CustomFEU.
When I try to create a new CustomFEU with the new action, it returns a white empty page after submitting the form and no user is being added.
The only strange thing I found was that the /Classes/Domain/Repository/ folder is empty.
TYPO3 7.6.8
Although I didn't edit the files yet, here they are:
Model / Controller / Setup
Did anyone encounter similar problems?
First you need to create the repositories that handle the new user and usergroup models.
Second you try to save the user with $this->customFEURepository->add($newCustomFEU); and the variable customFEURepository does not exist. It would be the best to inject it, it has to be the repository that you should create first. You can inject it like that:
/**
* CustomFEUController
*/
class CustomFEUController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController
{
/**
* #var \Vendor\Feregistration\Repository\CustomFEURepository
* #inject
*/
protected $customFEURepository;
// other code ...
}
Don't forget to clear the system cache after adding inject annotations, otherwise it wont work.
Last but not least i can't see the mapping to the database table for your model. You need to add it to your TypoScript (setup.txt)
config.tx_extbase.persistence.classes {
Vendor\Feregistration\Domain\Model\CustomFEU {
mapping {
recordType = 0
tableName = fe_users
}
}
Vendor\Feregistration\Domain\Model\FEGroups {
mapping {
recordType = 0
tableName = fe_groups
}
}
}
first off some code:
class User {
* #ORM\OneToMany(targetEntity="Profile", mappedBy="user")
*/
protected $profiles;
}
(There's come more code, but this is the part affecting my problem).
So for example I have
Already in Database
User1: id = 1
Profile1: id = 1, parent = User1
Profile2: id = 2, parent = User2
Not yet persisted
Profile3:
Profile4:
What I want to do is to be able to just call:
$user1->removeAllProfiles(); $user1->addAllNewProfiles(array($profile3, $profile4));
and this should automatically delete all the old profiles and add all the new.
I hope it's clear what I want to achieve. Anyone having an idea?
You can update your property annotation to make use of orphanRemoval...
/** #OneToMany(targetEntity="Profile", mappedBy="user", orphanRemoval=true) */
protected $profiles;
This tells Doctrine to remove any profiles that are left without an associated User object, so when you call $user->removeAllProfiles(); and then call $em->flush() any previous Profile objects associated with the user will be removed from the database.
I am currently trying to extend the SonataUserBundle's User to add a new ManyToMany relationship with a existing Entity.
I extended the User based on the answer found here - Extending Sonata User Bundle and adding new fields
User.php
/**
* #ORM\ManyToMany(targetEntity="Foo\BarBundle\Entity\Pledge", inversedBy="pledgedUsers")
**/
private $pledgedOn;
// (...) generated getters and setters here
Pledge.php
/**
* #ORM\ManyToMany(targetEntity="Foo\UserBundle\Entity\User", inversedBy="pledgedOn")
**/
private $pledgedUsers;
// (...) generated getters and setters here
The first thing I noticed when I sync the schema, is that it creates 2 pivot tables, instead of just one: pledge_user and user_pledge. I tried adding a #ORM\JoinTable in, but that's just changing the name of one. When I add the same #ORM\JoinTable to both, I get the 'table already exists' error.
When I try to access the user list in admin, I am getting a big sql error
An exception occurred while executing 'SELECT count(DISTINCT u0_.id) AS sclr0 FROM User u0_ LEFT JOIN fos_user_user_group f2_ ON u0_.id = f2_.user_id LEFT JOIN fos_user_group f1_ ON f1_.id = f2_.group_id':
SQLSTATE[42703]: Undefined column: 7 ERROR: column u0_.id does not exist
I am sure this is something simple, but I am smacking my head finding the source of this problem. What did I miss?
Full User.php: http://pastebin.com/TXunsgm1
Full Pledge.php: http://pastebin.com/Mta6aiVm
I knew it was a derpy error. I had
* #ORM\ManyToMany(targetEntity="Foo\UserBundle\Entity\User", inversedBy="pledgedOn")
and
* #ORM\ManyToMany(targetEntity="Foo\BarBundle\Entity\Pledge", inversedBy="pledgedUsers")
One of them had to be mappedBy instead of inversedBy . Changing the second one to
* #ORM\ManyToMany(targetEntity="Foo\BarBundle\Entity\Pledge", mappedBy="pledgedUsers")
fixed the problem.
In Doctrine2.0.6, I keep getting an error: "Column VoucherId specified twice".
The models in question are:
Basket
BasketVoucher
Voucher
Basket links to BasketVoucher.
Voucher links to BasketVoucher.
In Voucher and BasketVoucher, there is a field called VoucherId. This is defined in both models and exists with the same name in both DB tables.
The error occurs when saving a new BasketVoucher record:
$basketVoucher = new BasketVoucher;
$basketVoucher->setVoucherId($voucherId);
$basketVoucher->setBasketId($this->getBasket()->getBasketId());
$basketVoucher->setCreatedDate(new DateTime("now"));
$em->persist($basketVoucher);
$em->flush();
I've checked the models and VoucherId is not defined twice. However, it is used in a mapping. Is this why Doctrine thinks that the field is duplicated?
Here's the relevant code - I haven't pasted the models in their entirety as most of the code is get/set.
Basket
/**
* #OneToMany(targetEntity="BasketVoucher", mappedBy="basket")
* #JoinColumn(name="basketId", referencedColumnName="BasketId")
*/
private $basketVouchers;
public function getVouchers()
{
return $this->basketVouchers;
}
BasketVoucher
/**
* #ManyToOne(targetEntity="Basket", inversedBy="basketVouchers")
* #JoinColumn(name="basketId", referencedColumnName="BasketId")
*/
private $basket;
public function getBasket()
{
return $this->basket;
}
/**
* #OneToOne(targetEntity="Voucher", mappedBy="basketVoucher")
* #JoinColumn(name="voucherId", referencedColumnName="VoucherId")
*/
private $voucherEntity;
public function getVoucher()
{
return $this->voucherEntity;
}
Voucher
/**
* #OneToOne(targetEntity="BasketVoucher", inversedBy="voucherEntity")
* #JoinColumn(name="voucherId", referencedColumnName="VoucherId")
*/
private $basketVoucher;
public function getBasketVoucher()
{
return $this->basketVoucher;
}
Any ideas?
EDIT: I've found that the same issue occurs with another model when I save it for the first time. I am setting the primary key manually. The main issue appears to be saving a relationship within an entity.
In this case, I have a field - DraftOrderId - which is used as the primary key on three models. The first model - DraftOrder - has DraftOrderId as a primary key, which is an auto incrementing value. The other two models - DraftOrderDeliveryAddress, and DraftOrderBillingAddress - also use DraftOrderId as a primary key, but it isn't auto incremented.
What's happening is one of the following issues:
If I save the delivery address entity with a draft order id and set it to persist, I get an error: Column DraftOrderId specified twice. Code:
try {
$addressEntity->getDraftOrderId();
} catch (\Doctrine\ORM\EntityNotFoundException $e) {
if ($addressType == "delivery") {
$addressEntity = new Dpp\DraftOrderDeliveryAddress;
} elseif ($addressType == "billing") {
$addressEntity = new Dpp\DraftOrderBillingAddress;
}
$addressEntity->setDraftOrderId($draftOrder->getDraftOrderId());
$em->persist($addressEntity);
}
(It would also help to know if there's a better way of checking if a related entity exists, rather than trapping the exception when trying to get a value.)
If I remove the line that sets the draft order id, I get an error: Entity of type Dpp\DraftOrderDeliveryAddress is missing an assigned ID.
If I keep the line that sets the draft order id but I remove the persist line, and I also keep the lines later on in the code that sets the name and address fields, I don't get an error - but the data is not saved to the database. I am using flush() after setting all the fields - I'm just not using persist(). In the previous examples, I do use persist() - I'm just trying things out to see how this can work.
I can paste more code if it would help.
I think I've fixed it! A couple of findings:
For a primary key that is not an auto-incrementing value, you need to use:
#generatedValue(strategy="IDENTITY")
You also have to explicitly set the mapped entities when creating them for the first time. At first, I was trying to create the address entity directly, but I wasn't setting the mapped entity within the parent model to reference the address entity. (if that makes any sense)
I'm fairly sure it was mostly due to the lack of the IDENTITY keyword, which for some reason was either saying the key wasn't set, or saying it was set twice.