0

As cookbook says:

Routes can use the _host option to only match specific hosts. You can use the *. wildcard to match any subdomain.

But what if I would like set same route for multiple hosts at once?

For example:

$routes->connect(
    '/images',        
    ['controller' => 'Images', 'action' => 'index']
)->setHost('images.example.com');

$routes->connect(
    '/images',        
    ['controller' => 'Images', 'action' => 'index']
)->setHost('images.example2.com');

$routes->connect(
    '/images',        
    ['controller' => 'Images', 'action' => 'index']
)->setHost('images.example3.com');

Above is pointless if I have to set several dozen of those routes.

Ideal would be something like this:

$routes->connect(
    '/images',        
    ['controller' => 'Images', 'action' => 'index']
)->setHosts(['images.example.com','images.example2.com','images.example3.com']);
ndm
  • 59,784
  • 9
  • 71
  • 110
danny3b
  • 313
  • 5
  • 17

1 Answers1

2

That's not supported, you'll either have to set multiple routes accordingly, which you could simply do in a loop that you feed a list of your hosts:

foreach (['images.example.com','images.example2.com','images.example3.com'] as $host) {
    $routes
        ->connect(
            '/images',        
            ['controller' => 'Images', 'action' => 'index']
        )
        ->setHost($host);
}

or create a custom route class that accepts either multiple hosts, or maybe actual regular expressions. The latter would probably be easier, as it wouldn't require reimplementing a lot of stuff for matching, something like:

src/Routing/Route/RegexHostRoute.php

namespace App\Routing\Route;

use Cake\Routing\Route\DashedRoute;

class RegexHostRoute extends DashedRoute
{
    public function match(array $url, array $context = []): ?string
    {
        // avoids trying to match the _host option against itself in parent::match()
        if (!isset($url['_host'])) {
            return null;
        }

        return parent::match($url, $context);
    }

    public function hostMatches(string $host): bool
    {
        return preg_match('^@' . $this->options['_host'] . '@$', $host) === 1;
    }
}

That should allow to set a host like images\.example[2-3]?\.com:

$routes
    ->connect(
        '/images',        
        ['controller' => 'Images', 'action' => 'index'],
        ['routeClass' => \App\Routing\Route\RegexHostRoute::class]
    )
    ->setHost('images\.example[2-3]?\.com');

See also

ndm
  • 59,784
  • 9
  • 71
  • 110