Symfony Forms manual submission of both GET and POST requests - symfony

Is there any way to get merged data from Request class? Because currently we are submitting forms manually for API controller that accepts both POST and GET queries (this is not an REST API because of legacy project).
$data = array_merge($request->query->all(), $request->request->all());
$form->submit($data);
Is there any way to write something cleaner instead of code below?
$data = array_merge($request->query->all(), $request->request->all());

I think that is not possible. (Maybe I'm wrong)
If you look at the source code of Request, you can see that when Symfony create the request, Symfony put the global variable $_GET in $this->query and $_POST in $this->request.
There is no Symfony variable that takes both.
If you need it in only one place, I think what you have done is fine.
If not, create a service that will or another solution that factors this code.
Another solution is to use the global variable $_REQUEST, because Symfony makes the merge, but it depends on your php configuration (request_order parameter of your php.ini).
But I do not think using Superglobals variables with Symfony is a good idea ... (Besides symfony overwrites them)

Related

Object storage alternatives in Wordpress

so I am developing a Quiz plugin for Wordpress.
I have defined a shortcode which is replaced by my html, and I also have enqueued javascript and styles. So far all good.
At this point, I want to visualize each question using ajax and jquery. My quiz has some sophisticated logic - some quiz question-trees can fall off depending on the answers and on the settings of the plugin.
Thus, I am trying to achieve a solution, where javascript uses ajax call to fetch one next question at a time. On the backend, I created controller-class which is responsible for handling the logic and outputing the fetched-question's html code. Thus, whenever a starts the quiz, the backend will generate some controller object.
My question is, how can i store multiple controller objects persistently? So that i can get the current use's progress.
To do that, i need some kind of persistent storage for all the running quizzes. Here, as far as I understand, i have 2 alternatives: put serialized controller objects into the database, or use some sort of WP_CACHE.
So now I have some questions:
1) Is there any other alternative for storing a set of objects in Wordpress?
2) Is the approach I am using for the quiz implementation - okay? Like maybe I am doing something unconventional?
3) Is having ajax calls communicating to the DB a good idea?
* Edit *
Thanks to #cabrerahector, who pointed out the set_transient() wordpress API.
I was able to store an object in the db with the following code:
...
$base64_serial = base64_encode(serialize($report_controller));
set_transient($report_id, $base64_serial, 60*60*12);
...
and then retreive the object with the following code:
...
$report_controller = unserialize(base64_decode( get_transient( $_GET['report_id'] )));
...
I know it's kind of hacky, but does anybody know a better way? Please don't tell me to create an array with all fields of the class...

How to test internal controllers without route in Symfony 2

I am trying to reduce redundant code by refactoring template and controller code into reusable components, which I then use via the render(controller('AppBundle:Foo/Bar:baz')) construct inside my other templates.
Of course I would like to test these components. In the examples regarding functional testing, however, an actual route is required to make fake test requests. But my BarController here is purely internal and has no routes attached to it. How can I test this controller?
Creating dummy routes is not always possible, because some of the arguments are model objects that cannot be passed via URL. Am I approaching this the wrong way?
The service approach sounds nice, but I am simply doing this now:
self::$kernel->getContainer()->get('router')->getContext()->setParameter('_locale', 'en');
$controller = new MyController();
$controller->setContainer(self::$kernel->getContainer());
$response = $controller->myAction($arg1, $arg2, $argWhatever);
// assertions here
Seems to work just fine.
If the controllers are setup as services, then they can be easily tested much as any other class would be unit-tested. Even before Symfony 3.3 started to make them services by default, I had altered some of my own to allow them to be more easily tested like this.

How to filter in Symfony2?

