Update Entity with a new field in a controller - Symfony 6 - php

I'm new in Symfony, and I am trying to calculate the average of the customer reviews at the controller level.
I did a dump in the foreach shown below, where I have the entity as I want, but in the return of the postman the field I added does not exist in my object.
nb: I don't have this field in my user table
My controller:
public function __invoke(UserRepository $rep, Request $request , EntityManagerInterface $em)
{
$user = $this->get('security.token_storage')->getToken()->getUser();
$dataUser = $rep->findUsersData();
$Reviews = $rep->findUsersReviews($user->getId());
$countReviews = count($Reviews);
$starsValues = 0;
foreach($Reviews as $review){
//dump($review);
$starsValues += $review['stars'];
}
$reviewsuservalue = $starsValues / $countReviews;
foreach($dataUser as $key => $userForeach){
if($userForeach->getId() == $user->getId()){
$userForeach->setReviewsuservalue($reviewsuservalue);
//dump($dataUser[$key]->getReviewsuservalue());
$em->persist($userForeach);
$em->flush();
//dump($em->flush());
}
}
return $this->json($dataUser);
}
and I add this in my entity:
private $reviewsuservalue;
and this is my getter & setter in the mentioned entity
public function getReviewsuservalue(): ?float
{
return $this->reviewsuservalue;
}
public function setReviewsuservalue(float $reviewsuservalue): self
{
$this->reviewsuservalue = $reviewsuservalue;
return $this;
}

Related

How to get ID from a relationship table, Laravel

I have 4 table : Users, CompanyRegister, VoucherDetails, Addvoucher.
So the Authenticate Users Id will be submit as user_id in companyRegister table,and then companyRegister ID will be submit as company_id in Voucherdetails table, and lastly voucherDetails Id will be submit in addVoucher table as voucher_ID. I am new to using eloquent and also laravel, I cant understand why I cant get the id from voucherdetails and submit in addvoucher but I can get id from companyregister and submit in company_id in voucherdetails. I'm using the same method to get id but not work, I hope can get solution and explanation here,Thank you in advance!!
My users model
public function companyregisters()
{
return $this->hasOne('App\companyregisters');
}
public function voucherdetails()
{
return $this->hasMany('App\voucherdetails');
}
public function addvoucher()
{
return $this->hasMany('App\addvoucher');
}
public function roles()
{
return $this->belongsToMany('App\role');
}
public function hasAnyRoles($roles)
{
if($this->roles()->whereIn('name', $roles)->first()){
return true;
}
return false;
}
public function hasRole($role)
{
if($this->roles()->where('name', $role)->first()){
return true;
}
return false;
}
my companyregister model
public function User(){
return $this->belongsTo('App\User');
}
public function voucherdetails()
{
return $this->hasMany('App\voucherdetails');
}
my voucherdetails model
public function User(){
return $this->belongsTo('User');
}
public function companyregisters(){
return $this->belongsTo('App\companyregisters');
}
public function addvoucher()
{
return $this->hasOne('App\addvoucher');
}
my addvoucher model
public function User(){
return $this->belongsTo('App\User');
}
public function voucherdetails(){
return $this->belongsTo('App\voucherdetails');
}
my voucherdetailsController
public function store(Request $request){
$voucherdetail = new voucherdetails();
$voucherdetail->title = $request->input('title');
$voucherdetail->description = $request->input('description');
$voucherdetail->user_id = Auth::user()->id;
$id = Auth::user()->id;
$user = User::find($id);
$company = $user->companyregisters;
$companyId = $company->id;
$voucherdetail->company_id = $companyId;
$voucherdetail->save();
return redirect()->to('addvoucher');
}
my addvoucherController
public function store(Request $request){
$addvoucher = new addvoucher();
$addvoucher->voucherTitle = $request->input('voucherTitle');
$addvoucher->voucherCode = $request->input('voucherCode');
$addvoucher->user_id = Auth::user()->id;
//Here(the voucherdetails id cant get to submit in voucher_id)
$id = Auth::user()->id;
$user = User::find($id);
$voucher = $user->voucherdetails;
$voucherID = $voucher->id;
$addvoucher->voucher_id = $voucherID;
$addvoucher->save();
return redirect()->to('displayVouchers');
}
This code works because companyregisters is a hasOne relationship for which the docs say:
Once the relationship is defined, we may retrieve the related record
using Eloquent's dynamic properties.
public function companyregisters()
{
return $this->hasOne('App\companyregisters');
}
$company = $user->companyregisters; // ie this returns the single related record
$companyId = $company->id; // and it has an `id` property, all good here
However, this code fails because voucherdetails is a hasMany relationship for which the docs say:
Once the relationship has been defined, we can access the "collection"
of comments by accessing the comments property.
More info on collections
public function voucherdetails()
{
return $this->hasMany('App\voucherdetails');
}
$voucher = $user->voucherdetails; // ie this returns a "collection" of related records
$voucherID = $voucher->id; // this "collection" does NOT have an id property, but each record IN the collection does.
In summary, either your relationship is defined incorrectly (hasMany vs hasOne) or, you'll need to loop over the related records to get the id from each.

