Symfony2: Session Global variable in PHP template - php

Symfony doc says:
During each request, Symfony2 will set a global template variable app
in both Twig and PHP template engines by default. The app variable is
a GlobalVariables instance which will give you access to some
application specific variables automatically: app.security - The
security context. app.user - The current user object.
app.request - The request object. app.session - The session
object. app.environment - The current environment (dev, prod,
etc). app.debug - True if in debug mode. False otherwise.
Examples:
In twig: {{ app.request.method }}
In PHP: echo $app->getRequest()->getMethod()
In twig: {{ app.user.username }}
But for the session object:
In twig: {{ app.session.varname }}
In PHP: // I don't know, do you know how to call it?
I've tried: $session = $app->getSession('uid'); but when I try to store it to a database it tells me:
Catchable Fatal Error: Object of class
Symfony\Component\HttpFoundation\Session could not be converted to
string in C:\wamp\www...
There's a lack of resources when it comes to PHP templates, but in my case I can't switch for some reasons.
The question in other words, what is the equivalent in PHP templating of:
{{ app.session.varname }}?

In twig: {{ app.session.varname }}
In PHP: echo $app->getSession()->get('uid');

$session = $this->get('session');
if ($session->has('varname')) {
echo $session->varname
}

have you tried to error_log $app->getSession() to see what it returns?
error_log(var_dump($app->getSession(), true));

Related

Render Symfony 5 service as twig global

I'm using a service as twig global variable. In the service constructor I set a default value of the property $title. It works initially.... Twig render the property value using the command {{ service.getTitle() }} in a template file. But after update the service property by the controllers constructor and rendering the view, the value is not updated at screen. The goal is set a twig global variable by the controllers to render in all views. How to do it?
twig.yaml
twig:
globals:
pageMap: "#Base.PageMap"
services.yaml
services:
Base.PageMap:
class : App\Bundle\Base\Services\PageMap
public: true
controller
public function __construct(PageMap $pageMap)
{
$pageMap->setTitle('Registration listing');
}
twig template:
<div class="title">{{ pageMap.getTitle() }}</div>
Twig globals are setup at init time and compiled/cached for the duration of an execution.
If you want to update and be able to call things dynamically, you should create a RuntimeExtension (see documentation here : https://symfony.com/doc/current/templating/twig_extension.html#creating-lazy-loaded-twig-extensions)
Calling it from your template will be a little more expensive (but more correct !)

Symfony Twig {{render}} handling passed arguments

Over a template I do a render method:
{{ render(controller('AppBundle:Widgets:myCapsWidget'),{'somestring':someString}) }}
Over the controller I have the following method:
public function myCapsWidgetAction($somestring)
{
return new Response(strtoupper($somestring));
}
I also looked over theese links:
symfony twig render controller argument array
https://knpuniversity.com/screencast/symfony2-ep3/render-controller
But still cannot find any light to my path.
If I read the first link you gave us, you should use:
{{ render(controller('AppBundle:Widgets:myCapsWidget',{'somestring':someString})) }}

No authentication token when another controller action is rendered in the template

I have a template which contains {{ render(controller(...) }} code. It works fine until I try to process 404 error. I'm getting The security context contains no authentication token trying to invoke controller action even though the result it returns contains single line of text and doesn't use session or anything.
Check if you rendered template (not only the subrequest, but the container and additional includes aswell) contains any references to {{ app.user }}. Quoting from the official documentation:
You must not use is_granted in your error pages (or layout used by
your error pages), because the router runs before the firewall. If the
router throws an exception (for instance, when the route does not
match), then using is_granted will throw a further exception. You can
use is_granted safely by saying {% if app.user and is_granted('...')
%}.
http://symfony.com/doc/current/cookbook/controller/error_pages.html

how to access base url in twig from symfony 2 console?

I am porting my website which is in Kohana to Symfony 2 gradually. Right now I am writing backend command in Symfony2, e.g. cron to send email notifications.
How can I access base url in twig. Can I do some configuration so that accessing urls in twig from console and from http request to be same ?
I have already reffered to this,
http://symfony.com/doc/current/cookbook/console/sending_emails.html
http://symfony.com/doc/current/cookbook/templating/global_variables.html
here, it is given how to configure it, but it is not mentioned how to access it, I assume I have to use {{ router.request_context.host }}.
But my question is, isn't there any way to be consistent between console and HTTP ?
e.g. {{ url }} ?
Add following setting in parameters.yml,
router.request_context.scheme: http
router.request_context.host: domain.com
base_url: '%router.request_context.scheme%://%router.request_context.host%/'
and inside console command controller you can access like,
$host = $this->getContainer()->get('router')->getContext()->getHost();
$scheme = $this->getContainer()->get('router')->getContext()->getScheme();
$baseURL = $this->getContainer()->getParameter('base_url');
First, you must set the url (you're calling it base_url) in a route by adding the following lines to /app/config/routing.yml:
base_url:
pattern: /
After that, you must set the router.request_context parameters as mentioned in the Symfony cookbook.
Now that everything's setup, you can simply use the same url functions in Twig as you would do in your webpages:
{{ url('base_url') }}
This worked for me.
In config.yml:
twig:
globals:
base_url: "http://www.example.com/"
In twig template:
{{ base_url }}

Twig - assume variables as object methods

This is a strange one. I'm trying to implement a 1:1 relationship between Twig and some ViewModel objects, such that Twig is aware of its context and assumes variables are methods on the object.
For example, I have a Twig template and a ViewModel_Product. I could do this...
$template->render(array('product', $product));
...and in the template...
<p>{{ product.name }}</p>
However, because the only thing that will ever be passed to the template is the model, it seems pointless to have users prefix each variable. Better usage would be:
$template->render(array('viewModel', $product));
...and...
<p>{{ name }}</p>
How can I achieve this?
I don't believe this would be possible because twig keeps track of other global variables in each template so how would it know if the variable {{ name }} is part of your view or some other global variable? And as it was mentioned above, having the variable prefix helps to namespace your view which makes for easier reading.
Don't be a lazy coder.

Categories