Brock Caldwell
Brock Caldwell

Reputation: 17

Zend routing issue

I'm working on converting a (quite sloppily put together) zend expressive website to a zend framework 3 website for a local restaurant. When I set up the routing on the expressive website I would load a location based on a query parameter looking like this.

website.com/location?location=xxx

On my new website the routing looks like this

website.com/locations/view/xxx

I need to set up a route that redirects the old url to the new url. So far I have set up a route that looks for the /location?location=[/:location] hoping that it would recognize this 'Segment' route and load the appropriate LocationsController. Right now it is giving me a route not found error.

My code looks like below.

module.config.php

namespace Application;

use Zend\Router\Http\Literal;
use Zend\Router\Http\Segment;
use Zend\ServiceManager\Factory\InvokableFactory;

return [
    'router' => [
        'routes' => [
            'home' => [
                'type' => Literal::class,
                'options' => [
                    'route'    => '/',
                    'defaults' => [
                        'controller' => Controller\IndexController::class,
                        'action'     => 'index',
                    ],
                ],
            ],
            'locations-old' => [
                'type'    => Segment::class,
                'options' => [
                    'route'    => '/location?location=[/:location]',
                    'defaults' => [
                        'controller' => Controller\LocationController::class,
                        'action'     => 'index',
                    ],
                ],
            ],
            'locations' => [
                'type'    => Segment::class,
                'options' => [
                    'route'    => '/locations[/:action[/:location]]',
                    'constraints' => [
                        'action' => '[a-zA-Z]*',
                        'location'     => '[a-zA-Z]*',
                    ],
                    'defaults' => [
                        'controller' => Controller\LocationController::class,
                        'action'     => 'index',
                    ],
                ],
            ],
            'locations.html' => [
                'type'    => Literal::class,
                'options' => [
                    'route'    => '/locations.html',
                    'constraints' => [
                        'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
                        'location'     => '[a-zA-Z][a-zA-Z0-9_-]*',
                    ],
                    'defaults' => [
                        'controller' => Controller\IndexController::class,
                        'action'     => 'index',
                    ],
                ],
            ],
            'about' => [
                'type' => Literal::class,
                'options' => [
                    'route'    => '/about',
                    'defaults' => [
                        'controller' => Controller\AboutController::class,
                        'action'     => 'index',
                    ],
                ],
            ],
            'employ' => [
                'type' => Literal::class,
                'options' => [
                    'route'    => '/employ',
                    'defaults' => [
                        'controller' => Controller\EmployController::class,
                        'action'     => 'index',
                    ],
                ],
            ],
            'news' => [
                'type' => Literal::class,
                'options' => [
                    'route'    => '/news',
                    'defaults' => [
                        'controller' => Controller\NewsController::class,
                        'action'     => 'index',
                    ],
                ],
            ],
        ],
    ],
    'view_manager' => [
        'display_not_found_reason' => true,
        'display_exceptions'       => true,
        'doctype'                  => 'HTML5',
        'not_found_template'       => 'error/404',
        'exception_template'       => 'error/index',
        'template_map' => [
            'layout/layout'           => __DIR__ . '/../view/layout/layout.phtml',
            'application/index/index' => __DIR__ . '/../view/application/index/index.phtml',
            'error/404'               => __DIR__ . '/../view/error/404.phtml',
            'error/index'             => __DIR__ . '/../view/error/index.phtml',
        ],
        'template_path_stack' => [
            __DIR__ . '/../view',
        ],
    ],
];

LocationController.php

namespace Application\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Application\Model\StoreTable;
use Zend\View\Model\ViewModel;

class LocationController extends AbstractActionController
{
    private $table;

    public function __construct(StoreTable $table)
    {
        $this->table = $table;
    }

    public function indexAction()
    {
        if($_GET['location'] && $this->table->doesExist($_GET['location'])) {
            $location = $_GET['location'];
            $this->redirect()->toRoute('locations', ['action' => 'view', 'location' => $location])->setStatusCode(302);
        } else {
            $this->redirect()->toUrl('/#locations')->setStatusCode(301);
        }
    }

    public function viewAction()
    {
        $location = (string) $this->params()->fromRoute('location');

        $store = $this->table->getStore($location);

        return new ViewModel([
            'store' => $store,
        ]);
    }
}

Any help would be greatly appreciated and I can provide more info if needed. Thanks!

Upvotes: 0

Views: 134

Answers (1)

Gautam Rai
Gautam Rai

Reputation: 2505

configure your route as following, this will be handle query based url as you given "website.com/location?location=xxx",

In below route ":key" variable implies ?location=xxx

          'locations-old' => [
                'type'    => Segment::class,
                'options' => [
                    'route'    => '/location/:key',
                    'defaults' => [
                        'controller' => Controller\LocationController::class,
                        'action'     => 'index',
                    ],
                    'constraints' => [
                        'key' => '[a-z0-9]+',
                    ],
                ],
                'child_routes' => [
                    'query' => ['type' => 'query'],
                ],
            ]

Upvotes: 0

Related Questions