Zend overwrite default view object - zend-framework

How can I overwrite the default view object in zend framework so I could have the custom one?
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap {
function _initViewHelpers() {
$this->bootstrap('view');
$view = $this->getResource('view');
$view->doctype('HTML4_STRICT');
$view->setHelperPath(APPLICATION_PATH . '/helpers', '');
$view->headMeta()->appendHttpEquiv('Content-type', 'text/html;charset=utf-8')
->appendName('description', 'Zend Framework');
$view->headTitle()->setSeparator(' - ');
$view->headTitle('Zend Custom View');
$view->setScriptPath(APPLICATION_PATH . '/themes/admin');
return $view;
}
}
The default view contains default script path for module. I want one path for all modules, to enable template system. The setScriptPath method should overwrite the default path generated by the view object, but it doesn't.
array(2) { [0]=> string(66) "C:/xampp/htdocs/NEOBBS_v6/application/modules/admin/views\scripts/" [1]=> string(51) "C:\xampp\htdocs\NEOBBS_v6\application/themes/admin/" }
it has two scriptPaths. Can this be done by overwriting the default view object?

What ArneRie posted is correct, however the ViewRenderer checks to see whether the standard script path is set and adds it if not. Since the paths are checked LIFO, what's happening is that the ViewRenderer is adding the standard path after your one and then always using that one.
What worked for me was to set both the standard path and my custom path at the same time, with the custom one being last, something like:
$view->setScriptPath(array(
APPLICATION_PATH . '/views/scripts/', // or whatever the standard path is
APPLICATION_PATH . '/themes/admin'
));
there may be a better solution for this though.

Try to add:
$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer();
$viewRenderer->setView($view);
Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);

Related

change script path calling view action helper

I want to create different view scripts for each modules in my application. My structure look like that:
-- application
-- modules
-- default
-- views
-- default
-- scripts
-- fluid
--scripts
I set default script path in Zend Controller Plugin, which preDispatch() is executed with the request:
$view->setScriptPath(sprintf('%s/modules/%s/views/%s/scripts', APPLICATION_PATH, $module, $views));
Everything works great until i call action from view:
$this->action('activity-stream', 'index', 'observation');
Application throws an exception with message:
script 'index/activity-stream.phtml' not found in path (C:/wamp/www/erp/application/modules/observation/views\scripts/;C:\wamp\www\erp\application/modules/user/views/fluid/scripts/)
Looks like, when calling module with View Action Helper, script path is not set properly. Any idea how to achieve that?
Problem not solved, but i dit what i want in a different way. Each controller within any module of my application inherits my custom action controller that inherits Zend_Controller_Action. Inside that custom controller i have something like this:
public function init() {
parent::init();
$module = $this->_request->getModuleName();
$config = new Zend_Config_Ini(APPLICATION_PATH . "/configs/modules.ini", $module);
$layout = isset($config->layout) ? $config->layout : 'default';
$views = isset($config->views) ? $config->views : 'default';
$this->view->layout()->setLayout($layout);
$this->view->setScriptPath(sprintf('%s/modules/%s/views/%s/scripts', APPLICATION_PATH, $module, $views));
}
It's not exactly what i wanted, but solves my problem.

How to call custom filters in Zend?

I want to use htmlpurifier on my website, but can't figure out how to load my filter in the view. I've added my filter the way described in the first answer here.
I want to be able to call it from my view with something like $this->filter($content) Any suggestions how I do that?
It is a two step process:
Write an actual Zend_Filter implementation of HTMLPurifier (done, answer in the question you mentioned)
Write a view helper
It will look like this:
class My_View_Helper_Purify extends Zend_View_Helper_Abstract
{
public function purify($value)
{
$filter = new My_Filter_HtmlPurifier();
return $filter->filter($value);
}
}
Don't forget to add your custom view helper path:
$view->addHelperPath(
APPLICATION_PATH . '/../library/My/View/Helper',
'My_View_Helper_'
);
And later in any of your view scripts:
<?= $this->purify($text) ?>

Setting routes in application.ini in Zend Framework