Parse data after getChangeSet action in Symfony, Doctrine

I have this EventSubscriber:
class ChangeLogListener implements EventSubscriber
{
private $tokenStorage;
private $str,$str1;
public function __construct(TokenStorage $tokenStorage)
{
$this->tokenStorage = $tokenStorage;
}
public function getSubscribedEvents()
{
return array(
'postPersist',
'postUpdate',
'onDelete',
);
}
public function postPersist(LifecycleEventArgs $args)
{
if (!$args->getEntity() instanceof ChangeLog)
$this->createLog($args, 'creation');
}
public function postUpdate(LifecycleEventArgs $args)
{
$this->createLog($args, 'update');
}
public function preRemove(LifecycleEventArgs $args)
{
$this->createLog($args, 'remove');
}
public function createLog(LifecycleEventArgs $args, $action)
{
# Entity manager
$em = $args->getEntityManager();
$uow = $em->getUnitOfWork();
$entity = $args->getEntity();
# Get user
$user = $this->tokenStorage->getToken()->getUser();
#Get changes
$changes = $uow->getEntityChangeSet($entity);
$cl = new ChangeLog();
$cl->setDate(new \DateTime());
$cl->setUser($user);
$cl->setEntityName(get_class($entity));
$cl->setEntityId($entity->getId());
$cl->setAction($action);
$cl->setDescription($log);
$cl->setChangeset($changes);
$em->persist($cl);
$em->flush();
}
}
And when I want to POST item, some data must be recorded to db. After all actions I receive this in change_set in my db:
a:3:{s:5:"value";a:2:{i:0;N;i:1;s:3:"120";}s:4:"item";a:2:{i:0;N;i:1;O:21:"AppBundle\Entity\Item":6:{s:25:"AppBundle\Entity\Itemid";i:127;s:27:"AppBundle\Entity\Itemname";s:7:"newitem";s:13:"*categories";O:33:"Doctrine\ORM\PersistentCollection":2:{s:13:"*collection";O:43:"Doctrine\Common\Collections\ArrayCollection":1:{s:53:"Doctrine\Common\Collections\ArrayCollectionelements";a:2:{i:0;O:25:"AppBundle\Entity\Category":7:{s:29:"AppBundle\Entity\Categoryid";i:2;s:31:"AppBundle\Entity\Categoryname";s:10:"child
to
1";s:33:"AppBundle\Entity\Categoryparent";O:40:"Proxies__CG__\AppBundle\Entity\Category":8:{s:17:"isInitialized";b:0;s:29:"AppBundle\Entity\Categoryid";i:1;s:31:"AppBundle\Entity\Categoryname";N;s:33:"AppBundle\Entity\Categoryparent";N;s:35:"AppBundle\Entity\Categorychildren";N;s:8:"*items";N;s:36:"AppBundle\Entity\CategorycreatedAt";N;s:36:"AppBundle\Entity\CategoryupdatedAt";N;}s:35:"AppBundle\Entity\Categorychildren";O:33:"Doctrine\ORM\PersistentCollection":2:{s:13:"*collection";O:43:"Doctrine\Common\Collections\ArrayCollection":1:{s:53:"Doctrine\Common\Collections\ArrayCollectionelements";a:0:{}}s:14:"*initialized";b:0;}s:8:"*items";O:33:"Doctrine\ORM\PersistentCollection":2:{s:13:"*collection";O:43:"Doctrine\Common\Collections\ArrayCollection":1:{s:53:"Doctrine\Common\Collections\ArrayCollectionelements";a:0:{}}s:14:"*initialized";b:0;}s:36:"AppBundle\Entity\CategorycreatedAt";N;s:36:"AppBundle\Entity\CategoryupdatedAt";N;}i:1;O:25:"AppBundle\Entity\Category":7:{s:29:"AppBundle\Entity\Categoryid";i:4;s:31:"AppBundle\Entity\Categoryname";s:8:"child1.1";s:33:"AppBundle\Entity\Categoryparent";r:13;s:35:"AppBundle\Entity\Categorychildren";O:33:"Doctrine\ORM\PersistentCollection":2:{s:13:"*collection";O:43:"Doctrine\Common\Collections\ArrayCollection":1:{s:53:"Doctrine\Common\Collections\ArrayCollectionelements";a:0:{}}s:14:"*initialized";b:0;}s:8:"*items";O:33:"Doctrine\ORM\PersistentCollection":2:{s:13:"*collection";O:43:"Doctrine\Common\Collections\ArrayCollection":1:{s:53:"Doctrine\Common\Collections\ArrayCollectionelements";a:0:{}}s:14:"*initialized";b:0;}s:36:"AppBundle\Entity\CategorycreatedAt";N;s:36:"AppBundle\Entity\CategoryupdatedAt";N;}}}s:14:"*initialized";b:1;}s:13:"*attributes";N;s:32:"AppBundle\Entity\ItemcreatedAt";O:8:"DateTime":3:{s:4:"date";s:26:"2018-03-19
10:22:47.000000";s:13:"timezone_type";i:3;s:8:"timezone";s:3:"UTC";}s:32:"AppBundle\Entity\ItemupdatedAt";N;}}s:9:"attribute";a:2:{i:0;N;i:1;O:26:"AppBundle\Entity\Attribute":3:{s:30:"AppBundle\Entity\Attributeid";i:96;s:33:"AppBundle\Entity\Attributealias";s:5:"price";s:32:"AppBundle\Entity\Attributename";s:5:"price";}}}
But I think this data is not readable.I think I need to parse received data before writing it into db, but I don't understand how to parse this into readable format, something like this:
name: Old Value: 12 => New Value: 121, updatedAt: Old Value:
2018-03-20 05:51:44 => New Value: 2018-03-20 08:36:12 and other
Any idea how to parse this?
You are directly inserting all work done on entities with whole object, that's why you are saving all the meta-data into db. Better to doctrine customized extension to handle this (doctrine-extensions and see Loggable behavioral extension for Doctrine2) or if you want to create self customized ChangeLogListner then use methods to compute or get exact change-Set using doctrine methods. to methods see here.
you can change your EventListner code something like this:
$em = $this->getDoctrine()->getManager();
$entity = $em->find('My\Entity', 1);
$entity->setTitle('Changed Title!');
$uow = $em->getUnitOfWork();
$uow->computeChangeSets(); // do not compute changes if inside a listener
$changeset = $uow->getEntityChangeSet($entity);
or check Is there a built-in way to get all of the changed/updated fields in a Doctrine 2 entity
if you are trying inside EventListner then try inside particular events like:
public function preUpdate(Event\LifecycleEventArgs $eventArgs)
{
$changeArray = $eventArgs->getEntityChangeSet();
//do stuff with the change array
}

Objects are not persisted by Doctrine

last couple of days I've been busy making a form using Doctrine and MongoDB. Companies should be able to reserve tables, chairs, .. at a certain event by use of this form. The snippet below shows the controller for this form.
The 'ObjectMap' object maps the amount of a certain object to the object itself. The controller creates all the 'ObjectMap' objects, and adds them to the company object. However, the 'ObjectMap' objects are persisted by Doctrine (they show up in the database) but the company object isn't modified at all, there is no database request made by MongoDB. The persist() function seems to have no effect at all.
public function logisticsAction(Company $company)
{
$form = $this->createForm(new LogisticsForm($this->getDoctrine()->getManager()), $company);
if ($this->getRequest()->isMethod('POST')) {
$form->bind($this->getRequest());
if ($form->isValid()) {
$formData = $this->getRequest()->request->get('_company_logistics_edit');
$objects = $this->getDoctrine()->getManager()
->getRepository('Jobfair\AppBundle\Document\Company\Logistics\Object')
->findAll();
foreach($objects as $object) {
$requirement = $formData['objectRequirement_'.$object->getId()];
$map = new ObjectMap($requirement, $object);
$this->getDoctrine()->getManager()->persist($map);
$company->addObjectMap($map);
//print_r($company->getObjectMaps());
}
$this->getDoctrine()->getManager()->persist($company);
$this->getDoctrine()->getManager()->flush();
$this->getRequest()->getSession()->getFlashBag()->add(
'success',
'The information was successfully updated!'
);
return $this->redirect(
$this->generateUrl(
'_company_settings_logistics',
array(
'company' => $company->getId(),
)
)
);
}
}
The Company object is defined here:
class Company{
/**
* #ODM\Id
*/
private $id;
/*
* #ODM\ReferenceMany(targetDocument="Jobfair\AppBundle\Document\Company\Logistics\ObjectMap", cascade={"persist", "remove"})
*/
private $objectMaps;
public function __construct($name = null, $description = null)
{
$this->objectMaps = new ArrayCollection();
}
public function getId()
{
return $this->id;
}
public function getObjectMaps()
{
return $this->objectMaps;
}
public function getObjectsArray()
{
$objects = array();
foreach($this->objectMaps as $map)
$objects[] = array(
'name' => $map->getObject()->getName(),
'amount' => $map->getRequirement()
);
return $objects;
}
public function addObjectMap(ObjectMapDocument $objectMap)
{
$this->objectMaps[] = $objectMap;
}
public function removeObject(ObjectMapDocument $objectMap)
{
$this->objectMaps->removeElement($objectMap);
}
}

Unable to create data through show method in Laravel 5.3

I am working on notifications I have 2 tables: one is notify and the other is notify_status. Through notify I am showing data like title and description and in notify_status I have field read_status which is by default 0. After I show it I want to change it to 1. I also have notify_id in it as a foreign key. This is my show method:
public function show($id)
{
$notify = Notify::find($id);
$notify_status = NotifyStatus::where('notify_id', $id)->get();
$user_data['read_status'] = 1;
$user = NotifyStatus::create($user_data);
return view('notify.desr')->with(compact('notify'));
}
But it isn't creating against notify_id. What should I do?
Your models should define the following relationships:
class Notify extends Model
{
public function setAsRead()
{
$this->status->read_status = 1
$this->status->save();
}
public function wasRead()
{
return (bool) $this->status->read_status;
}
public function status()
{
return $this->hasOne(NotifyStatus::class);
}
}
class NotifyStatus extends Model
{
public function notify()
{
return $this->belongsTo(Notify::class);
}
}
Take a look at Laravel Eloquent Relationships for further reading.
In your controller you can use it like:
$notify = Notify::find($id);
$notify->status->read_status = 1;
$notify->status->save();
return view('notify.desr')->with(compact('notify'));
Or you can simply create a new method to set the new status (take a look at first method of Notify class):
$notify = Notify::find($id);
$notify->setAsRead();
return view('notify.desr')->with(compact('notify'));
public function show($id)
{
$notify = Notify::find($id);
$notify_status = NotifyStatus::where('notify_id', $id)->first();
$notify_status->read_status = 1;
$notify_status->save()
return view('notify.desr')->with(compact('notify'));
}

Laravel Repositories Relationhips

I have a simple relationship between users and posts(User model and Post model) and i am using Repositories.
<?php namespace St0iK\Storage\Post;
use Post;
class EloquentPostRepository implements PostRepository {
protected $errors;
public function all()
{
return Post::all();
}
public function find($id)
{
return Post::find($id);
}
public function create($input)
{
return Post::create($input);
}
}
In my controller i have:
public function store()
{
// Get input from the form
$input = Input::all();
$input['user_id'] = (int)Auth::user()->id;
$p = $this->post->create( Input::all() );
if( $p->errors()->isEmpty() )
{
return Redirect::route('home')->with('flash', 'The new post has been created');
}
return Redirect::route('upload.create')->withInput()->withErrors($p->errors());
}
But the 'post' is not inserted in the database. I get validation errors(i am using Ardent) that all my fields are missing!
But if i try something like that in my controller:
$user = User::find( (int)Auth::user()->id);
$user->posts()->save($post);
it works just fine.
How can i implement this to my Post Repository so i can insert a new Post with re related user and pass the user_id?

Categories