HappyCoder
HappyCoder

Reputation: 6155

ZF2 - Setting a template for a vendor controller action

I am using ZfcUser and need to set a custom Login / Register page template. Originally how I achieved this was quite simple.

I set the login template in my Application/Module.config.php file:

'login/layout'            => __DIR__ . '/../view/login/login.phtml',

Then in the actual vendor controller I added the following:

$this->layout('login/layout');

This works perfectly.

The problem however is that the vendor directories are managed by composer and any changes overwrite my modifications.

On ZfTalk it was suggested that I can "override" some of the services of ZfcUser. To be honest, I have no idea what it means to override a service or how to go about it.

What I was thinking of doing was to write a simple check in the constructor of the Application module which simply looks at what module / action is being called and to serve a layout accordingly.

Something like this:

//get page string
//if string parts = user / login set template to login template

Any ideas of a better way to implement?

Upvotes: 1

Views: 801

Answers (3)

Tadej
Tadej

Reputation: 426

As said by Sergio, don't modify files inside vendor folder, that's just wrong!

To solve your problem: Inside the Module.php that you have (for overriding original ZfcUser module) you need to attach a function to an event EVENT_ROUTE, then check the matched route and override the ViewModel template for routes that you want layout changed. Here is the code:

    $e->getApplication()->getEventManager()->attach(MvcEvent::EVENT_ROUTE, function(MvcEvent $e) {
        $routeMatch = $e->getRouteMatch();
        if($routeMatch->getParam('action') == 'login' || $routeMatch->getParam('action') == 'register') {
            $e->getViewModel()->setTemplate('layout/login');
        }
    });

I'm not sure this is the best solution but it works.

Upvotes: 0

HappyCoder
HappyCoder

Reputation: 6155

To try and understand the suggestion provided by Sergio this is how I now understand "over riding" a modules settings:

Because settings are stored in arrays, we have an opportunity to write over vendor settings simply by including our new settings in a module that is called after the vendor module (in the config/application.config.php file) and using the same keys as the vendor settings.

My goal is to use a different template for my login pages and to extend the ZfcUser functionality. To get this right I need to create a new module (Zftoolbox) that will allow me to over ride certain ZfcUSer settings.

The following is not working 100% however:

 'modules' => array(
    'ZfcBase',             //Basic apps for ZfcUser and BjyAuthorize found in .vendors
    'ZfcUser',             //User login, logout, sessions, authentication etc. found in 
    'Application',         //The applications main functions run from this module
    'Zftoolbox',           //Applications override settings are stored here
),

My Zftoolbox file structure is as follows:

enter image description here The module.php file is as follows:

<?php
namespace Zftoolbox;
use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
use Zend\ModuleManager\Feature\ConfigProviderInterface;

class Module implements AutoloaderProviderInterface, ConfigProviderInterface
{
    public function getAutoloaderConfig()
    {
    return array(
        'Zend\Loader\ClassMapAutoloader' => array(
            __DIR__ . '/autoload_classmap.php',
        ),
        'Zend\Loader\StandardAutoloader' => array(
            'namespaces' => array(
                __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
            ),
        ),
    );
}

    public function getConfig()
    {
        return include __DIR__ . '/config/module.config.php';
    }

}

The NewUserController.php file

<?php
namespace Zftoolbox\Controller;

use ZfcUser\Controller\UserController;

class NewUserController extends UserController
{

    public function newindexAction()
    {
        $this->layout('login/layout');
        $this->indexAction();
    }

    public function newloginAction()
    {
        $this->layout('login/layout');
        $this->loginAction();
    }
}

And Module.config.php

<?php
return array(

'controllers' => array(
    'invokables' => array(
        'zfcuser2' => 'Zftoolbox/Controller/NewUserController',
    ),
),

'router' => array(
    'routes' => array(
        'zfcuser' => array(
            'type' => 'Literal',

            'child_routes' => array(
                'login' => array(
                    'type' => 'Literal',
                    'options' => array(
                        'route' => '/login',
                        'defaults' => array(
                            'controller' => 'zfcuser2',
                            'action'     => 'newlogin',
                        ),
                    ),
                ),

                'register' => array(
                    'type' => 'Literal',
                    'options' => array(
                        'route' => '/register',
                        'defaults' => array(
                            'controller' => 'zfcuser2',
                            'action'     => 'newregister',
                        ),
                    ),
                ),



            ),
        ),
    ),
),
);

So the idea in principle is to create a new route to my NewUserController where I set the template and then call the original loginAction.

This current setup however is invoking the following routing error:

Fatal error: Class 'Zftoolbox/Controller/NewUserController' not found in
/trunk/vendor/zendframework/zendframework/library/
Zend/ServiceManager/AbstractPluginManager.php on line 170

Upvotes: 3

Sergio Rinaudo
Sergio Rinaudo

Reputation: 2363

You should never edit anything on the vendor directory.

Anyway I just answered to a very similar question a couple of minute ago here

Cheers

Upvotes: 0

Related Questions