0
votes

I'm working on a zf2 project and i need to configure some of my modules to work on different subdomains following scenario:

  • I have different Modules like API, Backend (Admin), Application (Core module), Blog etc..
  • I have multiple vhosts which points to same application/public directory like api.foobar.com, admin.foobar.com
  • I'm using unique controller keys/aliases in each module like this:

...

'controllers' => array(
    'invokables' => array(
        'home-controller'     => 'Application\Controller\IndexController',
    ),
),

So, i want to change my application's behaviour based on domain (hostname/routeMatch), if hostname looks like api.foobar.com my default controller should derived form a restful controller, if it's a generic homepage request my auth-backed admin controller should not invoke, if it's a mobile site, change home controller to mobile-controller, utilize different layout etc...

Non-working configuration (application/config/module.config.php):

return array(
    'router' => array(
        'routes' => array(
           'home' => array(
                'type' => 'hostname',
                'options' => array(
                    'route' => 'www.foobar.com',
                    'defaults' => array(
                        '__NAMESPACE__' => 'Application\Controller',
                        'controller' => 'home-controller',
                        'action' => 'index'
                    )
                )
            ),
            'api' => array(
                'type' => 'hostname',
                'options' => array(
                    'route' => 'api.foobar.com',
                    'constraints' => array(
                        'subdomain' => 'api',
                    ),
                    'defaults' => array(
                        '__NAMESPACE__' => 'Api\Controller',
                        'controller' => 'api-controller',
                        'action' => 'index'
                    )
                )
            ),
            'admin' => array(
                'type' => 'hostname',
                'options' => array(
                    'route' => 'admin.foobar.com',
                    'constraints' => array(
                        'subdomain' => 'admin',
                    ),
                    'defaults' => array(
                        '__NAMESPACE__' => 'Admin\Controller',
                        'controller' => 'admin-controller',
                        'action' => 'index'
                    )
                ),
                'may_terminate' => true,
                'child_routes' => array(
                    'default' => array(
                        'type' => 'Segment',
                        'options' => array(
                            'route' => '/[:controller[/:action]]',
                            'constraints' => array(
                                '__NAMESPACE__' => 'Admin\Controller',
                                'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
                                'action' => '[a-zA-Z][a-zA-Z0-9_-]*'
                            ),
                            'defaults' => array()
                        )
                    )
                )
            )
        )
    )
);

Interesting thing is, currently with this configuration i'm getting a 404 page not found error both api.foobar.com, www.foobar.com and admin.foobar.com on my devlepment environment and dump of routes like following:

object(Zend\Mvc\Router\PriorityList)[214]
  protected 'routes' => 
    array (size=3)
      'home' => 
        array (size=3)
          'route' => 
            object(Zend\Mvc\Router\Http\Hostname)[216]
              ...
          'priority' => int 0
          'serial' => int 0
      'admin' => 
        array (size=3)
          'route' => 
            object(Zend\Mvc\Router\Http\Part)[218]
              ...
          'priority' => int 0
          'serial' => int 1
              ...
          'priority' => int 0
          'serial' => int 2
  protected 'serial' => int 3
  protected 'count' => int 3
  protected 'sorted' => boolean false

I got this dump in Application Module > Module.php > onBootstrap($e) method simply: $routes = $e->getApplication()->getServiceManager->get('router')->getRoutes();

Questions:

  1. What is wrong with this configration?
  2. why my top-level admin route listing as a Zend\Mvc\Router\Http\Part?
  3. Should i separate route definitions to every module's own module.config.php file for this scenario?
1

1 Answers

1
votes

---What is wrong with this configuration

it works well in my test, you can refer to the code at the bottom. So I suggest you should check:

  1. make sure the controller/action files exist
  2. make sure the vhosts has been configured in apache/nginx/, whatever http host you are using.

---why my top-level admin route listing as a Zend\Mvc\Router\Http\Part?

actully, your 'admin' route has child routes configured, zf2 will treat it as 'part' route, please refer to the Zend\Mvc\Router\Http\Part example

---Should I separate route definitions to every module's own module.config.php file for this scenario?

No, actually you can put all module routes in one module's config file if you like.

Here is my code: return array

(
    'router' => array(
        'routes' => array(
                /*
            'home' => array(
                'type' => 'Zend\Mvc\Router\Http\Literal',
                'options' => array(
                    'route'    => '/',
                    'defaults' => array(
                        'controller' => 'Application\Controller\Index',
                        'action'     => 'index',
                    ),
                ),
            ),
            */
            'home1' => array(
                    'type' => 'hostname',
                    'options' => array(
                            'route' => 'zfskeleton.com',
                            'defaults' => array(
                                    '__NAMESPACE__' => 'Application\Controller',
                                    'controller' => 'Index',
                                    'action' => 'index'
                            )
                    )
            ),
            'home' => array(
                    'type' => 'hostname',
                    'options' => array(
                            'route' => 'www.zfskeleton.com',
                            'defaults' => array(
                                    '__NAMESPACE__' => 'Application\Controller',
                                    'controller' => 'Index',
                                    'action' => 'index'
                            )
                    )
            ),
            'api' => array(
                    'type' => 'hostname',
                    'options' => array(
                            'route' => 'api.zfskeleton.com',
                            'constraints' => array(
                                    'subdomain' => 'api',
                            ),
                            'defaults' => array(
                                    '__NAMESPACE__' => 'Album\Controller',
                                    'controller' => 'Album',
                                    'action' => 'api'
                            )
                    )
            ),
            'admin' => array(
                    'type' => 'hostname',
                    'options' => array(
                            'route' => 'admin.zfskeleton.com',
                            'constraints' => array(
                                    'subdomain' => 'admin',
                            ),
                            'defaults' => array(
                                    '__NAMESPACE__' => 'Album\Controller',
                                    'controller' => 'Album',
                                    'action' => 'admin'
                            )
                    ),
                    'may_terminate' => true,
                    'child_routes' => array(
                            'default' => array(
                                    'type' => 'Segment',
                                    'options' => array(
                                            'route' => '/[:controller[/:action]]',
                                            'constraints' => array(
                                                    '__NAMESPACE__' => 'Admin\Controller',
                                                    'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
                                                    'action' => '[a-zA-Z][a-zA-Z0-9_-]*'
                                            ),
                                            'defaults' => array()
                                    )
                            )
                    )
            ),
            // The following is a route to simplify getting started creating
            // new controllers and actions without needing to create a new
            // module. Simply drop new controllers in, and you can access them
            // using the path /application/:controller/:action
            'application' => array(
                'type'    => 'Literal',
                'options' => array(
                    'route'    => '/application',
                    'defaults' => array(
                        '__NAMESPACE__' => 'Application\Controller',
                        'controller'    => 'Index',
                        'action'        => 'index',
                    ),
                ),
                'may_terminate' => true,
                'child_routes' => array(
                    'default' => array(
                        'type'    => 'Segment',
                        'options' => array(
                            'route'    => '/[:controller[/:action]]',
                            'constraints' => array(
                                'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
                                'action'     => '[a-zA-Z][a-zA-Z0-9_-]*',
                            ),
                            'defaults' => array(
                            ),
                        ),
                    ),
                ),
            ),
        ),
    ),