2

Zend\Navigationカスタムルーターがあり、このカスタムルーターの内部にアクセスする必要があります。私はグーグル、質問、検索をしていましたが、結果はありませんでした:/

必要なのは、Alias::match関数でZend\Navigationを使用して、「link」パラメータを持つノードを見つけることだけです。

これが私のmodule.config.phpです:

'navigation' => array(
        'default' => array(
            'account' => array(
                'label' => 'Account',
                'route' => 'node',
                'pages' => array(
                    'home' => array(
                        'label' => 'Dashboard',
                        'route' => 'node',
                        'params' => array(
                                    'id' => '1',
                                    'link' => '/about/gallery'
                                    ),
                    ),
                ),
            ),
        ),
    ),
[...]

そして、これが私のAliasクラスです。

// file within ModuleName/src/ModuleName/Router/Alias.php
namespace Application\Router;

use Traversable;
use Zend\Mvc\Router\Exception;
use Zend\Stdlib\ArrayUtils;
use Zend\Stdlib\RequestInterface as Request;
use Zend\Mvc\Router\Http;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

class Alias extends Http\Segment implements ServiceLocatorAwareInterface
{

    public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
    {
        $this->serviceLocator = $serviceLocator;
        return $this;
    }

    public function getServiceLocator()
    {
        return $this->serviceLocator;
    }

    public function match(Request $request, $pathOffset = null)
    {
        [...]

        return parent::match($request, $pathOffset);        
    }

}

編集:

これで、カスタムルーターにサービスマネージャーを挿入する必要があることがわかりました。あなたがこれを行う方法を知っているかどうか私に知らせてください:)

編集:

わかりました、カスタムルーターではなくルートです。私の悪い。私は#zftalkircchanellについて話していましたが、AliasSegmentクラスは実装する必要がありますServiceLocatorAwareInterface。試してみましたが、別の問題があります。

setServiceLocator関数では取得できませんservice locator。nullオブジェクトを返します$serviceLocatorが、クラスZend\Mvc\Router\RoutePluginManagerです。

public function setServiceLocator(ServiceLocatorInterface $serviceLocator){
    $sl = $serviceLocator->getServiceLocator();
    var_dump($sl); // NULL
}

それからZendナビゲーションを取得する方法はありますか?

編集済み

@mmmshuddupの発言に対応して、カスタムルータークラスを変更しました。(新しいバージョンは上にあります)。また、関数Module.php内で、次の行を追加しました。onBootstrap

$sm->setFactory('Navigation', 'Zend\Navigation\Service\DefaultNavigationFactory', true);

ナビゲーションは機能し、以前にインスタンス化されrouteているため、Aliasクラス内に表示されるはずですが、そうではありません。

この行をクラスのmatch関数に入れました:Alias

$servicesArray = $this->getServiceLocator()->getRegisteredServices();

そして$servicesArrayほとんど空です。サービスも工場もありません。onBootstrap(上記のように)新しいファクトリを設定した直後に挿入された同じ行は、navigationおよび他のサービスで配列を返します。

問題は、このアレイ(またはServiceManager)をカスタムルーターと共有するにはどうすればよいAliasですか?

私がやりたいのはZF1で可能で、とても簡単だったと言わざるを得ません。

編集

私は解決策を見つけました。答えは以下の通りです

4

2 に答える 2

2

これは、オブジェクト自体に実際に宣言されたプロパティがないためです。しかし、これを行う場合:

echo get_class($sl);

あなたはそれが確かにのインスタンスであることがわかりますZend\ServiceManager\ServiceManager

次のような操作を行うことで、ナビゲーションインスタンスを取得できるはずです。

$nav = $sl->get('Navigation');

編集:

コードの間違った場所に何かがあることに気づきました。あなたはすでにそのインスタンスであるものを呼び出しgetServiceLocator() ています。 $serviceLocatorまた、あなたはそれを内で呼んでいますsetServiceLocator()。次のように変更する必要があります。

