Symfony2: in Twig, pass Request with Render function - symfony

I understand that using {% render() %} automatically forces a new request object to be sent, but im curious if theres a way to pass in the originating request as an argument?
{% render('some_action', {'originalRequest': app.request}) %}
This doesn't seem to do anything for the controller:
public function actionAction($originalRequest = null)
{
// $originalRequest ends up just being null
}
Im assuming its because of the way the route is setup:
some_action:
pattern: /stuff/
defaults: { _controller:SomeApp:Controller:action }
I'd imagine data like that cant obviously be apart of the URL, so some type of way to pass in data to a renderable URL, anything at all?
EDIT (Solution)
The solution was pretty simple in the long run, as Petre Pătraşc below has demonstrated, that in Twig, all I needed to do was invoke the Controller directly, and with that approach I can pass in Objects (Such as a Request object) and Arrays, instead of text values in a URL.
To perform roughly the same idea in a controller, utilizing the forward() method from the router, will allow similar effects without needing to redirect the user to another page.

If I understand correctly, you're looking for this:
{% render "MyBundle:Controller:someAction" with { 'originalRequest' : app.request } %}

use the render function as a result
{{ render(controller('MyBundle:ControllerName:example', {'originalRequest': app.request})) }}
and then in your controller
public function exampleAction(Request $originalRequest)
{
// do something
}

Since Symfony 2.4 you can access the original request via the request_stack. This avoids the need to create a new method parameter.
function exampleAction() {
$request = $this->get('request_stack')->getMasterRequest();
//do something
}
Use this carefully as it makes your sub-requests incompatible with ESIs/reverse proxies (where a sub-request is also a master request) http://symfony.com/blog/new-in-symfony-2-4-the-request-stack

Related

Symfony, redirectToRoute() with data

When I render a twig I can do this:
return $this->render('mytwig.html.twig',array("message"=>"Hey"));
I'm passing an array with some data that I will use in the twig.
But, I will not render now, I need to use:
return $this->redirectToRoute('my_route');
How can I pass to that route some data? but I don't want to pass an argument with: redirectToRoute('my_route', array("some"=>"Hey")); because that's for the URL, I need to use the data in the Twig.
Using your method redirectToRoute('my_route', array("some"=>"Hey")); In the controller (or route) you pass the information to, you can use:
$some = $request->query->get('some');
And then use that variable again when you render render the template like so:
return $this->render('mytwig.html.twig',array("some"=> $some ));
And then in your twig use:
{{some}}

How to pass query string with routes in laravel 5.4

I am using Laravel 5.4. I want to use query string like below:
tempsite.com/lessons?id=23
For getting this how routes are to be modified. It is possible to give route in the following way.
Route::get('lessons/id={id}', ['as' => 'lessons.index', 'uses' => 'Lessons\LessonController#index']);
But adding '?' is not getting for me. Please help us to provide a solution as early as possible.
If you are using resourceful controllers, your routes are all handled for you so you would simply put
Route::resource('lessons', 'Lessons\LessonController');
You can then use route model binding to bind the model instance which matches that particular ID.
Route::model('lesson', Lesson::class);
This would be done in your RouteServiceProvider.
I would also suggest having a good read of the following documentation on the laravel website https://laravel.com/docs/5.4/routing. It provides really good insight in to how routes work and how they should be structured.
Instead of tempsite.com/lessons?id=23
Pass it like this tempsite.com/lessons/23
and in the route
Route::get('lessons/{id}', ['as' => 'lessons.index', 'uses' => 'Lessons\LessonController#index']);
to get the id in your controller, write your function like this
public function index($id)
{
//do anything with $id from here
}
There is no need to define query string parameters in your routes. You can return query string parameters in your controller like so:
URL example: tempsite.com/lessons?id=23
public function lessons(Request $request)
{
$request->get('id'); // Using injection
Request::get('id'); // Using the request facade
request()->get('id'); // Using the helper function
}
You could even validate the parameter:
public function lessons(Request $request)
{
$this->validate($request, ['id' => 'required|integer']);
}
Note: If you want to make the URL not accessible if the ID is omitted, see #DarkseidNG answer.
I was able to inform laravel to accept query stringed requests on my route by affixing the url with a forward slash, like so
// web.php
Route::get('/path/', "Controller#action");
With the above, mysite/path?foo=bar&name=john does not throw 404 errors.

