Zend Framework: Need advice on how to implement a controller helper - zend-framework

i need advice on how i can implement this action helper. currently, i have something like
class Application_Controller_Action_Helper_AppendParamsToUrl extends Zend_Controller_Action_Helper_Abstract {
function appendParamsToUrl($params = array()) {
$router = Zend_Controller_Front::getInstance()->getRouter();
$url = $router->assemble($params);
if (!empty($_SERVER['QUERY_STRING'])) {
$url .= $_SERVER['QUERY_STRING'];
}
return $url;
}
}
but as you can see, i think the function should be a static function? but how will that find into this Zend_Controller_Action_Helper thingy?

Make the function public and in your BootStrap.php ensure the controller helper can be autoloaded
// add paths to controller helpers
Zend_Controller_Action_HelperBroker::addPath( APPLICATION_PATH .'/controllers/helpers');
You should then be able to call the helper from your controller via
$this->_helper->appendParamsToUrl->appendParamsToUrl();

You can also rename appendParamsToUrl() function to direct()
function direct( $params = array() ) {...}
In this case, you'll be able to access it from controller with
$this->_helper->appendParamsToUrl( $params );

Related

Slim 4 get all routes into a controller without $app

I need to get all registed routes to work with into a controller.
In slim 3 it was possible to get the router with
$router = $container->get('router');
$routes = $router->getRoutes();
With $app it is easy $routes = $app->getRouteCollector()->getRoutes();
Any ideas?
If you use PHP-DI you could add a container definition and inject the object via constructor injection.
Example:
<?php
// config/container.php
use Slim\App;
use Slim\Factory\AppFactory;
use Slim\Interfaces\RouteCollectorInterface;
// ...
return [
App::class => function (ContainerInterface $container) {
AppFactory::setContainer($container);
return AppFactory::create();
},
RouteCollectorInterface::class => function (ContainerInterface $container) {
return $container->get(App::class)->getRouteCollector();
},
// ...
];
The action class:
<?php
namespace App\Action\Home;
use Psr\Http\Message\ResponseInterface;
use Slim\Http\Response;
use Slim\Http\ServerRequest;
use Slim\Interfaces\RouteCollectorInterface;
final class HomeAction
{
/**
* #var RouteCollectorInterface
*/
private $routeCollector;
public function __construct(RouteCollectorInterface $routeCollector)
{
$this->routeCollector = $routeCollector;
}
public function __invoke(ServerRequest $request, Response $response): ResponseInterface
{
$routes = $this->routeCollector->getRoutes();
// ...
}
}
This will display basic information about all routes in your app in SlimPHP 4:
$app->get('/tests/get-routes/', function ($request, $response, $args) use ($app) {
$routes = $app->getRouteCollector()->getRoutes();
foreach ($routes as $route) {
echo $route->getIdentifier() . " → ";
echo ($route->getName() ?? "(unnamed)") . " → ";
echo $route->getPattern();
echo "<br><br>";
}
return $response;
});
From there, one can use something like this to get the URL for a given route:
$routeParser = \Slim\Routing\RouteContext::fromRequest($request)->getRouteParser();
$path = $routeParser->urlFor($nameofroute, $data, $queryParams);
With the following caveats:
this will only work for named routes;
this will only work if the required route parameters are provided -- and there's no method to check whether a route takes mandatory or optional route parameters.
there's no method to get the URL for an unnamed route.

Zend pass variable from plugin to view

In plugin I try $this->view->menu = $menu; , but in view I try <?php var_dump($this->menu); ?> and get NULL
Maybe are solution to pass variable from plugin to view ?
you can use like below
First : Without using helpers or plugins do :
Zend_Layout::getMvcInstance()->assign('whatever', 'foo');
After this you can use the following in your layout:
<?php echo $this->layout()->whatever; ?>
This will print "foo".
OR
Second :
<?php
class My_Layout_Plugin extends Zend_Controller_Plugin_Abstract
{
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
$layout = Zend_Layout::getMvcInstance();
$view = $layout->getView();
$view->whatever = 'foo';
}
}
then register this plugin with the front controller, e.g.
Zend_Controller_Front::getInstance()->registerPlugin(new My_Layout_Plugin());

Hide and show navigator menu items, buttons and anchors using ACL

I am using ACL to grant resources to roles in the system, the allowed actions is excuted and denied actions are routed to custom page, I want to show and hide menu elements at run time using resources at ACL, and also I want to show and hide anchors, buttons in views.
I make a helper class
class Zend_View_Helper_Permission extends Zend_View_Helper_Abstract
{
private $_acl;
public function hasAccess($role, $action, $controller)
{
if (!$this->_acl) {
$this->_acl = Zend_Registry::get("Acl");
}
return $this->_acl->isAllowed($role, $controller, $action);
}
}
I define the view helper in config.ini file like this
resources.view.helperPath.Zend_View_Helper = APPLICATION_PATH "/modules/privileges/views/helpers"
how can I use this helper to make views created at run time?
Your method name should match class name hence it should be permission instead of hasAccess.
I myself use a global method show() instead of using view helper
function show($action = null)
{
$request = Zend_Controller_Front::getInstance()->getRequest();
$action = $action === null ? $request->getActionName() : $action;
$module = $request->getModuleName();
$controller = $request->getControllerName();
if(!Zend_Registry::isRegistered('acl')) throw new Exception('Show function can only be called inside view after preDispatch');
$acl = Zend_Registry::get('acl');
$resource = $module . '#' . $controller;
return $acl->isAllowed(Zend_Auth::getInstance()->getIdentity(),$resource,$action);
}
To keep it simple it takes controller , module name from request object .
To hide edit action link in list action view simply doo
list.phtml code as follow
<h2>Listing page Only superadmin can see edit link</h2>
<?php if(show('edit')): ?>
Edit
<?php endif;?>
Update
The global function show was defined inside library/Util.php which was loaded inside
public/index.php
require_once 'Zend/Application.php';
require_once 'Util.php';

