ZF Render an action and get the html in another action - zend-framework

What I want to do with Zend Framework is to render the action Y from the action X and to obtain the html:
Example:
public xAction(){
$html = some_function_that_render_action('y');
}
public yAction(){
$this->view->somedata = 'sometext';
}
where the y view is something like:
<h1>Y View</h1>
<p>Somedata = <?php echo $this->somedata ?></p>
I fount the action helper, but I cannot use it from a controller. How can I solve it?
It is possible?

Here is one possible way to do what you want.
public function xAction()
{
$this->_helper
->viewRenderer
->setRender('y'); // render y.phtml viewscript instead of x.phtml
$this->yAction();
// now yAction has been called and zend view will render y.phtml instead of x.phtml
}
public function yAction()
{
// action code here that assigns to the view.
}
Instead of using the ViewRenderer to set the view script to use, you could also call yAction as I showed above, but get the html by calling $html = $this->view->render('controller/y.phtml');
See also the ActionStack helper.

You can use the Action View Helper from the controller
public function xAction()
{
$html = $this->view->action(
'y',
$this->getRequest()->getControllerName(),
null,
$this->getRequest()->getParams()
);
}
public function yAction()
{
// action code here that assigns to the view.
}
It's not very beautiful but it works well and you don't have to use $view->setScriptPath($this->view->getScriptPaths());
This helper creates a new Zend_Controller_Request for yAction(), so you can give your own parameters as 4th argument or use $this->getRequest()->getParams() to spread the request parameters of xAction().
http://framework.zend.com/manual/1.12/en/zend.view.helpers.html#zend.view.helpers.initial.action

Finally I found this "solution", it's not what I want to do, but it works, if someone found the real solution, please answer here.
public function xAction(){
$data = $this->_prepareData();
$view = new Zend_View();
$view->somedata = $data;
$view->setScriptPath($this->view->getScriptPaths());
$html = $view->render('controller/y.phtml');
}

Related

Zend Framework: Return view as JSON

so my question is: What would be the best way to return the html of a response as JSON encoded string?
I know there are the typical json action helpers but they dont fit my need.
What i need is a way to return the complete html of a view as a json string if the request is an ajax-request.
Because i want to change my app to only load the content of the main container and i also need to pass along a few other variables during the request i need to find a way to do so :)
Maybe someone has already had some experience with that!
I can propose another solution:
1 - create a plugins directory in application directory.
In this directory create the plugin POutput.php like that:
<?php
class Application_Plugin_POutput extends Zend_Controller_Plugin_Abstract
{
public function postDispatch(Zend_Controller_Request_Abstract $request)
{
if (Zend_Registry::get('Output_Json'))
Zend_Layout::getMvcInstance()->setLayout('layout_json');
}
}
2 - Create a new layout "layout_json.phtml" like that:
<?php
echo $this->json($this->layout()->content); ?>
You can see the documentation for options about this helper
3 - Call the plugin in the bootstrap like that:
protected function _initPlugins(){
$front = Zend_Controller_Front::getInstance();
$front->registerPlugin(new Application_Plugin_POutput());
}
4 - In the bootstrap, for example, initiate the variable Output_Json like that:
protected function _initJson(){
Zend_Registry::set('Output_Json', true); // true for Json output, False for Html output
}
With this method, you do not have to change all your controller. ;)
I hope that answers your question. :)
I do not know what is the best way, but I'll give you mine.
To send a json to ajax call, I do it in the controller. I disable the layout, view, and I send the json.
for example to send an array, I do:
public function fooAction() {
$this->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
...
//get array $auth with value $authentification
$auth = array('authentification' => $authentification);
return $this->_helper->json($auth);
}
And it works very well :)
If you want a Json response that interacts with your Model layer, you should use this:
return new JsonModel(array);
And if you need a simple response, you should use the Response class, like this:
$response = new Response();
$response->getHeaders()->addHeaders(
array(
'Content-type' => 'application/json'
));
$response->setContent($yourContent);
return $response;

Custom Decorator Label in Zend Framework 2

according to this post: Zend Framework 2 - Form Element Decorators , i've tried the solution from iroybot (thanks to him) and it worked.
but new problem occurs. Here the details:
In the render method in FormCollection.php (View Helper) i throw object like this:
<?php
namespace Cust\View\Helper;
use Zend\Form\ElementInterface;
use Zend\Form\View\Helper\FormCollection as BaseFormCollection;
class FormCollection extends BaseFormCollection
{
public function render(ElementInterface $element)
{
return sprintf('<table class="table table-condensed">%s</table>',parent::render($element));
}
}
and in the render method in FormElement.php (View Helper), i throw :
<?php
namespace Cust\View\Helper;
use Zend\Form\ElementInterface;
use Zend\Form\View\Helper\FormElement as BaseFormElement;
class FormElement extends BaseFormElement
{
public function render(ElementInterface $element)
{
$req = '';
if($element->getOption('required')){
$req = 'required';
}
return sprintf('<tr><td>%s</td><td>%s</td> </tr>',$element->getLabel(),parent::render($element));
}
}
and the form render in the table perfectly. but before table, the label show in the tag label. so the label display twice, first in span tag, and the second in the row of the table...
i don't know how to solve this..
please give me advice..
thanks
bestregards

How to retrieve the default Zend_View object from a controller