I'm a Zend Framework newbie, and I'm trying to work out how to add another route to my application.ini file.
I currently have my routes set up as follows:
resources.router.routes.artists.route = /artists/:stub
resources.router.routes.artists.defaults.controller = artists
resources.router.routes.artists.defaults.action = display
...so that /artists/joe-bloggs uses the "display" action of the "artists" controller to dipslay the profile the artist in question - that works fine.
What I want to do now is to set up another route so that /artists/joe-bloggs/random-gallery-name goes to the "galleries" action of the "artists" controller.
I tried adding an additional block to the application.ini file (beneath the block above) like so:
resources.router.routes.artists.route = /artists/:stub/:gallery
resources.router.routes.artists.defaults.controller = artists
resources.router.routes.artists.defaults.action = galleries
...but when I do that the page at /artists/joe-bloggs no longer works (Zend tries to route it to the "joe-bloggs" controller).
How do I set up the routes in application.ini so that I can change the action of the "artists" controller depending on whether "/:gallery" exists?
I realise I'm probably making a really stupid mistake, so please point out my stupidity and set me on the right path (no pun intended).
Try reversing the order of the routes. ZF matches routes in the opposite order they are added (so that the default route is the last to be matched)
If that doesn't work, you'll probably have to investigate regex routes with optional components.
Your second block needs to have a different route name, rename the 'artists' word to something similar to this for your new block:
resources.router.routes.artists-gal.route = /artists/:stub/:gallery
resources.router.routes.artists-gal.defaults.controller = artists
resources.router.routes.artists-gal.defaults.action = galleries
I usually setup my routes in application/Bootstrap.php (or wherever your Bootstrap.php file is)
add a method like the one below:
protected function _initRoutes()
{
$ctrl = Zend_Controller_Front::getInstance();
$router = $ctrl->getRouter();
$router->addRoute(
'artist_detail',
new Zend_Controller_Router_Route('artists/:stub',
array('controller' => 'artists',
'action' => 'display'))
);
$router->addRoute(
'artist_detail_gallery',
new Zend_Controller_Router_Route('artists/:stub/:gallery',
array('controller' => 'artists',
'action' => 'gallery'))
);
}
As far as checking weather an specific artist has a gallery, in the case of my example, i would have a galleryAction method in the ArtistsController
do a check if a gallery exists for the 'stub' request paramater, if it doesnt throw a 404:
throw new Zend_Controller_Action_Exception("Object does not exist", 404);
or redirect them to some other page:
return $this->_helper->redirector('index', 'index'); //redirect to index action of index controller
Hope this helps.

Render action to HTML email in Zend Framework

I have an action which is rendering some content via a layout.
I actually want to send this output in an email. What is the best way to achieve this in the Zend Framework?
I know I need to use the Zend_Mail component to send the email, but I'm unclear about how to attach the output of my action to Zend_Mail.
I've done some reading on the ContextSwitch action helper, and I think that might be appropriate, but I'm still not convinced.
I'm still new to Zend Framework. I'm used to using techniques like output buffering to capture output, which I don't think is the correct way to do this in Zend.
From your controller:
// do this if you're not using the default layout
$this->_helper->layout()->disableLayout();
$this->view->data = $items;
$htmlString = $this->view->render('foo/bar.phtml');
If you're doing this from a class that's not an instance of Zend_Controller_Action, you may have to create an instance of a Zend_view first, to do this:
$view = new Zend_view();
// you have to explicitly define the path to the template you're using
$view->setScriptPath(array($pathToTemplate));
$view->data = $data;
$htmlString = $view->render('foo/bar.phtml');
public static function sendMail($data = array(), $template = ''){
$html = new Zend_View();
$html->setScriptPath(APPLICATION_PATH . '/modules/default/views');
// assign valeues
if(count($data['Assigni'])){
foreach($data['Assigni'] as $assign){
$html->assign($assign['key'], $assign['value']);
}
}
// create mail object
$mail = new Zend_Mail('utf-8');
// render view //'scripts/newsletter/emailtemplate.phtml'
$bodyText = $html->render($template);
$mail->addTo($data['To']);
$mail->setSubject($data['Subject']);
$mail->setFrom($data['From'], $data['FromName']);
$mail->setBodyHtml($bodyText);
$mail->send();
}
when you dispatch the action, you can catch the event in postDispatch() method of plugin, that you can dynamically add to the stack from desired action. In that you recieve the contents of response by
//in action
//...some php code
Zend_Controller_Front::getInstance()->registerPlugin(new My_Plugin());
//in plugin
$htmlCode = $this->_response->getBody();
I can't give you a super-detailed answer, but if you want the full output (including the layout), I think you want to write your email function as an Action helper, and insert it at the PostDispatch hook of the Zend_Controller_Action->dispatch() loop.
See http://nethands.de/download/zenddispatch_en.pdf for the full Zend Framework Dispatch Process Overview.
If you don't need the layout included in your email content, then you could do this at many points, including by the use of a context switch, as you mentioned.

How to retrieve the Zend_Config used by Zend_Application?

I'm migrating my app to use Zend_Application for bootstrap. I used to have the Zend_Config as a key for my $registry.
Now I don't know how to use it this way anymore (without having to reload the config file).
I know it's possible to use $application->getOptions(), but that gives my an array and I would have to change everywhere in my code where $config is used like an object ($config->services->storage) to array-like ($config['services']['storage']).
Zend_Registry::set('config', new Zend_Config($this->getOptions()));
is all you need.
Zend_Application only uses (and stores) the config.ini file, as given in the second parameter of the call to 'new Zend_Application(ENV, '.../app.ini');' as an array. To be able to store it as an object, you'll have to re-parse it.
You can add a function into the bootstrap to do so, and store it into the registry,
<?php
// in 'class Bootstrap extends Zend_Application_Bootstrap_Bootstrap'
protected function _initConfig()
{
// config
//#Zend_Registry::set('config', $this->getOptions()); // as an array
$ZFOptions = array(); // could be: 'allowModifications'=>true
$section = 'production'; // or from the environment
$configFilename = APPLICATION_PATH .'/configs/application.ini';
$config = new Zend_Config_Ini($configFilename, $section, $ZFOptions);
Zend_Registry::set('config', $config); // as an object
}