One of the features lacking in OpenCart is simple URL query string generation. This has lead to a significant amount of boilerplate code manually generating them:
Code: Select all
$url = '';
if (isset($this->request->get['filter_name'])) {
$url .= '&filter_name=' . urlencode(html_entity_decode($this->request->get['filter_name'], ENT_QUOTES, 'UTF-8'));
}
if (isset($this->request->get['filter_model'])) {
$url .= '&filter_model=' . urlencode(html_entity_decode($this->request->get['filter_model'], ENT_QUOTES, 'UTF-8'));
}
if (isset($this->request->get['filter_price'])) {
$url .= '&filter_price=' . $this->request->get['filter_price'];
}
if (isset($this->request->get['filter_quantity'])) {
$url .= '&filter_quantity=' . $this->request->get['filter_quantity'];
}
if (isset($this->request->get['filter_status'])) {
$url .= '&filter_status=' . $this->request->get['filter_status'];
}
if (isset($this->request->get['sort'])) {
$url .= '&sort=' . $this->request->get['sort'];
}
if (isset($this->request->get['order'])) {
$url .= '&order=' . $this->request->get['order'];
}
if (isset($this->request->get['page'])) {
$url .= '&page=' . $this->request->get['page'];
}
$this->response->redirect($this->url->link('catalog/product', 'token=' . $this->session->data['token'] . $url, 'SSL'));
Proof Of Concept
The issue could be addressed many ways. The following is a simple controller-based method:
Code: Select all
protected function makeQueryString($defaults = []) {
$queries = array(
'filter_name' => null,
'filter_model' => null,
'filter_price' => null,
'filter_quantity' => null,
'filter_status' => null,
'sort' => null,
'order' => null,
'page' => null
);
$queries = array_merge($queries, $defaults);
$url = 'token=' . $this->session->data['token'];
foreach ($queries as $query => $value) {
if (isset($this->request->get[$query])) {
$url .= '&' . $query . '=' . urlencode(html_entity_decode($this->request->get[$query]));
continue;
}
if (!is_null($value)) {
$url .= '&' . $query . '=' . urlencode(html_entity_decode($value));
}
}
return $url;
}
Code: Select all
$this->response->redirect($this->url->link('catalog/product', $this->makeQueryString(), 'SSL'));
Code: Select all
$this->response->redirect($this->url->link(
'catalog/product',
$this->makeQueryString(['filter_category' => null, 'sort' => 'DESC']),
'SSL'
));
Along with eliminating redundant code it will also make the core easier to learn and debug. It could also be expanded for use with the event system so developers could add or modify GET parameters. Small mistakes developers make like forgetting to include the URL token could also be prevented.