zend, i cant call any view helpers - zend-framework

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.

Related

zfcuser add user role after registration

I'm using Zend Framework 2 with ZfcUser, BjyAuthorize and Doctrine for the database. Registration etc. works very well so far. My problem is, that registered users have no role assigned, so i want to add the role "user" to the user during registration.
I think i could attach this to the "register" event, but i don't know how to do that.
I hope someone can help me ...
(i used this tutorial for setting up zfcuser etc. http://samminds.com/2013/03/zfcuser-bjyauthorize-and-doctrine-working-together/)
public function onBootstrap(MvcEvent $e)
{
$zfcServiceEvents = $e->getApplication()->getServiceManager()->get('zfcuser_user_service')->getEventManager();
$zfcServiceEvents->attach('register', function($e) {
$user = $e->getParam('user');
// probably the role must be added here, with $user->addRole();
// but how do i get the user Role Entity to add from DB?
});
Building on DangelZM's answer, and using another reference (see link at end of my post) about the Event Manager, I came up with this solution which organizes the potential ZfcUser event listeners out into a user listener object.
Note: I created my own user module called NvUser, so depending on the name of your module you'll have to replace all references of NvUser to your user module name.
Summary
I created an NvUserListener object that can itself attach event listeners to the shared event manager, and house the event listener callbacks.
Inside NvUser/Module.php:
<?php
namespace NvUser;
use Zend\Mvc\MvcEvent;
use NvUser\Listener\NvUserListener;
class Module
{
public function onBootstrap(MvcEvent $mvcEvent)
{
$em = $mvcEvent->getApplication()->getEventManager();
$em->attach(new NvUserListener());
}
}
Inside NvUser/src/NvUser/Listener/NvUserListener.php:
<?php
namespace NvUser\Listener;
use Zend\EventManager\AbstractListenerAggregate;
use Zend\EventManager\EventManagerInterface;
use Zend\EventManager\Event;
class NvUserListener extends AbstractListenerAggregate
{
public function attach(EventManagerInterface $events)
{
$sharedManager = $events->getSharedManager();
$this->listeners[] = $sharedManager->attach('ZfcUser\Service\User', 'register', array($this, 'onRegister'));
$this->listeners[] = $sharedManager->attach('ZfcUser\Service\User', 'register.post', array($this, 'onRegisterPost'));
}
public function onRegister(Event $e)
{
$sm = $e->getTarget()->getServiceManager();
$em = $sm->get('doctrine.entitymanager.orm_default');
$user = $e->getParam('user');
$config = $sm->get('config');
$criteria = array('roleId' => $config['zfcuser']['new_user_default_role']);
$defaultUserRole = $em->getRepository('NvUser\Entity\Role')->findOneBy($criteria);
if ($defaultUserRole !== null)
{
$user->addRole($defaultUserRole);
}
}
public function onRegisterPost(Event $e)
{
$user = $e->getParam('user');
$form = $e->getParam('form');
// Do something after user has registered
}
}
Inside NvUser/config/module.config.php:
<?php
namespace NvUser;
return array(
'zfcuser' => array(
'new_user_default_role' => 'user',
),
);
References:
Understanding the Zend Framework 2 Event Manager
Maybe it's not the best solution, but it works for me.
Add user_role_id option in config scope.
public function onBootstrap(MvcEvent $mvcEvent)
{
$zfcServiceEvents = $mvcEvent->getApplication()->getServiceManager()->get('zfcuser_user_service')->getEventManager();
$zfcServiceEvents->attach('register', function($e) use($mvcEvent) {
$user = $e->getParam('user');
$em = $mvcEvent->getApplication()->getServiceManager()->get('doctrine.entitymanager.orm_default');
$config = $mvcEvent->getApplication()->getServiceManager()->get('config');
$defaultUserRole = $em->getRepository('SamUser\Entity\Role')->find($config['user_role_id']);
$user->addRole($defaultUserRole);
});
}
Maybe someone will offer better solution.
This work too.
public function onBootstrap(MvcEvent $mvcEvent)
{
$zfcServiceEvents = $mvcEvent->getApplication()-getServiceManager()->get('zfcuser_user_service')->getEventManager();
$zfcServiceEvents->attach('register', function($e) use($mvcEvent) {
$user = $e->getParam('user');
$em = $mvcEvent->getApplication()->getServiceManager()-get('doctrine.entitymanager.orm_default');
$defaultUserRole = $em->getRepository('SamUser\Entity\Role')-find('id_of_your_role_on_table_role_for_example: '2'');
$user->addRole($defaultUserRole);
});
}
I just used a MySQL trigger
DROP TRIGGER IF EXISTS `user_role_after_insert_trig`;
DELIMITER //
CREATE TRIGGER `user_role_after_insert_trig` AFTER INSERT ON `user`
FOR EACH ROW begin
insert into user_role_linker (user_id,role_id) values (new.user_id, 5);
end
//
DELIMITER ;

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';

How do I combine Zend_Ath, Zend_Acl and partialview for the authentication and resource control

According to Randomness will get you everywhere.
Ryan’s Blog
the action stack component of Zend Framework is un-needed and that a partial view can be combined with Zend_Acl and Zend_Auth for the purpose of authenticating and controlling resources.
I have not been able to find any suitable example on google about how its done. Will be glad is someone will be kind to show me how to implement this. Thanks
Here you go:
You could use the combination of Zend_Auth and Zend_Acl. To extend the other answers I give a short example of how you can manage authentication using zend framework:
First you need to setup a plugin to predispatch all requests and check if the client is allowed to access certain data. This plugin might look like this one:
class Plugin_AccessCheck extends Zend_Controller_Plugin_Abstract {
private $_acl = null;
public function __construct(Zend_Acl $acl) {
$this->_acl = $acl;
}
public function preDispatch(Zend_Controller_Request_Abstract $request) {
//get request information
$module = $request->getModuleName ();
$resource = $request->getControllerName ();
$action = $request->getActionName ();
try {
if(!$this->_acl->isAllowed(Zend_Registry::get('role'),
$module . ':' . $resource, $action)){
$request->setControllerName ('authentication')
->setActionName ('login');
}
}catch(Zend_Acl_Exception $e) {
$request->setControllerName('index')->setActionName ('uups');
}
}
}
So every user type has certain permissions that you define in your acl library. On every request you check if the user is allowed to access a resource. If not you redirect to login page, else the preDispatch passes the user to the resource.
In Zend_Acl you define roles, resources and permission, that allow or deny access, e.g.:
class Model_LibraryAcl extends Zend_Acl {
public function __construct() {
$this->addRole(new Zend_Acl_Role('guests'));
$this->addRole(new Zend_Acl_Role('users'), 'guests');
$this->addRole(new Zend_Acl_Role('admins'), 'users');
$this->add(new Zend_Acl_Resource('default'))
->add(new Zend_Acl_Resource('default:authentication'), 'default')
->add(new Zend_Acl_Resource('default:index'), 'default')
->add(new Zend_Acl_Resource('default:error'), 'default');
$this->allow('guests', 'default:authentication', array('login'));
$this->allow('guests', 'default:error', 'error');
$this->allow('users', 'default:authentication', 'logout');
}
}
Then you have to setup acl and auth in your bootstrap file:
private $_acl = null;
protected function _initAutoload() {
//...your code
if (Zend_Auth::getInstance()->hasIdentity()){
Zend_Registry::set ('role',
Zend_Auth::getInstance()->getStorage()
->read()
->role);
}else{
Zend_Registry::set('role', 'guests');
}
$this->_acl = new Model_LibraryAcl ();
$fc = Zend_Controller_Front::getInstance ();
$fc->registerPlugin ( new Plugin_AccessCheck ( $this->_acl ) );
return $modelLoader;
}
Finally in your authentication controller you have to use a custom auth adapter and setup actions for login and logout:
public function logoutAction() {
Zend_Auth::getInstance ()->clearIdentity ();
$this->_redirect ( 'index/index' );
}
private function getAuthAdapter() {
$authAdapter = new Zend_Auth_Adapter_DbTable (
Zend_Db_Table::getDefaultAdapter ());
$authAdapter->setTableName('users')
->setIdentityColumn('email')
->setCredentialColumn ('password')
->setCredentialTreatment ('SHA1(CONCAT(?,salt))');
return $authAdapter;
}
In your login action you need to pass login data to the auth adapter which performs the authentication.
$authAdapter = $this->getAuthAdapter ();
$authAdapter->setIdentity ( $username )->setCredential ( $password );
$auth = Zend_Auth::getInstance ();
$result = $auth->authenticate ( $authAdapter );
if ($result->isValid ()) {
$identity = $authAdapter->getResultRowObject ();
if ($identity->approved == 'true') {
$authStorage = $auth->getStorage ();
$authStorage->write ( $identity );
$this->_redirect ( 'index/index' );
} else {
$this->_redirect ( 'authentication/login' );
}
And that's all. I recommend you this HOW TO on youtube on zend auth and zend acl.
You may find the following articles on Action Helpers useful, I recommend browsing the sites if any are new to you as they also have articles on implementing Zend_Auth:
Using Action Helpers To Implement Re-Usable Widgets by Matthew Weier O'Phinney
Introducing Action Helpers by Jon Lebensold
Using Action Helpers in Zend Framework by Rob Allen
ZF Reference Guide: Action Helpers Official Documentation

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

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 );

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"