Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
297 views
in Technique[技术] by (71.8m points)

zend framework2 - ZF2, what's the best practice for working with Vendor Module's Form classes?

How should I apply custom styles to Vendor Module's Form or embed it on my own View script? More specifically I want to work with forms provided by EdpUser Module (https://github.com/EvanDotPro/EdpUser).

The easiest way seems to be modifying the vendor's script directly. But obviously this will conflict with vendor's future updates.

Another way seems to be copying Vendor's Controller into my own Module then provide my own views. However this suffers a similar issue of getting out of sync with Vendor's future updates. And I will have to be careful with namespace.

Maybe I should extend Vendor's Controller instead of copying it. This should work well with namespaces and I should be able to access the Forms within my Controller quite easily. While using my own view scripts. Is this the right way or is there a better one?

Thanks

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

It is not the recommended approach to modify anything in the module's directory, especially those modules put in /vendor/. This is also the reason configuration templates must be copied to your own /config/autoload/ directory.

A module must provide sufficient extension points to make it flexible enough for your usage. Among those possibilities are the following options:

Change a route

The ZfcUser module registers itself under the /user url. If you want to change that into /account for example, you can simply add this to your configuration:

<?php
return array(
    'di' => array(
        'instance' => array(
            'ZendMvcRouterRouteStack' => array(
                'parameters' => array(
                    'routes' => array(
                        'zfcuser' => array(
                            'options' => array(
                                'route' => '/account',
                            ),
                        ),
                    ),
                ),
            ),
        ),
    ),
);

Change a controller

If you are not happy the ZfcUserControllerUserController is used and you want to override some action in this controller, you can create a custom controller, for example MyUserControllerUserController. If you extend the ZfcUserControllerUserController and provide this configuration, you are ready to go:

<?php
return array(
    'di' => array(
        'instance' => array(
            'ZendMvcRouterRouteStack' => array(
                'parameters' => array(
                    'routes' => array(
                        'zfcuser' => array(
                            'options' => array(
                                'defaults' => array(
                                    'controller' => 'MyUserControllerUserController'
                                ),
                            ),
                        ),
                    ),
                ),
            ),
        ),
    ),
);

You can also use DI aliasing to override the zfcuser alias in your DI configuration:

<?php
return array(
    'di' => array(
        'instance' => array(
            'alias' => array(
                'zfcuser' => 'MyUserControllerUserController'
            ),
        ),
    ),
);

Modify the form instance

For example the ZfcUser module triggers several events to help other modules hook into the form creation process. Both the ZfcUserFormLogin as ZfcUserFormRegister trigger an init event after they set up all form elements. This gives you the chance to add or remove elements.

use ZendEventManagerStaticEventManager;

$events = StaticEventManager::getInstance();
$events->attach('ZfcUserFormLogin', 'init', function ($e) {
  $form = $e->getTarget();
  $form->addElement('text', 'something-new');
});

I need to make two remarks here:

  1. Every module must provide its own triggers. This ZfcUser has the init on both forms, but this is not a given for every module. You must look into the documentation or source code to find out about this.
  2. The ZendEventManager is currently under a refactoring to replace the singleton StaticEventManager by a SharedEventManager instance which can be instantiated through the ZendDi locator. You can watch the progress of this refactoring in this Pull Request.

Change a view or form rendering

As per this RFC the ZendForm component is likely to change. Especially for the rendering, the decorators will be removed and "just" normal view helpers will render the form instead. With this given, plus the possibility to override views, it is very easy to change the rendering of an action just by using another module with only some view scripts.

If you create your own module and provide this configuration, you add a new location to the template path stack:

<?php
return array(
    'di' => array(
        'instance' => array(
            'ZendViewResolverTemplatePathStack' => array(
                'parameters' => array(
                    'paths' => array(
                        'myuser' => __DIR__ . '/../view',
                    ),
                ),
            ),
        ),
    ),
);

Now you can create view scripts in your module's view directory. If you have your module called "MyUser" and located under /modules/MyUser and you want to override the login view script from ZfcUser (located in /vendor/ZfcUser/view/zfcuser/login.phtml, create your view script in /modules/MyUser/view/zfcuser/login.phtml.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...