First of all i am very new to Symfony 2 and started to learn.
Is there any possibility for filter a value? Perhaps filter chains too?
I know this concept from Zend Framework 1 and 2.
E.g.:
i have a string "1A- N "
now i want to filter so that only numeric values pass; result "1"
Do i have to implement this on my own i Symfony?
I would like to do something like:
$text = '1A - N';
$numberFilter = new NumberFilter();
$filteredText = $numberFilter->filter($text);
//now in $text i find '1'
But for now i nowhere found something like this in Symfony what surprises me a lot. I thought it is a full stack framework and such function is so basic.
I found something like validators but they only say if a value e.g. contains only numbers or not. Or is the validation concept of symfony like that it does not only say if it is numeric or not but filter all other smybols out, too?
Depending on what you want precisely:
disallow user input not fulfilling certain rules
use validators in forms
use asserts in entities
chenge user input in case it's wrong
use viewransformers in forms
use event listeners in forms
use event listeners for doctrine
change data that already exists in the database
use filters in twig
create a command to execute from commandline
You can also try http://php.net/manual/ro/filter.filters.sanitize.php
I have built quite big apps with Symfony and never needed such a feature. Filters are mostly used in views anyway. Symfony comes with Twig, which has filters, that can be chained, and you can write your own filters. But if you need filters in the backend to do some background processing, you can accomplish it the way you suggested.
I suggest you write an interface and use a factory pattern, so you set a standard if you make many filters, so it will be easier to make the chaining work;)
After the answers and searching i got to the following conclusion.
There is no concept for this for now in Symphony 2.
You have to write it on your own.

Symfony2: Access Request object in Entity

I'd like to know how to access the Request object in an entity (Symfony2) to modify the user locale.
If someone has found a solution for my problem, please let me know.
It's not possible. This is by design: the entity is just a simple object that should know nothing about the request - it's the responsibility of the controller to interpret the request, and manipulate the entity based on that.
Something like:
//inside your controller:
public function fooBarAction(Request $request)
{
$entity = // get entity
$entity->setLocale($request->getSession()->getLocale());
}
The above is just example code, it won't work if you just copy and paste it. It's just to demonstrate the general idea. The entity should just be a very simple object, who's only responsibility is to hold some data. It shouldn't know where the data is coming from - that keeps it flexible (if you want to set the locale based on something else, you only have to change your controller, not all your entities).
It is possible, but...
What you can but never should do is inject the Request object into the entity (Practically turning your entity into service, see here). Also, even worse idea (but which people still do), you could inject the whole container and get Request from there. The reason why you shouldn't do it is you never should have any code that deals with business rules or any system code in your entities.
You can switch your locale directly in your routes by using _locale custom variable (accessible also from the Request). Or you can create a kernel listener, which will do the required functionality for you. This way you keep your code testable and decoupled.

Access Session from EntityRepository

I'm using Symfony2 with Doctrine2. I want to achieve the following:
$place = $this->getDoctrine()->getRepository('TETestBundle:Place')->find($id);
And on that place will be the info of the place (common data + texts) on the user language (in session). As I am going to do that hundreds of times, I want to pass it behind the scenes, not as a second parameter. So an English user will view the place info in English and a Spanish user in Spanish.
One possibility is to access the locale of the app from an EntityRepository. I know it's done with services and DI but I can't figure it out!
// PlaceRepository
class PlaceRepository extends EntityRepository
{
public function find($id)
{
// get locale somehow
$locale = $this->get('session')->getLocale();
// do a query with the locale in session
return $this->_em->createQuery(...);
}
}
How would you do it? Could you explain with a bit of detail the steps and new classes I have to create & extend? I plan on releasing this Translation Bundle once it's ready :)
Thanks!
I don't believe that Doctrine is a good approach for accessing session data. There's just too much overhead in the ORM to just pull session data.
Check out the Symfony 2 Cookbook for configuration of PDO-backed sessions.
Rather than setting up a service, I'd consider an approach that used a Doctrine event listener. Just before each lookup, the listener would pick out the correct locale from somewhere (session, config, or any other place you like in the future), inject it into the query, and like magic, your model doesn't have to know those details. Keeps your model's scope clean.
You don't want your model or Repository crossing over into the sessions directly. What if you decide in the future that you want a command-line tool with that Repository? With all that session cruft in there, you'll have a mess.
Doctrine event listeners are magically delicious. They take some experimentation, but they wind up being a very configurable, out-of-the-way solution to this kind of query manipulation.
UPDATE: It looks like what you'd benefit from most is the Doctrine Translatable Extension. It has done all the work for you in terms of registering listeners, providing hooks for how to pass in the appropriate locale (from wherever you're keeping it), and so on. I've used the Gedmo extensions myself (though not this particular one), and have found them all to be of high quality.

Resources