I declare a publisher controller:
class PublisherController extends Zend_Controller_Action {
public function indexAction()
{
$this->view->form = $this->_getForm();
$this->render('form');
}
public function dataPostAction()
{
//#TODO
}
protected function _getForm()
{
$form = new Zend_Form();
$form->setAction('publisher/dataPost')//Here, I DO NOT want to do: setAction('*/dataPost') with `*` means current controller.
->setMethod('post')
->setAttrib('id','publisher-form');
$form->addElement('text', 'name',
array(
'label'=>'First Name',
'class'=>'required'
)
);
$form->addElement('submit', 'Save');
return $form;
}
}
Look at the line: $form->setAction('publisher/dataPost')
This means that I want to set the action for the form after submitting is dataPost of publisher controller.
Now I want do do $form->setAction('*/dataPost') with the * means current controller. Because current controller is publisher too.
But it does not work, or am I missing something? Can you tell me what is correct?
publisher/dataPost is much easier to type than $form->setAction($this->getRequest()->getControllerName().'/dataPost'), so I would recommend you stick with what you are already doing.
I don't normally use it in the zend form its self, but preferably in the actions view when calling the form using this code.
<?php echo $this->setAction(url(/.../.../) );?>
This is to echo the form you using in your action and also to set its action. So in short just stick to what you have or use sam's method but I think its better if you have something ACCURATE and working.
I decide the comment of #Sam is the best answer for me.
Using the statement:
$form->setAction($this->getRequest()->getControllerName().'/dataPost')
UPDATE
From this question, I know that: "DO NOT be complex", and some guys here is don't agree so much with the above solution. Now I got this too. But, for this answer, I believe that I SHOULD check and confirm what is correct.
Related
I need to generate widgets\ActiveForm::field() without "form" tag at begin. I looked in source of yii\widgets\ActiveForm and found that this can not be avoided :(
public function init()
{
if (!isset($this->options['id'])) {
$this->options['id'] = $this->getId();
}
echo Html::beginForm($this->action, $this->method, $this->options);
}
Maybe there's another way to solve this problem without extending the 'ActiveForm' class?
ActiveField is basically just a wrapper for yii\helpers\Html::active... methods so you just can call echo yii\helpers\Html::activeTextInput($model, $attribute, $options); without using ActiveForm
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');
}
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;
}
}
I need to redirect according to some conditions in the bootstrap file.
It is done AFTER the front controller and routes are defined.
How do I do that?
(I know I can simply use header('Location: ....) The point is I need to use the Router to build the URL.
more than year later, i'm programming in ZF and I got this solution for your problem.
Here is my function in bootstrap that determines where the user is logged on.
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected $_front;
(...)
protected function _initViewController()
{
(...)
$this->bootstrap('FrontController');
$this->_front = $this->getResource('FrontController');
(...)
}
protected function _initLogado()
{
$router = $this->_front->getRouter();
$req = new Zend_Controller_Request_Http();
$router->route($req);
$module = $req->getModuleName();
$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity()) {
$this->_view->logado = (array) $auth->getIdentity();
} else {
$this->_view->logado = NULL;
if ($module == 'admin') {
$response = new Zend_Controller_Response_Http();
$response->setRedirect('/');
$this->_front->setResponse($response);
}
}
}
}
Redirection should really not be in the bootstrap file... That will be one horrible night of debugging for the coder that ends up stuck with your code in a few years.
Use either a Front Controller Plugin, Action Controller Plugin, or do it in your Action Controller. Ultimately such a redirect should be avoided altogether...
The best way is probably a Controller Plugin
You can add a routeShutdown() hook that is called after routing has occured, but before the action method your controller is called. In this plugin you can then check the request data or maybe look for permissions in an ACL, or just redirect at random if that's what you want!
The choice is yours!
EDIT: Rereading your question, it looks like you're not even interested in the route - use routeStartup() as the earliest point after bootstrapping to inject your code.
I would grab the router from the front controller and call its assemble() method and then use header() :)
Regards,
Rob...
You can check the condition on "routeShutdown" method in plugin and then use $this->actionController->_helper->redirector() to redirect ;)
I am building a form in Zend Framework 1.9 using subforms as well as Zend_JQuery being enabled on those forms. The form itself is fine and all the error checking etc is working as normal. But the issue I am having is that when I'm trying to retrieve the values in my controller, I'm receiving just the form entry for the last subform e.g.
My master form class (abbreviated for speed):
Master_Form extends Zend_Form
{
public function init()
{
ZendX_JQuery::enableForm($this);
$this->setAction('actioninhere')
...
->setAttrib('id', 'mainForm')
$sub_one = new Form_One();
$sub_one->setDecorators(... in here I add the jQuery as per the docs);
$this->addSubForm($sub_one, 'form-one');
$sub_two = new Form_Two();
$sub_two->setDecorators(... in here I add the jQuery as per the docs);
$this->addSubForm($sub_two, 'form-two');
}
}
So that all works as it should in the display and when I submit without filling in the required values, the correct errors are returned. However, in my controller I have this:
class My_Controller extends Zend_Controller_Action
{
public function createAction()
{
$request = $this->getRequest();
$form = new Master_Form();
if ($request->isPost()) {
if ($form->isValid($request->getPost()) {
// This is where I am having the problems
print_r($form->getValues());
}
}
}
}
When I submit this and it gets past isValid(), the $form->getValues() is only returning the elements from the second subform, not the entire form.
I recently ran into this problem. It seems to me that getValues is using array_merge, instead of array_merge_recursive, which does render to correct results. I submitted a bug report, but have not gotten any feedback on it yet.
I submitted a bug report (http://framework.zend.com/issues/browse/ZF-8078). Perhaps you want to vote on it?
I think that perhaps I must have been misunderstanding the way that the subforms work in Zend, and the code below helps me achieve what I wanted. None of my elements share names across subforms, but I guess this is why Zend_Form works this way.
In my controller I now have:
if($request->isPost()) {
if ($form->isValid($request->getPost()) {
$all_form_details = array();
foreach ($form->getSubForms() as $subform) {
$all_form_details = array_merge($all_form_details, $subform->getValues());
}
// Now I have one nice and tidy array to pass to my model. I know this
// could also be seen as model logic for a skinnier controller, but
// this is just to demonstrate it working.
print_r($all_form_details);
}
}
I have a same problem to get value from subforms I solve it with this but not my desire one
code:
in controller i get value with this code that 'rolesSubform' is my subform name
$this->_request->getParam ( 'rolesSubform' );
Encountered the same problem. Used post instead of getValues.
$post = $this->getRequest()->getPost();
There are times when getValues does not return the same values returned by $post.
Must be a getValues() bug.