zend, i cant call any view helpers

i have a got a helpers folder in my views folder with a helper called Log.php
/views/helpers/log.php
which contains:
class Zend_View_Helper_Log extends Zend_View_Helper_Abstract
{
public function loggedAs ()
{
$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity()) {
$username = $auth->getIdentity()->uname;
$logoutUrl = $this->view->url(array('controller'=>'auth', 'action'=>'logout'), null, true);
return 'Hello' . $username . '. Logout?';
}
}
}
how can i call this from layouts? or views? i tried $this->_helpers->log->loggedAs();
but doesnt display anything, just an error:Fatal error: Call to a member function loggedAs() on a non-object in ...
I have a little experience in ZF. Yesterday I have the same problem and I decided its with the following code.
In the main Bootstrap.php I defined helper Path and Prefix
protected function _initDoctype()
{
$this->bootstrap('view');
$view = $this->getResource('view');
$view->doctype('XHTML1_STRICT');
$view->addHelperPath(APPLICATION_PATH . "/../library/My/Helper/View", "My_Helper_View");
}
After that in view file I used next syntax
$this->getPhoneString($value['per_telephone_number']);
where getPhoneString method in my Helper Class My_Helper_View_GetPhoneString
Hope this example will be useful for you :)
Your helper class should have a method that matches the name of the helper, and this is what you call. So if you want to call loggedAs() from your templates then this is what you should name your helper:
class Zend_View_Helper_LoggedAs extends Zend_View_Helper_Abstract
{
public function loggedAs()
{
$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity()) {
$username = $auth->getIdentity()->uname;
$logoutUrl = $this->view->url(array('controller'=>'auth', 'action'=>'logout'), null, true);
return 'Hello' . $username . '. Logout?';
}
}
}
this should then live in a file at application/views/helpers/LoggedAs.php, and you'd call it from within your templates like this:
<?=$this->loggedAs()?>
I'd also recommend using your own namespace instead of Zend in the class name, but the way you've done it should work as well.

Zend: Where/how can I register custom view helpers?

In my layout.phtml file I have :
<?php echo $this->Test(); ?>
I have created a Test view helper at application/views/helpers/Test.php
<?php
class My_View_Helper_Test extends Zend_View_Helper_Abstract {
public function Test() {
return 'test';
}
}
And my config file # configs/application.ini:
resources.view[] = ''
resources.view.helperPath = APPLICATION_PATH "/views/helpers"
Error I get:
Zend_Loader_PluginLoader_Exception:
Plugin by name 'Test' was not found in
the registry; used paths:
Zend_View_Helper_:
Zend/View/Helper/:./views/helpers/ in
/usr/share/php/Zend/Loader/PluginLoader.php
on line 406
On a similar note I can't register my admin view helper either..
resources.view.helperPath.Admin_View_Helper = APPLICATION_PATH "/modules/admin/views/helpers"
My modules/admin/views/helpers/AdminPanel.php:
<?php
class My_View_Helper_AdminPanel extends Zend_View_Helper_Abstract {
public function AdminPanel() { return 'test'; }
}
Do I have no choice but to do this in the Bootstrap with addHelperPath? If so could someone demonstrate how I would using my paths?
Using application.ini is probably the best way to define these. I put all my view helpers inside my library folder:
includePaths.library = APPLICATION_PATH "/../library"
autoloadernamespaces.0 = "SNTrack_"
; -- Note, these are the only resources.view lines I have...
resources.view.doctype = "XHTML1_STRICT"
resources.view.helperPath.SNTrack_View_Helper = APPLICATION_PATH "/../library/SNTrack/View/Helper"
Directory structure:
/
application/
library/
SNTrack/
View/
Helper/
Test.php
View:
$this->test('test')
SNTrack/View/Helper/Test.php:
class SNTrack_View_Helper_Test extends Zend_View_Helper_Abstract {
public function test($args) { return $args; }
}
in my bootstrap:
$view = new Zend_View();
$view->addHelperPath(DE_Config::get('DE_appDir').DIRECTORY_SEPARATOR.'lib'.DIRECTORY_SEPARATOR.'DE'.DIRECTORY_SEPARATOR.'View'.DIRECTORY_SEPARATOR.'Helper'.DIRECTORY_SEPARATOR, 'DE_View_Helper');
$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer();
$viewRenderer->setView($view);
Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
I just had this exact problem, and realised it was due to a problem in my bootstrap: I was defining and using a new Zend_View object in one of my _init functions, which I think was overwriting all my other view settings from both my bootstrap and my application.ini file (including my resources.view.helperPath definition). The offending code had been blindly copied from here, and placed into an _initJQuery() function in my bootstrap, which looked like this:
protected function _initJQuery() {
$view = new Zend_View();
$view->addHelperPath('ZendX/JQuery/View/Helper/', 'ZendX_JQuery_View_Helper');
$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer();
$viewRenderer->setView($view);
Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
}
The solution was to replace the first line ($view = new Zend_View()) with this:
$this->bootstrap('view');
$view = $this->getResource('view');
Another thing to bare in mind, regarding your line:
resources.view.helperPath = APPLICATION_PATH "/views/helpers"
Note that this only registers the path, and not the class prefix, so this will only work if the helper classes have the default Zend class prefix of Zend_View_Helper i.e. Zend_View_Helper_Test. If you want the class to be My_View_Helper_Test, then you need to do this:
resources.view.helperPath.My_View_Helper = APPLICATION_PATH "/views/helpers"