// EDIT - file within ModuleName/src/Router/Alias.php
namespace Application\Router;

use Traversable;
use Zend\Mvc\Router\Exception;
use Zend\Stdlib\ArrayUtils;
use Zend\Stdlib\RequestInterface as Request;
use Zend\Mvc\Router\Http;

class Alias extends Http\Segment implements ServiceLocatorAwareInterface
{
    public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
    {
        $this->serviceLocator = $serviceLocator;
        return $this;
    }

    public function getServiceLocator()
    {
        return $this->serviceLocator;
    }

    public function match(Request $request, $pathOffset = null)
    {
        $nav = $this->getServiceLocator()->get('Navigation');
        // ...
        return parent::match($request, $pathOffset);
    }
}
于 2012-11-10T22:15:26.750 に答える
1

私は解決策を見つけましたが、これは私が思うエレガントな解決策ではありません。ただし、すべてが完全に機能します。このソリューションの欠点を誰かが知っている場合は、この回答にコメントするか、別の回答を追加してください。@mmmshuddupのアイデアを変更する必要がありました(会話を読むことができます)。

まず第一にServiceLocatorAwareInterface、カスタムルートクラスでの実装はもう必要ありません。

関数Module.phponBootstrap

    $app = $e->getApplication();
    $sm  = $app->getServiceManager();
    $sm->get('translator');
    $eventManager        = $e->getApplication()->getEventManager();
    $moduleRouteListener = new ModuleRouteListener();
    $moduleRouteListener->attach($eventManager);

    $sm->setFactory('Navigation', 
                    'Zend\Navigation\Service\DefaultNavigationFactory', true);

    $nav = $sm->get('Navigation');
    $alias = $sm->get('Application\Router\Alias');
    $alias->setNavigation($nav);

最初にNavigationファクトリをインスタンス化しServiceManager、次にカスタムルートをインスタンス化します。その後、setNavigation関数を使用してナビゲーションクラスをカスタムルートに渡すことができます。カスタムルートのインスタンス化を完了するにgetServiceConfigは、同じファイルに必要です。

    return array(
        'factories' => array(
            'Application\Router\Alias' => function($sm) {
                $alias = new \Application\Router\Alias('/node[/:id]');
                return $alias;
            },
            'db_adapter' =>  function($sm) {
                $config = $sm->get('Configuration');
                $dbAdapter = new \Zend\Db\Adapter\Adapter($config['db']);
                return $dbAdapter;
            },
        )
    );

そして、ここにトリッキーな部分があります。このインスタンスは一時的なものです。ルーティング中に、このクラスはもう一度インスタンス化されるため、あまりエレガントではないと思います。パラメーターをコンストラクターに挿入する必要がありますが、現時点では、このパラメーターの値は重要ではありません。

カスタムルートクラス:

// file within ModuleName/src/ModuleName/Router/Alias.php
namespace Application\Router;

use Traversable;
use Zend\Mvc\Router\Exception;
use Zend\Stdlib\ArrayUtils;
use Zend\Stdlib\RequestInterface as Request;
use Zend\Mvc\Router\Http;

class Alias extends Http\Segment
{

    private static $_navigation = null;

    public function match(Request $request, $pathOffset = null)
    {
        //some logic here

        //get Navigation
        $nav = self::$_navigation;

        return parent::match($request, $pathOffset);
    }

    public function setNavigation($navigation){
        self::$_navigation = $navigation;
    }

}

最初のインスタンスは一時的なものであるためNavigation、静的変数にクラスを収集する必要があります。それはひどいですが、うまく機能します。たぶんそれを一度だけインスタンス化する方法があり、ルート構成でそのインスタンスを取得しますが、現時点ではこれが私の質問に対する最良の答えです。簡単に言えば、正しく機能しています。

于 2012-11-11T14:36:26.107 に答える