Symfony - render view by defined status - php

I defined status field in my db table like
$newPlay->setStatus(Plays::STATUS_PUBLISHED);
that is now saved in that db table.
I need to render a view with fields that have that status.
I made an api call for that but I keep getting an error
Controller "AppBundle\Website\Controller\PublishedTicketsController::publishedTicketsAction()" requires that you provide a value for the "$status" argument. Either the argument is nullable and no null value has been provided, no default value has been provided or because there is a non optional argument after this one.
This is my api call..
/**
* #Route("/published-tickets", name="published_tickets")
* #param Request $request
* #return \Symfony\Component\HttpFoundation\Response
* #throws \Exception
*/
public function publishedTicketsAction(Request $request, $status)
{
$query = $this->getDoctrine()
->getRepository('AppBundle:Plays')->findBy(['status' => $status]);
return $this->render('#FrontTemplates/pages/published-tickets.html.twig', array(
'query' => $query,
'status' => $status
));
}

I have done it like this..
In my service..
public function publishedTicket()
{
$query = $this->getPlaysRepository()
->createQueryBuilder('t')
->select('t')
->where('t.status =:status')
->setParameter('status', Plays::STATUS_PUBLISHED)
->getQuery()
->getResult();
return $query;
}
and in my controller
$playPublish = $this->container->get('publish.tickets')->publishedTicket();
return $this->render('#FrontTemplates/pages/published-tickets.html.twig', array(
'playPublish' => $playPublish
));
this is the part I could't figure out..
->setParameter('status', Plays::STATUS_PUBLISHED)

Related

Symfony RedirectToRoute with array paramater

I'm working on an upload system based on Symfony 4 and PHPSpreadsheet.
My user uploads the excel file. I then create the products/categories... At the end I want to get all categories created. The following Doctrine query :
/**
* #param $user_id
* #return array
* #throws \Doctrine\ORM\NonUniqueResultException
*/
public function checkIfNew($user_id): ?array {
return $this->createQueryBuilder('c')
->andWhere('c.categorie_parent_id is NULL')
->andWhere('c.created_by = :val')
->setParameter('val', $user_id)
->getQuery()
->getResult()
;
}
gets all my categories where created_by is by the user ID, and where Parent is null.
What I want to do is to get an array of all those categories and then redirect the user to a rendered Twig template page where he can make the link.
But I don't really understand how to use the parameters...
In my Upload I've set this :
$isNew = $this->getDoctrine()
->getRepository(Categorie::class)
->checkIfNew($this->getUser()->getId());
if (!is_null($isNew)){
$this->addFlash('success', 'Catalogue crée avec succès');
return $this->redirectToRoute('admin.categorie.link', $this->getUser()->getId());
}
I don't understand how I can use the request to redirect the user correctly using the route :
/**
* #Route("/admin/categories/import", name="admin.categorie.link", methods={"GET|POST"})
* #param Categorie $categories
*/
public function linkImport()
{
// What TODO here ?
return $this->render('admin/categories/link.html.twig', compact('categories'));
}
Well I suppose I have to add $isNew as a parameter for my request ? But did I reuse the array after to use this in my twig, and display the element from this array inside my twig.
There is a small error:
If your route is "/admin/categories/import" and you want to transfer a value like "$this->getUser()->getId()" then this should be like
Route "/admin/categories/import/{userId}" and your return would be:
return $this->redirectToRoute('admin.categorie.link', ['userId' => $this->getUser()->getId()]);
and your controller could take the userId as var:
/**
* #Route("/admin/categories/import/{userId}", name="admin.categorie.link", methods={"GET|POST"})
*/
public function linkImport(int $userId, EntityManagerInterface $em) // var name must be the same as in the route
{
// What TODO here ?
$categories = $em->getRepository(Categories::class)->findByUserId($userId);
return $this->render('admin/categories/link.html.twig', ['categories' => $categories]);
}
Now you can access your categories in twig with {{categories}}

return object's properties from related data in symfony json result

