0

I am trying to parse my form's GET method and create a function that can get all the parameters from the URL in DRUPAL 8. I have a form that I am gonna use it to filter my library items as search( I know I can use search api or advanced search but my client wants this way ) So I have a few fields such as keyword, title, description, location, author, from, to, collection. and when I add all the fields after the redirection to result page

http://example.com/advancedsearchresult?keyword=test1&title=test2&description=test3&author=test4&location=test5&from=&to=&collection=&media=all

I would like to do nice job with using OOP and Symfony service features. My question is how could i create a function in my controller for this result page that is gonna parse all the parameters from the URL so I can use them to create an object in service to create individual query for each parameters to make search mechanism for this form?

UPDATED:

After @oknate pointed out, I updated my controller like this:

namespace Drupal\advancedsearch\Controller;

use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\advancedsearch\AdvancedSearchQuery;

class SearchResultController extends ControllerBase {
 protected $advancedsearchSearchResult;

public function __construct(AdvancedSearchQuery $advancedsearch_search_result ) {
 $this->advancedsearchSearchResult = $advancedsearch_search_result;
}

public static function create(ContainerInterface $container) {
return new static(
  $container->get('advancedsearch.search.result')
);
}
private function setupAdvancedSearchQuery() {
$params = \Drupal::request()->query->all();
foreach ($params as $key => $value) {
  if (!empty($value)) {
    $params[$key] = $value;
  }
}
}
}

on the other hand, I created my service file, I created my variables which matches with parameters, so am I gonna be able to use setupAdvancedSearchQuery() when I call the object for each parameters, if so can anyone give a hint?

2

If these $_GET parameters are also route parameters (set up in a module's routing configuration), you can use

 \Drupal::routeMatch()->getParameters();

Or for a specific parameter:

$keyword = \Drupal::routeMatch()->getParameters()->get('keyword');

If the $_GET parameters are not route parameters, you can get all the parameters this way:

$params = \Drupal::request()->query->all();

If you want to set default parameters for parameters that aren't in the URL, you can merge the $params with an array of defaults. Then depending on how you're going to use the parameters, you may want to XSS filter the params to prevent cross-site scripting attempts. As @Berdir points out, this is rarely necessary, as twig auto escapes and if you are passing parameters into the query abstraction layer properly, it will also filter your input. But you could filter your params this way:

foreach ($params as $key => $value) {
  if (!empty($value)) {
    $params[$key] = Xss::filter($value);
  }
}

(If you are using arrays in your $_GET params, this foreach loop would need to be altered to handle that use case.)

Here's some more info on XSS security.

After you have pulled-in and cleaned up your $_GET variables, you could then save these parameters to your object, and then use them conditionally in your query.

Since you asked specifically about Controllers, you can pass the request object to controller in the constructor:

  public function __construct(Request $request) {
    $this->request = $request;
  }

  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('request_stack')->getCurrentRequest()
    );
  }

Then you could use the request object from the container.

If you set up the parameters as route parameters, you can just pass them in as arguments to the controller.

  • manual xss filtering is almost never necessary in D8, definitely not for input that you are processing and twig auto escape takes care of most output things, doing it manually actually often results in double escaping – Berdir Feb 27 '17 at 19:39
  • ok, I'll update my answer to say this isn't usually necessary. – oknate Feb 27 '17 at 19:41
  • great answer, because of the keywords symfony, oop and controller in the question you could get the request by placing it in the parameter list function myController(Request $request) and so avoid using a static method. – 4k4 Feb 27 '17 at 19:46
  • Yes, let me add that. – oknate Feb 27 '17 at 19:47
  • you don't need to inject the request in a controller class, the request object is available for all routes as controller parameter without the need to define it in the route. – 4k4 Feb 27 '17 at 20:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.