How to recover data from database using symfony2 - symfony

i need to display information of a product from my database but i have an
error: Controller
"UserBundle\Controller\DefaultController::profileAction()" requires
that you provide a value for the "$id" argument (because there is no
default value or because there is a non optional argument after this
one).
This is the profileAction:
public function profileAction($id)
{
$product = $this->getDoctrine()
->getRepository('UserBundle:Product')
->find($id);
if (!$product) {
throw $this->createNotFoundException(
'No product found for id '.$id
);
}
return $this->render('UserBundle:Default:profile.html.twig', array('product' =>$product));
}
please someone help me.

You need to provide $id as argument.
Change the return to something like that:
return $this->render('UserBundle:Default:profile.html.twig', ['product' => $product, 'id' => $id]);

You need a route like that :
_my_route:
path: /my_path/{id}
defaults: {controller: AcmeBundle:Default:profile}
requirements:
id: \d+
Action in your controller :
public function profileAction($id)
{
$product = $this->getDoctrine()
->getRepository('UserBundle:Product')
->find($id);
if (!$product) {
throw $this->createNotFoundException(
'No product found for id '.$id
);
}
return $this->render('UserBundle:Default:profile.html.twig', array('product' =>$product));
And a link or something else in your view like that (Hope you use Twig):
Lorem ipsum
It should be work.
EDIT :
For you search feature, i will do a route like that
_profile:
path: /profile
defaults: {_controller:AcmeBundle:Default:profile}
Controller :
public function profileAction(Request $request){
$form = $this->createForm(new SearchType());
$products = null ;
if($request->isMethod('POST')){
$form->handleRequest($request);
$value = ($form['search']->getData());// change de 'search' according to your form
$em = $this->getDoctrine()->getManager() ;
$product = $em->getRepository('UserBundle:Product')->find($value) ;
}
if(!$product) throw $this->createNotFoundException('your message');
return $this->render('UserBundle:Default:profile.html.twig',array(
'product' => $product
));
}
And finally, your form in the view :
<form method="POST" action="{{ path('_profile') }}">
//your code
</form>

Well i think that here $id become null and it causes error because $id is used to fetch data from your db, so set default value for $id check $id will never become null or empty. All the best.

Related

In Symfony how do I redirect to route with datas from search form ? Error : Variable does not exist

I made a search form in order to get events list. This form is displayed in front/search.html.twig. When I submit the search form, I'd like it leads me to front/events.html.twig.
When I submitted it, it says "category" doesn't exist. I don't have this problem when I replaced
return $this->redirectToRoute('events', $data);
with
return $this->render('front/events.html.twig', $data);
but I wish to use to route "events"...
This is my EventsController.php file :
<?php
namespace App\Controller\Front;
use App\Form\SearchType;
use App\Repository\EventsRepository;
use App\Repository\CategoriesRepository;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class EventsController extends AbstractController
{
#[Route('/search', name: 'search')]
public function search(Request $request, SessionInterface $sessionInterface)
{
$data = $request->request->all();
$sessionSearchFormData = $sessionInterface->get('searchFormData');
$form = $this->createForm(SearchType::class, ['data' => $sessionSearchFormData]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
$sessionInterface->set('searchFormData', $data);
return $this->redirectToRoute('events', $data);
}
return $this->renderForm('front/search.html.twig', [
'form' => $form
]);
}
#[Route('/events', name: 'events')]
public function events(
EventsRepository $eventsRepository,
CategoriesRepository $categoriesRepository
){
$events = $eventsRepository->findAll();
$categories = $categoriesRepository->findAll();
return $this->render("front/events.html.twig", ['events' => $events, 'categories' => $categories]);
}
}
Bonjour Emilie,
Your route events does not have parameters. So you can't redirect it using parameters.
you can try something like this :
public function index($name)
{
return $this->redirectToRoute('events', ['max' => 10]);
}
You can forward to another Controller :
public function index($name)
{
$response = $this->forward('App\Controller\OtherController::fancy', [
'name' => $name,
'color' => 'green',
]);
// ... further modify the response or return it directly
return $response;
}
Regards,
hous has found the solution :
The second parameter must be an array :
return $this->redirectToRoute('events', [$data]);

Symfony 5 - Display id and slug in category url and find it by id when slug is updated

My category url contains both id and slug like https://myapp.com/category/56-category-name (id field = 56 and slug field = category-name in the DB), when updating category name the slug field in DB is updated but the id still the same.
I would like to display my category whatever the slug provided that the id is correct and of course display the correct url. In this case SEO still correct i think.
Here my show method :
/**
* #Route("/category/{id}-{slug}", name="category_show", requirements={"id"="\d+"})
*/
public function show(CategoryRepository $categoryRepository, $slug, $id): Response
{
$category = $categoryRepository->find($id);
if($category->getSlug() !== $slug) {
return $this->redirectToRoute('category_show', [
'id' => $id,
'slug' => $category->getSlug()
]);
}
return $this->render('category/show.html.twig', [
'category' => $category
]);
}
It works if the given id exists in DB, othewise i got an error Call to a member function getSlug() on null. I can throw a NotFoundException, but i think this method use many times queries.
So please help me doing these properly with more flexibility and performance.
In case I would like to display the category in the post url as well like https://myapp.com/56-category-name/23-post-title how to go about it ??
Thanks in advance
Use findOneBy() and check if the result is null
/**
* #Route("/category/{id}-{slug}", name="category_show", requirements={"id"="\d+"})
* #Route("/{id}-{slug}/{idArticle}-{postSlug}", name="article_show", requirements={"idArticle"="\d+"})
*/
public function show(CategoryRepository $categoryRepository, $slug, $id, $idArticle = false, $postSlug = false ): Response
{
$category = $categoryRepository->findOneBy(['id'=>$id]);
if(is_null($category)){
throw new NotFoundHttpException(); //404, nothing found
}else{
//Category found.
if($idArticle){ // https://myapp.com/56-category-name/23-post-title
//Article route, put your logic here
}else{ //https://myapp.com/category/56-category-name
// Category route, logic here
if($category->getSlug() !== $slug) {
return $this->redirectToRoute('category_show', [
'id' => $id,
'slug' => $category->getSlug()
]);
}
return $this->render('category/show.html.twig', [
'category' => $category
]);
}
}
}
here is what i found good for my app :
in my CategoryController.php i create, the show method :
/**
* #Route("/{id}-{slug}", name="category_show", requirements={"id"="\d+"})
*/
public function show(CategoryRepository $categoryRepository, $slug = null, $id): Response
{
$category = $categoryRepository->find($id);
if (!$category) {
throw new NotFoundHttpException();
}
if($category->getSlug() !== $slug) {
return $this->redirectToRoute('category_show', [
'id' => $id,
'slug' => $category->getSlug()
]);
}
return $this->render('category/show.html.twig', [
'category' => $category
]);
}
in my index template to display the category_show link :
show
in my ArticleController.php i create, the show method :
/**
* #Route("/{category}/{id}-{slug}", name="article_show", requirements={"id"="\d+"})
*/
public function show(ArticleRepository $articleRepository, $slug = null, $id, $category = null): Response
{
$article = $articleRepository->find($id);
if (!$article) {
throw new NotFoundHttpException();
}
$cat = $article->getCategory()->getId() . '-' . $article->getCategory()->getSlug();
if($article->getSlug() !== $slug || $cat !== $category) {
return $this->redirectToRoute('article_show', [
'id' => $id,
'slug' => $article->getSlug(),
'category' => $cat
]);
}
return $this->render('article/show.html.twig', [
'article' => $article,
]);
}
in my index template to display the article_show link :
show
For me that solves my problem. But still, if we can improve the process, I'm a buyer.
Thanks

Why my action is not loaded when I click on a button?

I wanted to create a button that delete a pupil. But I have a problem, my button doesn't launch the deleteAction in my controller.
My controller :
public function deleteAction(Eleve $id, $schoolId)
{
$repository = $this->getDoctrine()->getManager()->getRepository('WCSCantineBundle:Lunch');
$pupil = $repository->findOneBy(array(
'eleve' => $id
));
$em = $this->getDoctrine()->getManager();
$em->remove($pupil);
$em->flush();
return $this->redirect($this->generateUrl('wcs_cantine_todayList', array('schoolId' => $schoolId)));
}
My route :
delete_pupil:
path: /
defaults: { _controller: "WCSCantineBundle:CanteenManager:delete" }
My button (in my view) :
Désinscrire
Thank you for your help.
public function deleteAction(Eleve $id, $schoolId)
{
$em = $this->getDoctrine()->getManager();
$pupil = $em->getRepository('WCSCantineBundle:Lunch')->findOneBy(array('eleve' => $id));
$em->remove($pupil);
$em->flush();
return $this->redirect($this->generateUrl('wcs_cantine_todayList', array('schoolId' => $schoolId)));
}
your code fails because the doctrine entity manager has no clue about what $pupil is since there is two different instances of entity managers, the above code is short hand for removing pupil, but you can change it as needed as long as the entity manager 'knows' about the entity
I did it and it works.
My controller :
public function deleteAction($id, $schoolId)
{
$dateNow = new \DateTime();
$em = $this->getDoctrine()->getManager();
$lunches = $em->getRepository('WCSCantineBundle:Lunch')->findBy(array(
'eleve' => $id,
'date' => $dateNow
));
foreach ($lunches as $lunch) {
$em->remove($lunch);
}
$em->flush();
return $this->redirect($this->generateUrl('wcs_cantine_todayList', array('schoolId' => $schoolId)));
}
My route :
delete_pupil:
path: /todayList/{schoolId}/{id}
defaults: { _controller: "WCSCantineBundle:CanteenManager:delete" }
methods: [GET, DELETE]
And my view :
Désinscrire
I missed to pass my arguments in my route with slashes : /todayList/{schoolId}/{id}
I thank everybody for your help.

Sonata Action with custom form

I have a custom action, based on the editAction from Sonata. Only the form is different.
public function customAction(){
$id = $this->get('request')->get($this->admin->getIdParameter());
$object = $this->admin->getObject($id);
if (!$object) {
throw new NotFoundHttpException(sprintf('unable to find the object with id : %s', $id));
}
if (false === $this->admin->isGranted('EDIT', $object)) {
throw new AccessDeniedException();
}
// On vérifie que l'annonce appartient bien à l'utilisateur connecté
if($this->getUser()->getId() !== $object->getUser()->getId()) {
throw new AccessDeniedException();
}
$em = $this->getDoctrine()->getManager();
$preparechoices = $em->getRepository('AcmeBundle:Entity')->findAll();
foreach($preparechoices as $c){
$choices[$c->getId()] = $c->getLibelle();
}
$form = $this->createFormBuilder(array('choix'=>1))
->add('choix','choice',array('choices'=>$choices))
->add('submit','submit')
->getForm();
$view = $form->createView();
$this->admin->setSubject($object);
$this->get('twig')->getExtension('form')->renderer->setTheme($view, $this->admin->getFormTheme());
return $this->render($this->admin->getTemplate('EDIT'), array(
'action' => 'edit',
'object' => $object,
'form' => $view,
));
}
But I got this error :
Impossible to access a key ("default") on a boolean variable ("")
The error come from this line in the twif file :
{{ form_helper.render_groups(admin, form, admin.formtabs['default'].groups, has_tab) }}
I can't find how to fix it, does anyone know ?
Thanks to Joshua, i was able to fix the error by adding this line:
$this->admin->setFormTabs(array('default'=>array('groups' => array())));
But now, i got a new error :
Impossible to access an attribute ("help") on a null variable
Form form_admin_fields.html.twig, this line, because sonata_admin.field_description is null :
{% if sonata_admin.field_description.help %}
title="{{ sonata_admin.admin.trans(sonata_admin.field_description.help, {}, sonata_admin.field_description.translationDomain)|raw }}"
{% endif %}
I don't know how to fix it, i tried several test, whitout success, in the form definition like :
$form = $this->createFormBuilder(array('choix'=>1))
->add('choix','choice',array('choices'=>$choices,'sonata_admin'=>array('field_description'=>array('help'=>'help_message'))))
->add('submit','submit')
->getForm();

Symfony2 - Can't figure out why my search function is having an error on my show page

I am implementing a simple search function that I've used on other projects without any problems. For some reason it's giving me an error on my showAction - 'Show page' that I can't figure out why.
Impossible to access an attribute ("title") on a NULL variable ("") in AcmeBundle:Blog:show.html.twig at line 9
I've done a dump on my $blog variable in showAction (which gives me the the error above - if I do not comment out the if statement I get the NotFoundException in my showAction(). My search code doesn't even go to any show action or template.
My blog entity is has a ManyToMany relationship to one entity and a ManyToOne on another, not sure if this is messing up my search code?
Question: I'm at a loss to why the search function is going to my showAction and why it's coming up null?
showAction()
/**
* #Route("/{slug}", name="AcmeBundle_show")
* #Method("GET")
* #Template("AcmeBundle:Blog:show.html.twig")
*/
public function showAction($slug)
{
$em = $this->getDoctrine()->getManager();
$blog = $em->getRepository('AcmeBundle:Blog')->findOneBy(array(
'slug' => $slug
));
var_dump($blog);
if (!$blog) {
throw $this->createNotFoundException('Unable to find blog post');
}
return array(
'blog' => $blog,
'slug' => $slug,
);
}
Search code as a service
public function search()
{
$results = null;
$query = $this->request->query->get('q');
if (!empty($query)) {
$em = $this->doctrine->getManager();
$results = $em->createQueryBuilder()
->from('AcmeBundle:Blog', 'b')
->select('b')
->where('b.title LIKE :search')
->addOrderBy('b.created', 'DESC')
->setParameter('search', "%${query}%")
->getQuery()
->getResult();
}
return array(
'query' => $query,
'results' => $results,
);
Controller with searchAction
/**
* #Route("/search", name="AcmeBundle_search")
* #Template("AcmeBundle:Page:search.html.twig")
*/
public function searchAction()
{
$em = $this->getDoctrine()->getManager();
// Search code: calling from the service Search
$query = $this->get('search');
$results = $query->search();
$recentBlogLimit = $this->container->getParameter('acme.latest.blogs_limit');
$latestBlogs = $em->getRepository('AcmeBundle:Blog')
->getBlogs($recentBlogLimit);
$tags = $em->getRepository('AcmeBundle:Tag')
->getTags();
return array(
'query' => $query,
'results' => $results['results'],
'latestBlogs' => $latestBlogs,
'tags' => $tags,
);
}
Search code on twig
<section class="section">
<form action="{{ path('AcmeBundle_search') }}" method="GET">
<label><input type="search" name="q" value={{ app.request.query.get('q') }}></label>
<input type="submit" value="Search">
</form>
</section>

Resources