I am trying to make a stand alone Zend Form with a custom form element. I need use custom view helper to create this element. How do I register a custom view helper path without an application.ini file?
set_include_path(
implode(PATH_SEPARATOR, array(
get_include_path(),
PATH_TO_ZF_LIBRARY
)));
require_once 'Zend/Loader/Autoloader.php';
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->registerNamespace( 'My' );
$form = new Zend_Form;
... create and add zend form elements here
//display form
echo $form->render(new Zend_View());
Also, will the custom Zend_Form_Element know to look for the custom helper in the new path? According to the docs all I have to do is create public $helper var with the class name of the view helper. But I can't figure out if that will work with a custom view helper.
class My_Form_Element_Ssn extends Zend_Form_Element_Xhtml
{
public $helper = 'ssnElement';
public function setValue()
{
}
public function getValue()
{
return '12345';
}
}
class My_View_Helper_SsnElement
extends Zend_View_Helper_FormElement
{
public function ssnElement( $name, $value = null, $attribs = null )
{
return 'SSN';
}
}
I thank you in advance for your assistance.
Try:
$view = new Zend_View();
$view->addHelperPath('/path/to/My/View/Helper', 'My_View_Helper');
echo $form->render($view);
Related
I want to pass some value from controller to view partial, basically, view partial is set using the placeholder in Application\Module.php, here is the code that does it.
<?php
namespace Application;
use Zend\Mvc\ModuleRouteListener;
use Zend\Mvc\MvcEvent;
use Zend\View\Renderer\PhpRenderer;
use Zend\View\Resolver;
use Zend\ServiceManager\ServiceManager;
class Module
{
public function onBootstrap(MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$eventManager->attach(\Zend\Mvc\MvcEvent::EVENT_DISPATCH, array($this, 'initBreadcrumbAndActionButtonWidget'));
$moduleRouteListener->attach($eventManager);
$serviceManager = $e->getApplication()->getServiceManager();
}
public function initBreadcrumbAndActionButtonWidget(\Zend\Mvc\MvcEvent $e)
{
$serviceManager = $e->getApplication()->getServiceManager();
$config = $serviceManager->get('config');
$viewHelperManager = $this->getViewHelperManager($e->getApplication()->getServiceManager());
$partialHelper = $viewHelperManager->get('partial');
$partial = $partialHelper('widgets/breadcrumb', array(
'config' => $config,
'actionButtons' => $config['action-buttons']
));
$placeHolder = $viewHelperManager->get('placeholder');
$placeHolder('widgets/breadcrumb')->set($partial);
}
public function getViewHelperManager($serviceManager)
{
$stack = new Resolver\TemplatePathStack(array('script_paths' => array(__DIR__ . '/view/')));
$resolver = new Resolver\AggregateResolver();
$resolver->attach($stack);
$renderer = new PhpRenderer();
$renderer->setResolver($resolver);
$viewHelperManager = $serviceManager->get('ViewHelperManager');
return $viewHelperManager;
}
public function getConfig()
{
return array_merge_recursive(
include __DIR__ . '/config/module.config.php',
);
}
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
),
),
);
}
}
It is all working good till here, however now i want to pass a value from controller to the partial widgets/breadcrumb, after several attempt i thought implementing a ViewHelper could be a solution, and i implemented following view helper.
<?php
namespace Application\View\Helper;
use Zend\View\Helper\AbstractHelper;
class Variable extends AbstractHelper
{
protected $data;
public function __invoke()
{
return $this;
}
public function set($identifier, $data)
{
$this->data[$identifier] = $data;
return $this;
}
public function get($identifier)
{
return $this->data[$identifier];
}
}
In controller i assign the value to ViewHelper like this.
$viewHelperManager = $this->getServiceLocator()->get('ViewHelperManager');
$variable = $viewHelperManager->get('variable');
$variable->set('stack', 'overflow');
And in partial, to access the value i use the get method.
$this->variable()->get('stack');
Now my problem is that get() is rendered first hence the value set in controller has no effect.
My question is how can i make the set() gets rendered first so i can have the value in partial, or if there is any better approach of passing the value to partial please suggest.
Thanks.
Baaah, i called the view helper in wrong action, it worked when i moved the $variable->set('stack', 'overflow'); in the action where i wanted the value to pass.
Not sure if there can be a better solution, but this does the job for me to pass the value after i found no way in ZF2 that satisfies my requirement.
Maybe it will be a very lame question, but i just try.
I built my own MVC framework.
In the controller, i am creating a new object, called $Object.
Object class has a private property $id, and a getter getId();
In the controller, i am creating a new View(), what is loading a template file.
So my controllers seems like this:
$View = new View('templateFile.php');
$View->Object = new Object();
$View->show();
If i am editing this in the controller, when typing $View->Object->ge... netbeans automatically try to autocomplete it to getId or offers all methods what starts with "ge".
Cool.
I am editing the template file, where the $this is the View object.
When i type, $this-> and CTLR+Space, there are no suggession.
Is it possible to earn this somehow?
That could be a dream, if i could do this with $this->Object-> and CTRL+Space.
Here are my important pieces of my View class:
public function show() {
echo $this->getViewContent();
}
public function getViewContent() {
$container = null;
$defaultViewHeader = '';
if ($this->showDefaultViewHeader) {
if (file_exists($this->viewsDir . $this->defaultViewHeaderFile)) {
$defaultViewHeader = $this->getContent($this->viewsDir . $this->defaultViewHeaderFile);
} else {
$defaultViewHeader = $this->getContent($this->commonDir . $this->defaultViewHeaderFile);
}
}
$pageContent = $this->getContent($this->file);
if ($this->showDefaultViewHeader) {
$pageContent = $defaultViewHeader . $pageContent;
}
if ($this->showContainer) {
$container = $this->getContent($this->viewsDir . $this->containerFile);
$pageContent = str_replace('[' . HTD_PAGECONTENT . ']', $pageContent, $container);
}
return $pageContent;
}
public function getContent($file) {
ob_start();
include ($file);
$content = ob_get_contents();
ob_end_clean();
return $content;
}
You could specify a variable type to netbeans using the "var" annotation.
Try to add this line into your template :
/* #var $this View */
More on this here https://blogs.oracle.com/netbeansphp/entry/defining_a_variable_type_in
I have made module Admin. In this module, in controller I have called form
class Admin_AdminController extends Zend_Controller_Action
{
public function indexAction()
{
//$form = new Application_Form_Login();
$form = new Admin_Form_Admin();
$this->view->form = $form;
}
}
But In controller its giving error -> Class 'Admin_Form_Admin' not found in application\modules\Admin\controllers\AdminController.php
My forms is in application\modules\Admin\forms\Admin.php.Below is my form code
class Admin_Form_Admin extends Zend_Form
{
public function init()
{
this->setMethod('post');
/* Form Elements & Other Definitions Here ... */
$user = $this ->CreateElement('text','username');
$password = $this->createElement('text','password');
$login = $this->createElement('submit','button');
$this->addElements(array($user,
$password,
$login
));
}
}
Three things are required here...
You need to bootstrap the modules resource
; application.ini
resources.modules[] =
You need to set the modules directory in your front controller
; application.ini
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
You need a bootstrap class in your admin module
<?php
// application/modules/Admin/Bootstrap.php
class Admin_Bootstrap extends Zend_Application_Module_Bootstrap {}
With these three things in place, your code should work as-is.
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');
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';
}
}