EasyAdmin convert value - php

For work I need to read through Symfony 5: The Fast Track. But in chapter 9 I have some problems. I have two entities Conference and Comment. The Comment entity is connected with the ID of the Conference.
Comment:
/**
* #ORM\ManyToOne(targetEntity=Conference::class, inversedBy="comments")
* #ORM\JoinColumn(nullable=false)
*/
private $conference;
public function setCreatedAt(\DateTimeInterface $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
public function getConference(): ?Conference
{
return $this->conference;
}
My EasyAdminController looks like this:
public function configureMenuItems(): iterable
{
return [
MenuItem::linkToCrud('Conference', '', Conference::class),
MenuItem::linkToCrud('Comment', '', Comment::class)>setController(CommentCrudController::class),
];
}
And the CommentCrudController likt that:
public function configureFields(string $pageName): iterable
{
return [
TextField::new('author'),
TextEditorField::new('text'),
TextField::new('email'),
DateTimeField::new('createdAt'),
IdField::new('conference')->formatValue(function ($value) {
dd($value);
}),
TextField::new('photoFilename'),
];
}
So first my problem is that I need values as a object of Conference. Because I don't know how to do it right I tried to use formatValue but the dd($value)is never executed. Can someone help me with that problem or link me somewhere where I can find the answer.
Thank you in advantage.

Related

How to read a DC2Type array with doctrine and symfony

I'm setting up an advanced search for a jobboard and I need to find resumes by contract, knowing that a resume can have multiple contracts.
I have a form where you can choose which type of contract you are looking for (It's a ChoiceType::class with multiple => true)
In my table, my colomn contract :
In my Entity Resume :
/**
* #ORM\Column(type="array", nullable=true)
*/
private $contract = [];
public function getContract(): ?array
{
return $this->contract;
}
public function setContract(?array $contract): self
{
$this->contract = $contract;
return $this;
}
In my repository :
public function findByContract(array $contract)
{
return $this->createQueryBuilder('r')
->andWhere('r.contract IN (:cons)')
->setParameter('cons', $contract)
->getQuery()
->getResult()
;
}
In my controller :
public function index(Request $request, ResumeRepository $resumeRepository)
{
$formSearch = $this->createForm(ResumeSearchFormType::class);
$formSearch->handleRequest($request);
if ($formSearch->isSubmitted() && $formSearch->isValid()) {
$data = $formSearch->getData();
$results = $resumeRepository->findByContract($data->getContract());
var_dump($results); die;
This var_dump() returns an empty array.
I don't know how I can do to find resume by contract
I suppose that you find the solution but maybe I can help someone else!
I had the same issue, so I used LIKE instead of IN, and I used the setParameter differently.
Like this :
return $this->createQueryBuilder('r')
->andWhere('r.contract LIKE (:cons)')
->setParameter('cons', '%' .$contract. '%')
->getQuery()
->getResult();
If you want more information about it, check this: What is DC2Type array datatype in mysql

Chaining Symfony Repository Methods ( Filters )

What is the best practice to chain repository methods to reuse query building logic?
Here is how I did it, but I doubt if this is the right way:
use Doctrine\ORM\Mapping;
use Doctrine\ORM\EntityManager;
class OrderRepository extends \Doctrine\ORM\EntityRepository
{
private $q;
public function __construct(EntityManager $em, Mapping\ClassMetadata $class)
{
parent::__construct($em, $class);
$this->q = $this->createQueryBuilder('o');
}
public function getOneResult()
{
return $this->q->getQuery()->getOneOrNullResult();
}
public function getResult()
{
return $this->q->getQuery()->getResult();
}
public function filterByStatus($status)
{
$this->q->andWhere('o.status = :status')->setParameter('status', $status);
return $this;
}
public function findNextForPackaging()
{
$this->q->leftjoin('o.orderProducts', 'p')
->orderBy('o.deliveryDate', 'ASC')
->andHaving('SUM(p.qtePacked) < SUM(p.qte)')
->groupBy('o.id')
->setMaxResults(1);
return $this;
}
}
This allows me to chain method like this:
$order = $em->getRepository('AppBundle:Order')->filterByStatus(10)->findNextForPackaging()->getOneResult();
This is of course just an example. In reality there are many more methods that can be chained.
One big problem with this is the fact that I need a join for some of the "filters", so I have to check if the join has already been set by some method/filter before I add it. ( I did not put it in the example, but I figured it out, but it is not very pretty )
The other problem is that I have to be careful when using the repository, as the query could already be set to something, so I would need to reset the query every time before using it.
I also understand that I could use the doctrine "matching" method with criteria, but as far as I understood, this is rather expensive, and also, I don't know how to solve the "join" Problem with that approach.
Any thoughts?
I made something similar to what you want:
Controller, this is how you use it. I am not returning Response instance but serialize the array in kernel.view listener but it is still valid example:
/**
* #Route("/root/pending_posts", name="root_pending_posts")
* #Method("GET")
*
* #return Post[]
*/
public function pendingPostsAction(PostRepository $postRepository, ?UserInterface $user): array
{
if (!$user) {
return [];
}
return $postRepository->begin()
->wherePublished(false)
->whereCreator($user)
->getResults();
}
PostRepository:
class PostRepository extends BaseRepository
{
public function whereCreator(User $user)
{
$this->qb()->andWhere('o.creator = :creator')->setParameter('creator', $user);
return $this;
}
public function leftJoinRecentComments(): self
{
$this->qb()
->leftJoin('o.recentCommentsReference', 'ref')->addSelect('ref')
->leftJoin('ref.comment', 'c')->addSelect('c');
return $this;
}
public function andAfter(\DateTime $after)
{
$this->qb()->andWhere('o.createdAt > :after')->setParameter('after', $after);
return $this;
}
public function andBefore(\DateTime $before)
{
$this->qb()->andWhere('o.createdAt < :before')->setParameter('before', $before);
return $this;
}
public function wherePublished(bool $bool)
{
$this->qb()->andWhere('o.isPending = :is_pending')->setParameter('is_pending', !$bool);
return $this;
}
}
and BaseRepository has most used stuff, still work in progress:
namespace wjb\CoreBundle\Model;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder;
abstract class BaseRepository extends EntityRepository
{
/** #var QueryBuilder */
private $qb;
public function begin()
{
$this->qb = $this->createQueryBuilder('o');
return $this;
}
public function qb(): QueryBuilder
{
return $this->qb;
}
public function none()
{
$this->qb()->where('o.id IS NULL');
return $this;
}
public function setMaxResults($maxResults)
{
$this->qb()->setMaxResults($maxResults);
return $this;
}
public function addOrderBy($sort, $order = null)
{
$this->qb()->addOrderBy($sort, $order);
return $this;
}
public function getResults()
{
return $this->qb()->getQuery()->getResult();
}
}
This helps me a lot in chaining calls like in controller example.

Calling a function inside a function [PHP, Laravel, Eloquentl]

I am using October CMS built on Laravel, and I am having some strange issues I am not sure how to interpret.
Code Sample 1: Works fine (Component EstateList)
public function onRun()
{
$this->listEstates();
}
/**
* Pulls all the estates from the model
*
* #return $estateList
*/
protected function listEstates()
{
$estateList = RealEstate::all();
return $estateList;
}
Code Sample 2: Doesn't work (Component EstateDetails)
public function onRun()
{
$this->show();
}
/**
* Returns the slug and display individual Estate Object
*
* #return $pageDetails
*/
protected function show()
{
$slug = $this->param('slug');
$pageDetails = RealEstate::find($slug);
echo $slug; //returns slug as it should
echo $pageDetails; //empty
if ($pageDetails) {
return $pageDetails;
} else {
return \Response::make('Page not found', 404);
}
}
If I just put the code of show() into the function onRun() it works fine. Why does echo echo $pageDetails return empty on the Code Sample 2? if it is ran in a seperate function show().
Thank you for your help.
Try changing it to RealEstate::where('slug', '=', $slug)->firstOrFail();. The find bit searches the ID table for the column, not the slug.
You are not 'returning' the Response from show()
Try changing $this->show(); to return return $this->show(); in onRun()
Try changing your code to this
public function onRun()
{
return $this->show();
}
/**
* Returns the slug and display individual Estate Object
*
* #return $pageDetails
*/
protected function show()
{
$slug = $this->param('slug');
$pageDetails = RealEstate::where('slug', '=', $slug)->firstOrFail();;
echo $slug; //returns slug as it should
echo $pageDetails; //empty
if ($pageDetails) {
return $pageDetails;
} else {
return \Response::make('Page not found', 404);
}
}
Hopefully This will solve your problem

MongoDB only works when using fetch via other function

I am trying to get a record from my MongoDB. To get the record I use the following code;
public function getEventsForAggregate($identifier)
{
$events = $this->MongoCollection()->findOne([
'_id' => $identifier
], [
'events',
]);
var_dump($events);
}
Unfortunately it dies on the findOne.
Do I change the code so the findOne is in a protected function it does work.
So the following code does work.
public function getEventsForAggregate($identifier)
{
$events = $this->getEvents($identifier);
var_dump($events);
}
protected function getEvents($identifier)
{
return $this->MongoCollection()->findOne([
'_id' => $identifier
], [
'events',
]);
}
Can some one explain how it is possible that the first code breaks, but the second one works?
Extra code;
/** #var MongoCollection */
protected $mongoCollection;
public function __construct(MongoCollection $MongoCollection)
{
$this->mongoCollection = $MongoCollection;
}
/**
* #return MongoCollection
*/
protected function MongoCollection()
{
return $this->mongoCollection;
}

accessing object and its relations in laravel 4.1

I hope I can explain this clearly, apologies in advance if it is confusing. I have a goals table which hasOne of each of bodyGoalDescs, strengthGoalDescs and distanceGoalDescs as shown below
goals.php
class Goal extends BaseModel
{
protected $guarded = array();
public static $rules = array();
//define relationships
public function user()
{
return $this->belongsTo('User', 'id', 'userId');
}
public function goalStatus()
{
return $this->hasOne('GoalStatus', 'id', 'goalStatus');
}
public function bodyGoalDesc()
{
return $this->hasOne('BodyGoalDesc', 'id', 'bodyGoalId');
}
public function distanceGoalDesc()
{
return $this->hasOne('DistanceGoalDesc', 'id', 'distanceGoalId');
}
public function strengthGoalDesc()
{
return $this->hasOne('StrengthGoalDesc', 'id', 'strengthGoalId');
}
//goal specific functions
public static function yourGoals()
{
return static::where('userId', '=', Auth::user()->id)->paginate();
}
}
each of the three tables looks like this with the function details changed
class BodyGoalDesc extends BaseModel
{
protected $guarded = array();
public static $rules = array();
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'bodyGoalDescs';
//define relationships
public function goal()
{
return $this->belongsTo('Goal', 'bodyGoalId', 'id');
}
}
a goal has either a body goal, a strength goal, or a distance goal. I am having a problem with this method in the controller function
<?php
class GoalsController extends BaseController
{
protected $goal;
public function __construct(Goal $goal)
{
$this->goal = $goal;
}
/**
* Display the specified resource.
*
* #param int $id
* #return Response
*/
public function show($id)
{
$thisgoal = $this->goal->find($id);
foreach ($this->goal->with('distanceGoalDesc')->get() as $distancegoaldesc) {
dd($distancegoaldesc->DistanceGoalDesc);
}
}
}
when I pass through goal 1 which has a distance goal the above method dies and dumps the Goal object with the details of goal 1 and an array of its relations including an object with DistanceGoalDes.
when I pass through goal 2 it passes through exactly the same as if I had passed through goal 1
if I dd() $thisgoal i get the goal that was passed through
what I want ultimately is a method that returns the goal object with its relevant goal description object to the view but this wont even show me the correct goal details not too mind with the correct relations
this function is now doing what I want it to do, I am sure there is a better way (besides the fact that its happening in the controller right now) and I would love to hear it.
public function show($id)
{
$thisgoal = $this->goal->find($id);
if (!$thisgoal->bodyGoalDesc == null) {
$goaldesc = $thisgoal->bodyGoalDesc;
return View::make('goals.show')
->with('goal', $thisgoal)
->with('bodygoaldesc', $goaldesc);
} elseif (!$thisgoal->strengthGoalDesc == null) {
$goaldesc = $thisgoal->strengthGoalDesc;
return View::make('goals.show')
->with('goal', $thisgoal)
->with('strengthgoaldesc', $goaldesc);
} elseif (!$thisgoal->distanceGoalDesc == null) {
$goaldesc = $thisgoal->distanceGoalDesc;
return View::make('goals.show')
->with('goal', $thisgoal)
->with('distancegoaldesc', $goaldesc);
}
}

Categories