Extending Zend\\View\\Helper\\Url in Zend Framework 2

人盡茶涼 提交于 2019-12-06 03:10:34

Not tested this so I don't know if it works, I am just guessing:

Replace:

$viewHelperManager->setInvokableClass('url', 'MyNamespace\View\Helper\Url');

with:

$viewHelperManager->setFactory('url', function ($sm) use($serviceLocator) {
    $helper = new \MyNamespace\View\Helper\Url;
    $router = Console::isConsole() ? 'HttpRouter' : 'Router';
    $helper->setRouter($serviceLocator->get($router));

    $match = $serviceLocator->get('application')
    ->getMvcEvent()
    ->getRouteMatch();

    if ($match instanceof RouteMatch) {
        $helper->setRouteMatch($match);
    }

    return $helper;
});

You can also use initializers!

'view_helpers' => array(
    'invokables' => array(
        'MyUrl' => 'MyModule\View\Helper\MyUrl'
    ),
    'initializers' => array(
        function ($instance, $sm) {
            if ($instance instanceof \Zend\View\Helper\Url) {
                $serviceLocator = $sm->getServiceLocator();

                $router = \Zend\Console\Console::isConsole() ? 'HttpRouter' : 'Router';
                $instance->setRouter($serviceLocator->get($router));

                $match = $serviceLocator->get('application')
                    ->getMvcEvent()
                    ->getRouteMatch();

                if ($match instanceof RouteMatch) {
                    $instance->setRouteMatch($match);
                }
            }
        }
    )
)

And You can extend \Zend\View\Helper\Url as You want it

namespace MyModule\View\Helper;

use Zend\View\Helper\Url as ZendUrl;

class MyUrl extends ZendUrl {

    public function __invoke() {
        return parent::__invoke('MyRoute');
    }

}

Though this questions is quite old, figured it might be worth adding a configuration based override here as well using a factory registered with the HelperPluginManager:

Inside the module.config.php:

'view_helpers' => array(
    'factories'=> array(
        'url' => 'Application\View\Helper\UrlFactory',
    )
),

And the view helper plugin factory itself:

<?php

namespace Application\View\Helper;

use Zend\Console\Console;
use Zend\Mvc\Router\RouteMatch;
use Zend\Mvc\Router\RouteStackInterface;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\View\Helper\Url as BaseUrlHelper;
use Zend\View\HelperPluginManager;

class UrlFactory implements FactoryInterface
{
    /**
     * Create service
     *
     * @param ServiceLocatorInterface $helperPluginManager
     * @return mixed
     */
    public function createService(ServiceLocatorInterface $helperPluginManager)
    {
        /**
         * @var $helperPluginManager HelperPluginManager
         * @var $router RouteStackInterface
         */
        $serviceLocator = $helperPluginManager->getServiceLocator();
        $helper = new Url();

        $router = Console::isConsole() ? 'HttpRouter' : 'Router';
        $router = $serviceLocator->get($router);
        $helper->setRouter($router);

        $match = $serviceLocator->get('application')
            ->getMvcEvent()
            ->getRouteMatch()
        ;

        if ($match instanceof RouteMatch) {
            $helper->setRouteMatch($match);
        }

        return $helper;
    }
}

The trick here really is that in this factory, one only receives the HelperPluginManager service locator. To access other services, one needs to fetch the global service locator first (which is done by the useing the global service locator from outside the closure in all other solutions).

Aydin's solution worked for me, I put the code, more or less untouched in the getViewHelperConfig of the module.php

public function getViewHelperConfig()
{
    return array(
        'invokables' => array(
            .....
        ),
        'factories' => array(
            'modalurl'            => function ($helperPluginManager) {
                $serviceLocator = $helperPluginManager->getServiceLocator();
                $view_helper =  new \Application\View\Helper\ModalUrl();
                $router = \Zend\Console\Console::isConsole() ? 'HttpRouter' : 'Router';
                $view_helper->setRouter($serviceLocator->get($router));

                $match = $serviceLocator->get('application')
                    ->getMvcEvent()
                    ->getRouteMatch();

                if ($match instanceof RouteMatch) {
                    $view_helper->setRouteMatch($match);
                }

                return $view_helper;
            }
        ),
    );
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!