Transform GET parameters to clean URL - symfony

I use Datatables on fronted to send GET parameters to my Silex application.
Datatables send GET parameters of that type:
champs_societes%5B%5D=naf&zone-geographique=ville&effectif%5B%5D=eff_1a9&effectif%5B%5D=eff_10a19&effectif
%5B%5D=eff_20a49&effectif%5B%5D=eff_plus5000&ca%5B%5D=10k-50k&ca%5B%5D=50k-100k&ca%5B%5D=1kk-2kk&ca%5B
%5D=2kk-5kk&champs_societes%5B%5D=capital_int&fondation%5Bmin%5D=&fondation%5Bmax%5D=&champs_societes
%5B%5D=siren&champs_societes%5B%5D=siret&champs_societes%5B%5D=nature&nature%5B%5D=Etablissement&champs_societes
%5B%5D=formejur&champs_societes%5B%5D=emailg&champs_contacts%5B%5D=emailn&ac_formejur=Artisan-Commer
%C3%A7ant%2CBanque+Populaire%2FLoi+Mars+1917%2CCoop.+%C3%80+Responsabilit%C3%A9+Limit%C3%A9e&ac_naf=0113Z
%2C0121Z%2C0126Z%2C0130Z&ac_departements=14%2C50%2C61%2C68%2C03&ac_villes=77330%2C77680%2C77340&ac_fonction
=Assistant%2CCharg%C3%A9+D'Affaires%2CContr%C3%B4leur+De+Gestion%2CDirecteur+%2F+Responsable
I there a way to genereate a clean URL from this chain ? Ideally by using the Symfony/Silex routing.
Thanks for help
EDIT
I get the GET params above with Request:
$app->post('/ajax/formprocess', function (Request $request) use ($app) {
$df = new Filtres( $request->request->get('dataForm') );
$filtroAdd = $df->getRequest();

I would try with Request class first
Request class from HttpFoundation component (default in Symfony, not sure about Silex as I never used it)
/**
* #param \Symfony\Component\HttpFoundation\Request $request
*/
public function someAction(Request $request)
{
$request->getSchemeAndHttpHost();
$request->getBasePath();
$request->getQueryString(); // this will be the most helpful in your case
// access what you need and build normalized url
}
You should be able to build clean normalized url
Edit, solution for parsing query parameter string to array
$queryParameters = 'query parameters as string to be parsed';
$output = [];
parse_str($queryParameters, $queryParameters);
print_r($queryParameters);
http://php.net/manual/en/function.parse-str.php

Related

API to get a content type against URL

I have a scenario where I need to perform some redirection of a not found url
http://localhost/drupal9/node/1/search
the word search is added though a plugin I am using and it is a front-end route not a backend so upon refreshing this url I get Not Found which totally makes sense what I need to do is remove the word search from the URL and redirect to,
http://localhost/drupal9/node/1/
as search is a common word and can be used in other content type I first need to check whether the URL is of my custom content type. let me show you a piece of implementation I already have.
function [module]_preprocess_page(&$variables) {
$query = \Drupal::entityQuery('node')
->condition('type', [module]);
$nids = $query->execute();
if(array_search(2,$nids)){
echo "yes";
}
}
so over here what I am doing is grabbing all the nodes with my content type and grabbing the Nid from URI and matching them and this does work but there is another problem with this.
In the page properties we have an option of ALias so if the user uses a custom alias, then I dont get the Nid in the URI anymore so this logic breaks,
the question may seem a bit tricky but the requirement is simple.I am looking for a unified solution to parse the URL into some drupal API and simply getting back the content type name.The Url may contain a custom alias or a Nid
You can create an EventSubscriber subscribing the event kernel.request to handle the case of URL <node URL>/search.
For detailed steps to create an EventSubscriber, you can see here.
And below is what you need to put in your EventSubscriber class:
RequestSubscriber.php
<?php
namespace Drupal\test\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\KernelEvents;
/**
* Class RequestSubscriber.
*/
class RequestSubscriber implements EventSubscriberInterface {
/**
* {#inheritdoc}
*/
public static function getSubscribedEvents() {
return [
KernelEvents::REQUEST => 'onKernelRequest',
];
}
public function onKernelRequest($event) {
$uri = $event->getRequest()->getRequestUri(); // get URI
if (preg_match('/(.*)\/search$/', $uri, $matches)) { // check if URI has form '<something>/search'
$alias = $matches[1];
$path = \Drupal::service('path_alias.manager')->getPathByAlias($alias); // try to get URL from alias '<something>'
if (preg_match('/node\/(\d+)/', $path, $matches)) { // if it is a node URL
$node = \Drupal\node\Entity\Node::load($matches[1]);
$content_type = $node->getType();
//... some logic you need
}
}
}
}

Is there a generic URL builder/manipulator in Drupal/Symfony?

How to build and/or modify generic URLs on Drupal/Symfony?
For example, having at the input an URL like: http://some.url/with?param1=value1#fragment I would like to be able to manipulate any parts of the url including:
cut off the query (search) part
add more query parameters
change the path part
replace domain
add/change fragment
etc
I couldn't find anything appropriate in Drupal or Symfony.
In Drupal 8 there is lib/Drupal/Core/Url.php class which provide some methods to get/set parameters
Availables methods to setting the route parameters:
setRouteParameters($parameters)
setRouteParameter($key, $value)
Availables methods to set the route options:
setOptions($options)
setOption($name, $value)
How to use the setParameter method:
/**
* #var Drupal\Core\Url $url
*/
$url->setRouteParameter('arg_0', $arg0);
With Symfony 3.3 you can use Request::create($url):
use Symfony\Component\HttpFoundation\Request;
$url = 'http://some.url/with?param1=value1#fragment'
$req = Request::create($url)
Then you can call
$req->getQueryString() // param1=value1
$req->getHost() // some.url
$req->getSchemeAndHttpHost() // http://some.url
$req->getBaseUrl() // /with
Ref http://api.symfony.com/3.3/Symfony/Component/HttpFoundation/Request.html
I don't think this class provides any setter for host/param/path so you can do the following:
str_replace($req->getHost(), 'new-host.com', $url) // change host
About the hash fragment #fragment, it doesn't seem to be available on server-side (see Get fragment (value after hash '#') from a URL in php).

Symfony Controller return array

I am trying to create a listener that configures the Response using annotations and sets the response content as the controller return.
The Controller code:
use PmtVct\PhotoBookBundle\Annotations\ResponseType;
use Symfony\Component\HttpFoundation\Request;
/**
* #ResponseType("JSON")
*/
public function home(Request $request) {
return ['asdf' => 123];
}
But I receive the 'The controller must return a response' error.
There is a way to return an array on Controller instead a Response?
You are trying to do a similar thing to FOSRestBundle. Maybe consider using this bundle? It will allow:
Return arrays in controller, exactly in a way you want
Serialise response into Json, or other format you wish, also it can detect format automatically from Request.
In case you still want to build such listener yourself - look how it's done in FOSRestBundle - https://github.com/FriendsOfSymfony/FOSRestBundle/blob/master/EventListener/ViewResponseListener.php - they are using "kernel.view" event.
According to the documentation you can return a JsonResponse like this:
return new JsonResponse(['asdf' => 123]);

Symfony3 get parameters from URL

I discovering symfony3, but im stuck at getting the parameters passed with a link from an action.
In my twig file, im redirecting the user to an action:
<td>go to</td>
And im my action, i'm trying to get the id with:
/**
* #Route("/AfficheDetail", name="esprit_park_affiche")
*/
public function afficheAction()
{
$id = $this->getParameter("id");
return $this->render("#EspritPark/Voiture/affiche.html.twig", array("id" => $id));
}
but each time i get: The parameter "id" must be defined.
like the getParameter isnt returning anything.
I even tried with:
$id = $this->get("request")->get("id");
but i get: You have requested a non-existent service "request". Did you mean one of these: "monolog.logger.request", "request_stack", "router.request_context", "data_collector.request"?
The getParameter() method from the base Controller class is looking up parameters from the service container.
I would make the parameters part of your route. You can then retrieve the values through the action method's parameters:
/**
* #Route("/AfficheDetail/{id}/{serie}/{dateMise}/{marque}", name="esprit_park_affiche")
*/
public function afficheAction($id, $serie, $dateMise, $marque)
{
// ...
}
If you do not add them to the route pattern, they will be accessible through the URL parameters (the current request will be injected automatically if you type hint an argument with the Request class):
public function afficheAction(Request $request)
{
$id = $request->query->get('id');
$serie = $request->query->get('serie');
$dateMise = $request->query->get('dateMise');
$marque = $request->query->get('marque');
// ...
}

Backbone.js and Symfony2 form validation

I'm creating a single-page app with backbone.js and symfony2 and I need your opinion on one thing.
For example see this create user action. The request is sent by a backbone model (model.save), and I want to check values on the server side. My question is pretty simple, is it pertinent to use the symfony2 form validation to do this check ?
/**
*
* #Route("/user", defaults={"_format"="json"}, name="create_user")
* #Method({"POST"})
*/
public function createUserAction() {
$request = $this->get('request');
if (0 === strpos($request->headers->get('Content-Type'), 'application/json')) {
$data = json_decode($request->getContent(), true);
$request->request->replace(is_array($data) ? $data : array());
}
$entity = new User();
$form = $this->createForm(new UserType(), $entity);
$form->bind($request);
...
}
If yes, how can I do that? Backbone sends JSON request body whereas bind method of Symfony2 form object only accepts URL encoding. I've already tried to use urlencode function without success.
Yes it is pertinent, you should always do server side validation. My question is where is your content variable coming from? I don't see it being assigned in the above code.
You could use FOSRestBundle. It has a "body listener", which will decode request body, and let you bind you form with a request that had a json body.
You can learn more about this feature in the FOSRestBundle documentation.

Resources