If I do this
public function indexAction()
{
$view = new Zend_View();
$registrationForm = new Form_NewAwatag();
$view->assign((array) $registrationForm);
echo $view->render("index.phtml");
}
it will create a new Zend_View object. How can I use the default Zend_View object?
Is it correct how I pass object to the view script?
You can get the view by using $this->view;
Assign values with $this->view->variable = $value
Your code could be stripped down to this
public function indexAction()
{
$registrationForm = new Form_NewAwatag();
$this->view->assign('myForm', $registrationForm);
}
Because the Zend MVC construct will automatically render the index.phtml file while it is the indexAction beeing called. In the view your form can be accessed by $this->myForm.

ZEND Controllers -- How to call an action from a different controller

I want to display a page that has 2 forms. The top form is unique to this page, but the bottom form can already be rendered from a different controller. I'm using the following code to call the action of the other form but keep getting this error:
"Message: id is not specified"
#0 .../library/Zend/Controller/Router/Rewrite.php(441): Zend_Controller_Router_Route->assemble(Array, true, true)
My code:
First controller:
abc_Controller
public function someAction()
{
$this->_helper->actionStack('other','xyz');
}
Second controller:
xyz_Controller
public function otherAction()
{
// code
}
Desired results:
When calling /abc/some, i want to render the "some" content along with the xyz/other content. I think I followed the doc correctly (http://framework.zend.com/manual/en/zend.controller.actionhelpers.html) but can't find any help on why that error occurs. When I trace the code (using XDebug), the xyz/other action completes ok but when the abc/some action reaches the end, the error is thrown somewhere during the dispatch or the routing.
Any help is greatly appreciated.
You can accomplish this in your phtml for your someAction. So in some.phtml put <?php echo $this->action('other','xyz');?> this will render the form found in the otherAction of XyzController
The urge to do something like this is an indication you're going about it in totally the wrong way. If you have the urge to re-use content, it should likely belong in the model. If it is truly controller code it should be encapsulated by an action controller plugin
In phtml file u can use the $this->action() ; to render the page and that response would be added to current response ..
The syntax for action is as follows::
public function action($action, $controller, $module = null, array $params = array())
You can create new object with second controller and call its method (but it`s not the best way).
You can extend your first controller with the second one and call $this->methodFromSecond(); - it will render second form too with its template.
BTW - what type of code you want to execute in both controllers ?
Just an update. The error had absolutely nothing to do with how the action was being called from the second controller. It turns out that in the layout of the second controller, there was a separate phtml call that was throwing the error (layout/abc.phtml):
<?php echo $this->render('userNavigation.phtml') ?>
line of error:
echo $this->navigation()->menu()->renderMenu(...)
I'll be debugging this separately as not to muddy this thread.
Thanks to Akeem and hsz for the prompt response. I learned from your responses.
To summarize, there were 3 different ways to call an action from an external controller:
Instantiate the second controller from the first controller and call the action.
Use $this->_helper->actionStack
In the phtml of the first controller, action('other','xyz');?> (as Akeem pointed out above)
Hope this helps other Zend noobs out there.
Hm I can't find and idea why you need to use diffrent Controlers for one view. Better practise is to have all in one Controller. I using this like in this example
DemoController extends My_Controller_Action() {
....
public function indexAction() {
$this->view->oForm = new Form_Registration();
}
}
My_Controller_Action extends Zend_Controller_Action() {
public function init() {
parent::init();
$this->setGeneralStuf();
}
public function setGeneralStuf() {
$this->view->oLoginForm = new Form_Login();
}
}
This kind of route definition:
routes.abc.route = "abc/buy/:id/*"
routes.abc.defaults.controller = "deal"
routes.abc.defaults.action = "buy"
routes.abc.reqs.id = "\d+"
requires a parameter in order to function. You can do this with actionStack but you can also specify a default id in case that none is provided:
$this->_helper->actionStack('Action',
'Controller',
'Route',
array('param' => 'value')
);
routes.abc.defaults.id = "1"
For Me this worked like a charm
class abcController extends Zend_Controller_Action
{
public function dashBoardAction()
{
$this->_helper->actionStack('list-User-Data', 'xyz');
}
}
class XyzController extends Zend_Controller_Action {
public function listUserDataAction()
{
$data = array('red','green','blue','yellow');
return $data;
}
}

zend-framework, call an action helper from within another action helper

i am writing an action helper and i need to call another action helper from within that helper. but i dont know how. here in the sample code:
class Common_Controller_Action_Helper_SAMPLE extends Zend_Controller_Action_Helper_Abstract
{
protected $_view;
public function __construct(Zend_View_Interface $view = null, array $options = array())
{
$this->_view = $view;
}
public function preDispatch()
{
$flashMessenger = $this->_helper->FlashMessenger; // IT IS NULL
}
}
Use the action helper broker:
$flashMessenger =
Zend_Controller_Action_HelperBroker::getStaticHelper('FlashMessenger');
You can also use getActionController to get a reference back to the actioncontroller you were using for any methods you'd normally use there.
In addition to mercator's answer, add your method after, see example below:
Zend_Controller_Action_HelperBroker::getStaticHelper('FlashMessenger')->myMethod();
You can call it in this way:
$this->_actionController->OtherActionHelper();
The _actionController property references the actual action controller.