I am attempting to return a list of comments related to a an entity. The query results on when it runs and returns, the related field does not provide a meaningful result.
Here is the comment entity declarations
/**
* #var Books
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Books")
*/
private $imagefk;
/**
* #var User
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Users")
*/
private $userfk;
This is my controller snippets of codes that fetches all the comment a user commented to a particular book
private function serializeComments(Comments $cmt) {
return array(
'message' => $cmt->getMessage(),
'userid' => $cmt->getUserfk(),
'bookid' => $cmt->getBookfk(),
);
}
the below function calls the function above
public function getAllCommentsAction($books)
{
$messages = $em->getRepository("AppBundle")->findBy(
array(
"imagefk" => $books
)
);
$data = array();
foreach ($messages as $message)
{
array_push($data, $this->serializeComments($message));
}
$response = new Response(json_encode($data), 200);
$response->headers->set('Content-Type', 'application/json');
return $response;
}
Here is the result of attempt
[{"message":"This is comment for a user one","userid":{"__initializer__":{},"__cloner__":{},"__isInitialized__":false},"bookid":{"path":"http:\/\/10.0.2.2:88\/xxx\/web\/uploads\/pdf\/5ub3uy8zv09cee2avi11.pdf"}}
Please how can I return the objects properties from this result instead of this
"userid":{"__initializer__":{},"__cloner__":{},"__isInitialized__":false},"bookid":{"path":"http:\/\/10.0.2.2:88\/xxx\/web\/uploads\/pdf\/5ub3uy8zv09cee2avi11.pdf"
Try accessing the object properties:
'userid' => $cmt->getUserfk()->getId(),
instead of
'userid' => $cmt->getUserfk(),
Hope this help

Symfony submit a search form with categories and region

I got a search form in page's header that must to submit to my SearchController and be handeld by searchAction in case of the user input only the query string.
This form got the ability to search in selected category and country region.
So the user can make the search in all category and all region or select category and all region or select category and region
How I can handle this? I've made the controller action that actually work when i put the data in url.
Here is my search class using QueryBuilder:
class SearchController extends Controller
{
/**
* #Route("cerca/{query}", name="search")
*/
public function searchAction(Request $request,$query)
{
$results = $this->getDoctrine()
->getRepository('AppBundle:Ads')
->createQueryBuilder('p')
->where("p.name LIKE '%$query%'")
->getQuery()
->getResult(\Doctrine\ORM\Query::HYDRATE_ARRAY);
return $this->render('search\search.html.twig', [
//'pagination'=>$pagination,
'query' => $query,
'region' => 'Italia',
'results' => $results,
]);
}
/**
* #Route("cerca/{region}/{query}", name="search_regioni")
*/
public function searchRegionAction($region,$query)
{
$results = $this->getDoctrine()
->getRepository('AppBundle:Ads')
->createQueryBuilder('p')
->where("p.name LIKE '%$query%'")
->andWhere("p.region Like '%$region%'")
->getQuery()
->getResult(\Doctrine\ORM\Query::HYDRATE_ARRAY);
$region = ucfirst($region);
return $this->render('search/search.html.twig', [
'region' => $region,
'query' => $query,
]);
}
/**
* #Route("cerca/{category}/{query}", name="search_categorie")
*/
public function searchCategoryAction($category,$query)
{
$results = $this->getDoctrine()
->getRepository('AppBundle:Ads')
->createQueryBuilder('p')
->where("p.name LIKE '%$query%'")
->andWhere("p.region Like '%$region%'")
->getQuery()
->getResult(\Doctrine\ORM\Query::HYDRATE_ARRAY);
$category = ucfirst($category);
return $this->render('search/search.html.twig', [
'region' => 'Italia',
'category' => $category,
'query' => $query,
]);
}
/**
* #Route("cerca/{category}/{region}/{query}", name="search_categorie_regioni")
*/
public function searchCategoryRegionAction($category,$region,$query)
{
$results = $this->getDoctrine()
->getRepository('AppBundle:Ads')
->createQueryBuilder('p')
->where("p.name LIKE '%$query%'")
->andWhere("p.region LIKE '%$region%'")
->andWhere("p.category LIKE '%$category%'")
->getQuery()
->getResult(\Doctrine\ORM\Query::HYDRATE_ARRAY);
$category = ucfirst($category);
$region = ucfirst($region);
return $this->render('search/search.html.twig', [
'region' => $region,
'category' => $category,
'query' => $query,
]);
}
}
How I can make the form submit to this controller? How to handle the different cases?
I think my logic is wrong too, symfony don't know if I search for a category or country region, how can I improve this?
I think instead of having different actions you should submit the data and store it in a ValueObject, e.g. a Search object:
class Search {
public $query;
public $category;
public $region;
}
You could also create a SearchType that binds a form to the value object and provides some validation and constraints, e.g. create a ChoiceLoader that loads the available categories from a database and checks that the selected one is valid. After submitting and validating the form input you retrieve the search object from the form and use it to build your Doctrine-Query. In case region is empty, e.g. not selected you just omit it from the query like this:
/** #var Search $search **/
$search = $form->getData();
$queryBuilder = $this->getDoctrine()
->getRepository('AppBundle:Ads')
->createQueryBuilder('p')
$queryBuilder->where($queryBuilder->expr()->like('p.name', "%{$search->query}%");
if (null != $search->region) {
$queryBuilder->andWhere('region = :region')
->setParameter('region', $search->region);
}
$results = $queryBuilder->createQuery()->getResults();
Some things to note:
Do not just inject the variables into the where-clauses. This is a security problem. You should use parameters and the expression builder to safeguard against SQL injection.
You can chain clauses in the query builder (like you do above) or split them up, like I do in the if condition.
Since the form is already connected to the Search-object the fields should be pre-filled with the last inserted values, so you don't have to pass around the input separately.
I'm not 100% sure the LIKE-expression will work as expected. It can be somewhat tricky. You should search for how to use it properly.

Laravel 5: Odd "Undefined Variable" error when returning a defined array to View

As the title states, I'm getting an odd error in Laravel 5. I'm new to Laravel, and this week I dived into Jobs/Queues. I've gotten an "Undefined Variable: $errors" error in the past, and that one I was able to understand and fix. But now, I can't seem to get past this one. To my knowledge, everything looks fine. The following breakdown will (hopefully) give you an idea of what I'm doing/where the error happens:
class PostFormFields extends Job implements SelfHandling
{
use InteractsWithQueue, SerializesModels;
/**
* The id (if any) of the Post row
*/
protected $id;
/**
* List of fields and default value for each field
*/
protected $fieldList = [
'title' => '',
'subtitle' => '',
'page_image' => '',
'content' => '',
'meta_description' => '',
'is_draft' => '8',
'publish_date' => '',
'publish_time' => '',
'layout' => 'blog.layouts.post',
'tags' => [],
];
/**
* Create a new job instance.
*
* #return void
*/
public function __construct($id = null)
{
$this->id = $id;
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
$fields = $this->fieldList;
if($this->id)
{
$fields = $this->fieldsFromModel($this->id, $fields);
} else {
$when = Carbon::now()->addHour();
$fields['publish_date'] = $when->format('M-j-Y');
$fields['publish_time'] = $when->format('g:i A');
}
/**
* Populate with old values, if they exist
* #var [type]
*/
foreach ($fields as $fieldName => $fieldValue)
{
$fields[$fieldName] = old($fieldName, $fieldValue);
}
$fields = array_merge($fields, ['allTags' => Tag::lists('tag')->all()]);
return $fields;
}
Above is the code inside the handler function of my Job class, the file it sits in is called PostFormFields.php. It's job, essentially, is just to return an array filled with all the values pertaining to a post, based on the Post Model and what's in the database that pertains to that specific Post ('title','content',etc) if a user's entered them in the past
public function create()
{
$data = $this->dispatch(new PostFormFields());
$data['title'] = 'testing';
var_dump($data);
return view('admin.post.create', $data);
}
Above is the code inside my PostController class, in the create() method. As you can tell, I'm using a resource controller for my Post Controller. It dispatches the PostFormFields Job and stores all the returned data in an array $data. However, since the create() method will be used to create a new post, only the keys should be returned, with values set to their default value ''.
This works. As you can see, i run a 'var_dump()' on the variable $data to see what, if anything, is returned. I then pass the $data array to the create View. This is where the error comes up.
Laravel "Undefined Varieble" Error
Above is a picture of the error I get when I try to access the /create route. It's clear that the $data does have the $title variable defined, as well as all the other keys in the array. Why am I getting an "Undefined Variable" array when I clearly have it defined by the time it's sent to the create View?
The line of code is says the error is in is the following:
<input type="text" class="radius" name="title" id="title" value="{{ $title }}">
You have to pass that array to view via compact function of laravel. So that you can use it in view as you want.
Please check about compact here - https://laracasts.com/discuss/channels/general-discussion/phps-compact-pros-and-cons?page=1
public function create()
{
$data = $this->dispatch(new PostFormFields());
$data['title'] = 'testing';
var_dump($data);
return view('admin.post.create', compact('data'));
}

Symfomy2 manual route definitions with FOSRestBundle

I am now using the FOSRestBundle in order to build a REST API within my Symfony application. The idea for now is to list some locations(hotels, restaurants...), I managed to configure the automatic routes with FOSRestBundle like:
/api/locations , /api/locations/{id} , /api/locations/{name}/detail
with this controller:
class LocationController extends FOSRestController implements ClassResourceInterface
{
/**
* GET /locations
*
* #return Array
*
*/
public function cgetAction()
{
$locations = $this->getDoctrine()
->getManager()
->getRepository('VisitBILocationsBundle:Location')
->findAll();
if (!$locations) {
return array(
'locations' => $locations,
'status' => 1
);
}
return array(
'locations' => $locations,
'status' => 0
);
}
/**
* GET /locations/{locationId}
*
* #return Array
*
*/
public function getAction($id)
{
$location = $this->getDoctrine()
->getManager()
->getRepository('VisitBILocationsBundle:Location')
->findBy(array('id' => $id));
if (!$location) {
return array(
'location' => $location,
'status' => 1
);
}
return array(
'location' => $location,
'status' => 0
);
}
/**
* GET /locations/{name}/detail
*
* #return Array
*/
public function getDetailAction($name)
{
$detail = $this->getDoctrine()
->getManager()
->getRepository('VisitBILocationsBundle:LocationDetail')
->findBy(array('name' => $name));
if (!$detail) {
return array(
'locationDetail' => $detail,
'status' => 1
);
}
return array(
'locationDetail' => $detail,
'status' => 0
);
}
}
I've been struggling with this, but would anyone know how should I proceed to generate one custom url like this:
/api/locations/nearby/{latitude}/{longitude}
The idea is that I would provide my own latitude and longitude, and the backend will calculate and provide the locations which are the closest to me.
Of course I've looked at the documentation of FOSRestBundle for manual route configuration, but since I spent some time trying to do it, I come here to ask for some help :)
If you want to manually define a route, it should just be as simple as adding the route to the existing routing configuration. How exactly you do it depends on how you're handling the routing configuration: annotation, yaml, or xml.
Option 1: YAML
In the routing.yml file (ex: src/Vendor/MyBundle/Resources/config/routing.yml) add something like:
location_nearby:
pattern: /api/locations/nearby/{latitude}/{longitude}
defaults: { _controller: "MyBundle:Location:nearby" }
requirements:
_method: GET
which would correspond to this method in LocationController:
public function nearbyAction($latitude, $longitude) { ... }
Option 2: Annotations
Add this use statement to the Controller file:
use FOS\RestBundle\Controller\Annotations\Get;
and then define the route above the controller method:
/**
* Return a nearby location
* #Get("/api/locations/nearby/{latitude}/{longitude}")
*/
public function nearbyAction($latitude, $longitude) { ... }
OK here is how to proceed, works fine for me:
I use the annotation system to route /locations/nearby/{latitude}/{longitude}
/**
* Return a nearby location
* #Get("/locations/nearby/{latitude}/{longitude}", requirements={"latitude" = "[-+]?(\d*[.])?\d+", "longitude" = "[-+]?(\d*[.])?\d+"})
*/
public function nearbyAction($latitude, $longitude) {...}
Then I have to specify float numbers with: requirements={"latitude" = "[-+]?(\d*[.])?\d+", "longitude" = "[-+]?(\d*[.])?\d+"}
Those will still be interpreted as string by the controller: "64.1333", I just have to use this in the controller:
floatval($latitude)
to get url parameters as float and then do my calculations!

Categories