Problem With View Helpers - zend-framework

I wrote few custom view helpers but I have a little trouble using them. If I add the helper path in controller action like this:
public function fooAction()
{
$this->view->addHelperPath('My/View/Helper', 'My_View_Helper');
}
Then I can use the views from that path without a problem. But when I add the path in the bootstrap file like this:
protected function _initView()
{
$this->view = new Zend_View();
$this->view->doctype('XHTML1_STRICT');
$this->view->headScript()->appendFile($this->view->baseUrl()
. '/js/jquery-ui/jquery.js');
$this->view->headMeta()->appendHttpEquiv('Content-Type',
'text/html; charset=UTF-8');
$this->view->headMeta()->appendHttpEquiv('Content-Style-Type',
'text/css');
$this->view->headMeta()->appendHttpEquiv('Content-Language', 'sk');
$this->view->headLink()->appendStylesheet($this->view->baseUrl()
. '/css/reset.css');
$this->view->addHelperPath('My/View/Helper', 'My_View_Helper');
}
Then the view helpers don't work. Why is that? It's too troublesome to add the path in every controller action. Here is an example of how my custom view helpers look:
class My_View_Helper_FooBar
{
public function fooBar() {
return 'hello world';
}
}
I use them like this in views:
<?php echo $this->fooBar(); ?>
Should I post my whole bootstrap file?
UPDATE:
Added complete bootstrap file just in case:
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initFrontController()
{
$this->frontController = Zend_Controller_Front::getInstance();
$this->frontController->addModuleDirectory(APPLICATION_PATH
. '/modules');
Zend_Controller_Action_HelperBroker::addPath(
'My/Controller/Action/Helper',
'My_Controller_Action_Helper'
);
$this->frontController->registerPlugin(new My_Controller_Plugin_Auth());
$this->frontController->setBaseUrl('/');
}
protected function _initView()
{
$this->view = new Zend_View();
$this->view->doctype('XHTML1_STRICT');
$this->view->headScript()->appendFile($this->view->baseUrl()
. '/js/jquery-ui/jquery.js');
$this->view->headMeta()->appendHttpEquiv('Content-Type',
'text/html; charset=UTF-8');
$this->view->headMeta()->appendHttpEquiv('Content-Style-Type',
'text/css');
$this->view->headMeta()->appendHttpEquiv('Content-Language', 'sk');
$this->view->headLink()->appendStylesheet($this->view->baseUrl()
. '/css/reset.css');
$this->view->addHelperPath('My/View/Helper', 'My_View_Helper');
}
protected function _initDb()
{
$this->configuration = new Zend_Config_Ini(APPLICATION_PATH
. '/configs/application.ini',
APPLICATION_ENVIRONMENT);
$this->dbAdapter = Zend_Db::factory($this->configuration->database);
Zend_Db_Table_Abstract::setDefaultAdapter($this->dbAdapter);
$stmt = new Zend_Db_Statement_Pdo($this->dbAdapter,
"SET NAMES 'utf8'");
$stmt->execute();
}
protected function _initAuth()
{
$this->auth = Zend_Auth::getInstance();
}
protected function _initCache()
{
$frontend= array('lifetime' => 7200,
'automatic_serialization' => true);
$backend= array('cache_dir' => 'cache');
$this->cache = Zend_Cache::factory('core',
'File',
$frontend,
$backend);
}
public function _initTranslate()
{
$this->translate = new Zend_Translate('Array',
BASE_PATH . '/languages/Slovak.php',
'sk_SK');
$this->translate->setLocale('sk_SK');
}
protected function _initRegistry()
{
$this->registry = Zend_Registry::getInstance();
$this->registry->configuration = $this->configuration;
$this->registry->dbAdapter = $this->dbAdapter;
$this->registry->auth = $this->auth;
$this->registry->cache = $this->cache;
$this->registry->Zend_Translate = $this->translate;
}
protected function _initUnset()
{
unset($this->frontController,
$this->view,
$this->configuration,
$this->dbAdapter,
$this->auth,
$this->cache,
$this->translate,
$this->registry);
}
protected function _initGetRidOfMagicQuotes()
{
if (get_magic_quotes_gpc()) {
function stripslashes_deep($value) {
$value = is_array($value) ?
array_map('stripslashes_deep', $value) :
stripslashes($value);
return $value;
}
$_POST = array_map('stripslashes_deep', $_POST);
$_GET = array_map('stripslashes_deep', $_GET);
$_COOKIE = array_map('stripslashes_deep', $_COOKIE);
$_REQUEST = array_map('stripslashes_deep', $_REQUEST);
}
}
public function run()
{
$frontController = Zend_Controller_Front::getInstance();
$frontController->dispatch();
}
}

