Search code examples
phpzend-framework2

Calling Zend Plugin from View Helper class


I'm looking to call a zend plugin from a view helper class. I'm using zend 2.3. I have a job-wizard.phtml file which I need to add code for identifying a file's owner. I have a GroupFilesTable.php file which extend AbstractModelTable and has the capability to get the file's owner.

I created a view helper class called 'FileQuery'. Since I need to call getServiceLocator to access GroupFilesTable, I then created a FileQueryPlugin which FileQuery calls.

However I'm running into an error when FileQueryPlugin is called.

I tried changing FileQuery view helper from extending AbstractHelper to AbstractPluginManager, but I got errors from doing so.

From job-wizard.phtml

<?php $modifiedBy  =$this->FileQuery()->getModifiedBy('addresscleaningservice.xlsx');
?>\

From filequery.php

class FileQuery extends AbstractHelper {
    public function getModifiedBy($filename) {
        $fileQuery = $this->FileQueryPlugin();
        $owner = $fileQuery->getModifiedBy($filename);
        return $filename;
    }
}

From filequeryplugin.php

class FileQueryPlugin extends AbstractPluginManager {

    public function fileQuery($filename) {
        $fileQuery = $this->getServiceLocator->get('qatools\Model\GroupFilesTable');
        $modified = $fileQuery->getModifiedBy($filename)

        return $modified;
    }
}

Excerpts from module.config.php

'view_helpers' => array(
    'invokables'=> array(
        'MenuBuildLink' => 'qatools\View\Helper\MenuBuildLink',
        'FileQuery' => 'qatools\View\Helper\FileQuery'
    ),
),
'plugins' => array(
    'invokables' => array(
        'FileQueryPlugin' => 'qatools\Plugins\FileQueryPlugin'
    ),
),

I'm seeing this message which indicates to me that probably I haven't setup module.config.php correctly.

[26-Jul-2019 09:53:19 America/Chicago] PHP Fatal error:  Uncaught Error: Call to undefined method qatools\View\Helper\FileQuery::FileQueryPlugin() in /mnt/c/git-repos/qatools/module/qatools/src/qatools/View/Helper/FileQuery.php:9
Stack trace:
#0 /mnt/c/git-repos/qatools/module/qatools/view/partials/job-wizard.phtml(4735): qatools\View\Helper\FileQuery->getModifiedBy('addresscleaning...')
#1 /mnt/c/git-repos/qatools/vendor/zendframework/zendframework/library/Zend/View/Renderer/PhpRenderer.php(506): include('/mnt/c/git-repo...')
#2 /mnt/c/git-repos/qatools/vendor/zendframework/zendframework/library/Zend/View/Helper/Partial.php(61): Zend\View\Renderer\PhpRenderer->render(NULL, NULL)
#3 [internal function]: Zend\View\Helper\Partial->__invoke('partials/job-wi...')
#4 /mnt/c/git-repos/qatools/vendor/zendframework/zendframework/library/Zend/View/Renderer/PhpRenderer.php(399): call_user_func_array(Object(Zend\View\Helper\Partial), Array)
#5 /mnt/c/git-repos/qatools/module/qatools/view/qatools/jobs/index.phtml(1064): Zend\View\Renderer\PhpRenderer->__call('partial', Array)
 in /mnt/c/git-repos/qatools/module/qatools/src/qatools/View/Helper/FileQuery.php on line 9

Solution

  • You should change your setup of the viewhelper for the FileQuery. Inject the controller plugin into your viewhelper using dependency injection. This can be achieved by creating a factory class or callable for your FileQuery viewhelper.

    See: https://docs.zendframework.com/zend-servicemanager/configuring-the-service-manager/#factories

    In your case this would come down to module.config.php:

        'view_helpers' => array(
            'invokables'=> array(
                'MenuBuildLink' => 'qatools\View\Helper\MenuBuildLink',
            ),
            'factories' => array(
                'FileQuery' => function ($container, $requestedName) {
                    # Using an older version of Zend - the container is the ViewHelperManager and not the main ServiceManager so getServiceLocator() should be called.
                    # return new \qatools\View\Helper\FileQuery($container->getServiceLocator()->get(\Zend\Mvc\Controller\PluginManager::class)->get('FileQueryPlugin')));
                    return new $requestedName($container->get(\Zend\Mvc\Controller\PluginManager::class)->get('FileQueryPlugin'));
                },
            ),
        ),
        'plugins' => array(
            'invokables' => array(
                'FileQueryPlugin' => 'qatools\Plugins\FileQueryPlugin'
            ),
        ),
    

    Or as the documentation explains is that you can create a Factory class which creates a new viewhelper.

    And update your viewhelper so that it accepts the FileQueryPlugin in the constructor.

    class FileQuery extends AbstractHelper {
    
        protected $fileQueryPlugin;
    
        public function __construct(FileQueryPlugin $fileQueryPlugin)
        {
            $this->fileQueryPlugin = $fileQueryPlugin;
        }
    
        public function getModifiedBy($filename) 
        {
            return $this->fileQueryPlugin->getModifiedBy($filename);
        }
    }