How To Call a Common function to Every (Twig) Symfony2

Hi I have a common function to get a Client Name dynamicaly. Now I want to call that function to every view (Twig). I am following it like this:
//My controler
public function getSchoolNameAction(){
$session = new Session();
$dm = $this->getDocumentManager();
$commonFunction = new CommonFunctions();
return $schoolName= $commonFunction->schoolName($dm,$session);
}
//My View (search.html.twig)
{% render controller('EduAccountBundle:Ledger:getSchoolName') %}
But its showing an error that :
he controller must return a response (null given). I need to make it for every view. Please guide me how to fix this
Don't define a controller as a service, controllers should be used only to take a request and to produce a response (you're just returning a value, that isn't acceptable for Symfony logic)
Unless you want to return a rendered template (or produce a valid response, such like a json response) to put where you're calling the common action (you could do that of course), I will recommend to write a custom twig extension

How to fetch value from url in silverstripe

I want to print value 5 on the ss page.
www.xyz.com?a=5.
How to fetch url data in silverstripe? Any help is accepeted.
In your controller that your Silverstripe template is for, you can retrieve "GET" (aka. query string) by returning the result of $this->getRequest()->getVar('a') in a function on your controller.
It is good practice to use $this->getRequest()->getVar('a') over $_GET['a'] as SilverStripe will automatically sanitise the string.
When your code is not in the controller (so you can't make use of $this->getRequest()), you can request the current controller by using Controller::curr() which will make the complete call for getting a single var:
Controller::curr()->getRequest()->getVar('a')
If you want to get all "GET" variables, just call getVars() instead..
Also, you can access "POST" variables in a similar calling postVar('a') or postVars() instead. If you want to get the value from both "POST" or "GET", you can call requestVar('a') or requestVars().
Anyway, here is a basic mock-up of a controller using a function on the controller that is accessible in the template.
Controller
class TestPage_Controller extends Page_Controller
{
public function init()
{
parent::init();
}
public function MySpecialProperty()
{
return $this->getRequest()->getVar('a');
}
}
Template
<p> $MySpecialProperty </p>

symfony2 routing requirements combining 2 parameters

So I got this in my routing.yml:
requirements:
var1: \d+
var2: \d+
Both are checked on their own and valid.
I need to check the combination of the 2, since the combination is not always valid.
For this case I need to check the relation between 2 objects in the database, the first should be the parent of the second.
I can do this in the controller, but I don't really like that implementation. Also, I need this same check for more than 1 route.
How would I add another requirement that checks the combination? Can I define a method in the controller class that would be called?
Or would the best solution be something like:
public function indexAction($var1, $var2)
{
$result = $this->checkRelation($var1, $var2);
if ($result) {
// return errorpage
return $result;
}
// ...
}
So as I understand your question, you want the following:
/parent/child/ --> returns 200
/not_parent/not_child --> returns 404
The Symfony2 Routing component doesn't do this natively, but you could extend it.
http://symfony.com/doc/master/cmf/cookbook/using-a-custom-route-repository.html
The final solution I went with was the following:
add a method checkRelation that requires all parameters
run a query inside that method to check if everything is ok.
return false when there is a problem, return true when values are ok. (alternatively you can return an object or something)
in the action I check if the value is false, if so I return a generic "not found" page for the specific controller.
In all this is very similar to what I posted in my initial question.
When using the same checkRelation in multiple controllers it might be a good idea to move it (partially) to a repository-class or something similar to prevent duplication of code/logic.

Resources