Solved. I just needed to add these lines at the end of _initView() method:
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer');
$viewRenderer->setView($this->view);

I in my _initView() have something like this:
protected function _initView() {
$view = new Zend_View();
#some view initialization ...
$view->addHelperPath(APPLICATION_PATH . '/views/helpers', 'My_View_Helper');
return $view;
}
Then in a view I can execute:
<?php echo $this->fooBar(); ?>
Without APPLICATION_PATH it does not work in my case.

Just a thought: are you sure that the view that you are creating in your bootstrap ($this->view = new Zend_View();) is the same as '$this' in your view file?
I think you would need to change your initView code to the following:
protected function _initView()
{
$view = new Zend_View();
$view->doctype('XHTML1_STRICT');
$view->headScript()->appendFile($this->view->baseUrl()
. '/js/jquery-ui/jquery.js');
$view->headMeta()->appendHttpEquiv('Content-Type',
'text/html; charset=UTF-8');
$view->headMeta()->appendHttpEquiv('Content-Style-Type',
'text/css');
$view->headMeta()->appendHttpEquiv('Content-Language', 'sk');
$view->headLink()->appendStylesheet($this->view->baseUrl()
. '/css/reset.css');
$view->addHelperPath('My/View/Helper', 'My_View_Helper');
return $view;
}
If you have some View related settings in your config.ini file, you might want to change your code a little bit:
protected function _initMyView()
{
$view = $this->bootstrap('view')->getResource('view');
...
instead of:
protected function _initView()
{
$view = new Zend_View();
....

You might consider adding another init function just for your view helpers:
protected function _initViewHelpers()
{
$this->bootstrap('view');
$view = $this->getResource('view');
$view->addHelperPath('My/View/Helper', 'My_View_Helper');
}
This way the built in view setup is not overridden.

If you add only $this->view->addHelperPath('My/View/Helper', 'My_View_Helper');
in your bootstrap use this format:
class Zend_View_Helper_FooBar extends Zend_View_Helper_Abstract {
public function fooBar() {
return 'hello world';
}
}

Related

Why Zend plugin postDispatch method is not called after indexAction

When i go to controllers index URL preDispatch is called before entering indexAction method of that controller but postDispatch is not called after it. Why it is not called and should i force it somehow to call postDispatch?
I have two plugin with postDispach methods whitch are not called.
If i got to URL e.g admin/listperms postDispatch is called and everything works.
AdminController.php
class AdminController extends Application_Controllers_Base {
public function indexAction() {
$this->view->headTitle = $this->alias('TITLE_ADMIN_PANEL');
}
public function listpermsAction() {
$this->view->headTitle = $this->alias('TITLE_PERMISSION_LIST');
$permService = new Application_Services_AdminPermission();
$perms = $permService->getPermissionList();
if(!$perms) {
// TODO:
} else {
$this->view->permList = $perms;
}
}
}
Base.php
class Application_Controllers_Base extends Zend_Controller_Action {
}
DbLogPlugin.php
class Application_Plugin_DbLogPlugin extends Zend_Controller_Plugin_Abstract {
public function postDispatch(Zend_Controller_Request_Abstract $request) {
$view = Zend_Controller_Front::getInstance()->getParam('bootstrap')->getResource('view');
$view->developerLog = $this->getQuerysLogs();
}
}
bootstrap.php
protected function _initAutoload(){
$autoloader = new Zend_Application_Module_Autoloader(array(
'namespace' => 'Application_', //'
'basePath' => APPLICATION_PATH
));
$autoloader->addResourceType('dao', 'dao', 'Dao');
$autoloader->addResourceType('services', 'services', 'Services');
$autoloader->addResourceType('plugins', 'plugins', 'Plugins');
$autoloader->addResourceType('models', 'models', 'Models');
$autoloader->addResourceType('controllers', 'controllers', 'Controllers');
require_once('controllers/FrontController.php');
$front = Application_Controllers_FrontController::getInstance();
$front->setControllerDirectory(APPLICATION_PATH.'/controllers')
->setRouter(new Zend_Controller_Router_Rewrite())
->registerPlugin(new Application_Plugin_DbLogPlugin())
->registerPlugin(new Application_Plugin_AuthPlugin())
->registerPlugin(new Application_Plugin_ViewPlugin());
return $autoloader;
}

Zend Framework route/redirect

I am trying to redirect the user to a registered page once they have registered but its not doing so..
<?php
class RegisterController extends Zend_Controller_Action
{
public function init()
{
/* Initialize action controller here */
}
public function indexAction()
{
$form = new Application_Form_Register();
$form->submit->setLabel('Register');
$this->view->form = $form;
if ($this->getRequest()->isPost()) {
$formData = $this->getRequest()->getPost();
if ($form->isValid($formData)) {
$first_name = $form->getValue('first_name');
$surname = $form->getValue('surname');
$email = $form->getValue('email');
$username = $form->getValue('username');
$password = $form->getValue('password');
$is_admin = $form->getValue('is_admin');
$age = $form->getValue('age');
$gender = $form->getValue('gender');
$uni = $form->getValue('uni');
$register = new Application_Model_DbTable_Users();
$register->addUser($first_name, $surname, $email, $username, $password, $is_admin, $age, $gender, $uni);
} else {
$form->populate($formData);
}
$route = array('controller'=>'Register', 'action'=>'registered');
$this->_helper->redirector->gotoRoute($route);
}
}
public function registeredAction()
{
// action body
}
}
This is what I have
Thanks
In the controller you can to the following:
$this->_redirect('/controller/action');
I usually don't use gotoRoute() therefore I am not sure if this is the cause of your problem, but your controller-name should be all lowercased, i.e. Register should be register or maybe gotoRouteAndExit() will solve your problem (just picked it up from a quick glance at the API)
You could try an alternative: For routing between actions/controllers I find the following most convenient:
$this->_helper->redirector('registered');
Which will redirect you to registeredAction in the same controller. If you want to go to an action in a different controller, just add the controller as 2nd argument like this:
$this->_helper->redirector('registered', 'register');

Appending scripts from view helper method not working in zend framework

I have a view helper method which is like this
class Zend_View_Helper_LoginForm extends Zend_View_Helper_Abstract
{
public function loginForm()
{
$script = "<script type='text/javascript'>(function (){ $('#submit').click(function (){alert('hello'); return false;})})</script>";
$this->view->headScript()->appendScript($script, $type = 'text/javascript');
$login = new Application_Form_User();
return $login;
}
}
But this is not working. I also tried
$this->view->headScript()->appendFile($this->view->baseUrl('/js/jquery.js'), 'text/javascript');
but this is not working either. If i try this code in layout.phtml then it works.Any Idea?
In view file:
<?php $this->headScript()->appendFile('your/sript/file.js') ?>
In your layout:
<?php echo $this->headScript() ?>
You have to add setView method:
class My_View_Helper_ScriptPath
{
public $view;
public function setView(Zend_View_Interface $view)
{
$this->view = $view;
}
public function scriptPath($script)
{
return $this->view->getScriptPath($script);
}
}

Zend Framework: How to make view from bootstrap.php

For example i have echo $this->escape($this->test); in index.phtml and in controller $this->view->test = 'test message';, but i want to do this from bootstrap, becouse i want to show Form in every page (controller).
protected function _initView()
{
$this->view = new Zend_View();
$this->view->test = 'test message';
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer');
$viewRenderer->setView($this->view);
}
But I would recommend doing this in a controller plugin, not during the bootstrap:
<?php
class My_Controller_Plugin_AddSomethingToViewInAllControllerActions extends Zend_Controller_Plugin_Abstract
{
public function preDispatch()
{
$viewRenderer = Zend_Controller_Action_HelperBroker::getExistingHelper('ViewRenderer');
$viewRenderer->initView();
$view = $viewRenderer->view;
$view->test = 'test message';
}
}
sorry i made it
$view = new Zend_View;
$view->setBasePath(APPLICATION_PATH . "/views");
$view->arr = 'message';
echo $view->render('test.php');

Zend: ACL logic in View helpers

Background information:
I'm in my admin module, and I created a view helper in modules/admin/views/helpers/AdminPanel.php. I have a layout plugin that forces my view to use the layout in admin/views/layouts/default.phtml.
I'm trying to access my ACL object to determine whether or not the user has resources in the context of a view helper, and then determine whether to return the admin panel html by parsing a configs/admin-nav.xml or not return anything at all.
I'm calling it in my admin layout like so:
<?php echo $this->AdminPanel(); ?>
And the class code which is blank, which I need to access the acl object in:
class My_View_Helper_AdminPanel extends Zend_View_Helper_Abstract {
public function AdminPanel() {}
}
I tried this:
$acl = Zend_Controller_Action_HelperBroker::getStaticHelper('acl');
But this probably isn't what I'm looking for as it forces the default module's views/layouts/default.phtml to load and errors occur.
Here's my global bootstrap file:
<?php
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
private $_acl = null;
private $_auth = null;
protected function _initDoctype() {
$this->bootstrap('view');
$view = $this->getResource('view');
$view->setEncoding('UTF-8');
$view->doctype('HTML4_STRICT');
}
protected function _initAutoload() {
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->registerNamespace('KG_');
$resourceLoader = new Zend_Loader_Autoloader_Resource(
array(
'basePath' => APPLICATION_PATH,
'namespace' => '',
'resourceTypes' => array(
'form' => array(
'path' => 'forms/',
'namespace' => 'Form_'
),
'model' => array(
'path' => 'models/',
'namespace' => 'Model_'
)
)
));
return $autoloader;
}
protected function _initAclAuth() {
$this->_acl = new Model_Acl;
$this->_auth = Zend_Auth::getInstance();
}
protected function _initNav() {
$this->bootstrap('layout');
$layout = $this->getResource('layout');
$view = $layout->getView();
$config = new Zend_Config_Xml( APPLICATION_PATH . '/configs/nav.xml', 'mainNav');
$navigation = new Zend_Navigation( $config );
$fc = Zend_Controller_Front::getInstance();
$fc->registerPlugin( new KG_Controller_Plugin_Acl( $this->_acl, $this->_auth ) );
$role = $this->_auth->getStorage()->read()->role;
if ( !$role ) {
$role = 'guest';
}
$view->navigation( $navigation )->setAcl( $this->_acl)->setRole( $role );
}
protected function _initEncoding() {
$fc = Zend_Controller_Front::getInstance();
$response = new Zend_Controller_Response_Http;
$response->setHeader('Content-Type','text/html;charset=utf-8', true);
$fc->setResponse($response);
}
}
Your KG_Controller_Plugin_Acl plugin should be taking care of the access logic, not your view. If the user doesn't have access to the resource, you should error out or redirect the user to somewhere else.
The layout should be set within the controller. Preferably in the init() method with:
$this->_helper->layout->setLayout();
It looks like you followed the same or a similar tutorial as I did for Zend_Acl. I'm posting my plugin for reference, which includes the logic to handle access control from within the plugin:
class App_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract
{
protected $_auth = null;
protected $_acl = null;
public function __construct(Zend_Auth $auth, Zend_Acl $acl)
{
$this->_auth = $auth;
$this->_acl = $acl;
}
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
if ($this->_auth->hasIdentity()) {
$identity = $this->_auth->getIdentity();
$role = $identity->acl_role;
} else {
$role = 'guest';
}
// Mapping to determine which Resource the current
// request refers to (really simple for this example!)
$resource = $request->controller;
$privilege = $request->action;
if (!$this->_acl->has($resource)) {
$resource = null;
}
// ACL Access Check
if (!$this->_acl->isAllowed($role, $resource, $privilege)) {
if ($this->_auth->hasIdentity()) {
// authenticated, denied access, forward to /error/permissions
$request->setModuleName('default');
$request->setControllerName('error');
$request->setActionName('permissions');
} else {
// not authenticated, forward to login form
$request->setModuleName('default');
$request->setControllerName('auth');
$request->setActionName('login');
}
}
}
}