Zend Router overwrites post variables from form - php

We are using the Zend Router and it seems that its overwriting the parameters that are sent by forms. The only parameters that arrive to the controller are the params from the Url.
Does anyone know why this is happening?
Here is the config file:
; Routing config
routes.groups.route = groups/:group/:type/:idPost/:postUrl/:page
routes.groups.defaults.controller = groups
routes.groups.defaults.action = index
routes.groups.defaults.type = main
routes.groups.defaults.idPost =
routes.groups.defaults.postUrl =
routes.groups.defaults.page = 1
And the form:
<form action="<?= $this->_view->baseUrl ?>/groups/<?= $group['groupUrl'] ?>/deletepost/" method="post">
<input type="hidden" name="formUrl" value="<?=$formUrl ?> />
...
</form>
Controller:
public function deletepostAction() {
$params = $this->getRequest()->getParams();
print_r($params);
die;
}
...that outputs:
Array
(
[group] => dandy-handwriting
[type] => deletepost
[idPost] =>
[controller] => groups
[action] => index
[postUrl] =>
[idGroup] => 1
[lang] => en
)
note that "formUrl" is missing, its only the parameters from the router.

You can use the request-object in your controller to access your data.
Fetch the request object:
$request = $this->getRequest();
Retrieve POST data (if your form is submitted via POST):
$post = $request->getPost();
Retrieve GET data (if your form is submitted via GET):
$get = $request->getQuery();
Retrieve parameter in the order user parameters set via setParam(), GET parameters and POST parameters:
$params = $request->getParams();
If you fetch your data with getParams() the params set by the router will override your POST data.
So if you only want to fetch the data from your form, use the getPost() or getQuery() method.

Probably you are sending your form data as GET, and have configured Zend_Router to rewrite the url (without taking the other get parameters).
In that case the solution is to send the form data with POST or change the routes in Zend_Router.
Your code would help to determine what your exact problem is.

Related

Validate field in form - check if "product" exists in CakePhp 3

I've got problem with field validation.
I would like to validate form through model. I want to check if field with some value exists.
I would like to block using some titles more than once.
For example
if field "Site" with title "Main" exists in database, you can't validate form.
If it doesn't exist, you can pass it.
I would like to allow user to add just one "Site" with title "Main", but he can add "Site" with any other title in any case.
Have you got some idea how to solve it?
I think you have two options.
(1) Setup an Ajax request to the server.
To do so:
Create a function, that responds to an Ajax request, in your SiteController named checkName()
public function checkName($name) {
// allow ajax requests
$this->request->allowMethod(['ajax']);
// perform your check within the db
$isExistent = [...];
// prepare the response
$response = ['name' => $name, 'isExistent' => $isExistent];
if ($this->request->isAjax()){
$this->autoRender = false;
$this->response->disableCache();
$this->response->type(['json' => 'application/json']);
$this->response->body(json_encode($response));
}
}
Add the route to your routes file with the option '_ext' => 'json'
Prepare your Javascript Ajax function that call the route you have defined and attach it on the onchange attribute of your input field. (see this link for a simple example: http://www.w3schools.com/jquery/ajax_ajax.asp)
(2) Make the 'name' field of the Site table unique.
To do so you could add the following function to your SiteTable class
public function buildRules(
RulesChecker $rules
) {
$rules->add($rules->isUnique(['name']));
return $rules;
}

ZF2: How to change Request object globally for all Controllers when using forward plugin?

I'm using forward plugin in testing and performance purposes.
At first IndexController data passes through normal POST request.
There I get this requst and POST data and I need add one more parameter to it.
$this->getRequest()->getPost()->subsystem = 'avia';
Than I use forward plugin
$result = $this->forward()->dispatch(
"Port\\Controller",
[
'controller' => 'Port\\Controller',
'action' => 'port',
]
);
And whan I'm in this PortController I would get my request POST data again and it SHOULD contain my changes from IndexController
$post = $this->getRequest()->getPost();
isset($post['subsystem']) //true
But it does't. It get's request object without changes.
isset($post['subsystem']) //FALSE
How to change Request globally for all controllers in current request process?
What i'm already trying?
//#1
$params = $this->getServiceLocator()->get('ControllerPluginManager')->get('params');
$params->getController()->getRequest()
->getPost()->subsystem
= 'avia';
//#2
$this->getRequest()->getPost()->subsystem = 'avia';
//#3
$post = $this->getRequest()->getPost();
$post['subsystem'] = 'avia';
//NEED UPDATE GLOBALLY !
$this->getRequest()->setPost($post);
//#4
$event = $this->getEvent();
$event->getRequest()->getPost()->subsystem = 'avia';
Debug::vars($event->getRequest()->getPost());
//#5
$_POST = $post->toArray();
And all this variances not working.
I'm already read this answer
ZF2: How to pass parameters to forward plugin which I can then get in the method I forward them to?
But I don't want pass data through params, I need change Request.
UPD
But now i'm tested and maybe it was because on receiver side I tried to get request this way
$request = $this->bodyParams();
But I should use it like this
if (!$request['subsystem']) {
$request = $this->getRequest()->getPost()->toArray();
}
It was because I used Apigility RPC service and placed post data in JSON format in Request Content field, not in POST. And in another place I tried get it
$params = $this->serviceLocator->get('ControllerPluginManager')->get('params');
$requestContent = $params->getController()->getRequest()->getContent();
$request = Json::decode($requestContent, Json::TYPE_ARRAY);
But after I started to use POST and that's why it started to be confused.
I am not sure if this is really something you should do but I think you should be able to achieve it like this:
$parameters = $this->getRequest()->getPost();
$parameters->set('subsystem', 'avia');
$parameters is instance of Zend\Stdlib\Parameters.

CakePHP redirect form post with querystring

I'm a Cake newbie, and I'm looking to post a querystring value into a controller method, but always reload the view with the querystring intact. Currently I have the below snippet.
public function something()
{
if($this->request->query !=null )
$date = $this->request->query["date"];
}
<?php echo $this->Form->create('setup',array('action' => 'something?date=2013','id'=>'setup-form','role'=>'form') ); ?>
Any advice on why something() doesn't redirect to something?date=2013 on its default render? Do I need to do some special routing?
In CakePHP 2, you can include query string parameters in $url parameters like so:
array('action' => 'something', '?' => array('date' => '2013'))
CakePHP will build the query string and append it to the matched URL in your routing configuration.
(Note: You may need to pass FormHelper::create an entire URL, generated from HtmlHelper::url, instead of using the "shorthand" technique.)

How can I use ajax in Zend Framework 2?

I am trying a small ajax application whereby I only want to return a hello world string from my controller action.
it is returning the Hello world but along with this, it is also returning my template file..
I tried to disable it the templating using the following code in the action of my controlelr
$this->_helper->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender( true );
but this returns me this error
SCREAM: Error suppression ignored for
( ! ) Notice: Undefined property: Survey\Controller\SurveyController::$_helper in C:\wamp\www\zend\module\Survey\src\Survey\Controller\SurveyController.php on line 55
SCREAM: Error suppression ignored for
( ! ) Fatal error: Call to a member function layout() on a non-object in C:\wamp\www\zend\module\Survey\src\Survey\Controller\SurveyController.php on line 55
Call Stack
How do I fix this ?
EDIT
I modifed the controller such that it looks like this
public function registerAction()
{
$result = new JsonModel(array(
'some_parameter' => 'some value',
'success'=>true,
));
return( $result );
}
Added strategies in the module..module.config in module appl directory
'strategies' => array(
'ViewJsonStrategy',
),
Still, in the ajax response I get the template being returned
Here's a solid example:
http://akrabat.com/zend-framework-2/returning-json-from-a-zf2-controller-action/
You should be using JsonMoodels to send back a Json Response.
i use this in my controller:
$view = new ViewModel(array('form'=>$my_form));
//disable layout if request by ajax
$view->setTerminal($request->isXmlHttpRequest());
$view->setTemplate('path/to/phtml');
return $view;
The user wanted to know how to get just the html back, not json as Andrews reply offers.
I also wanted the html returned so i could use it with jquery qtip plugin and this is how i did it.
I also had to make the page degrade gracefully in case javascript failed, e.g. the page output should render properly in the layout template.
/**
* Tourist Summary action
*
* #return ViewModel
*/
public function touristSummaryAction()
{
// Get the Id
$id = $this->params()->fromRoute('id', '');
// Get the data from somewhere
$data = array() ;
// Get the html from the phtml
$view = new ViewModel(
array(
'id' => $id ,
'data' => $data ,
)
);
//disable layout if request by ajax
$view->setTerminal($this->getRequest()->isXmlHttpRequest());
return $view;
}
The most simple way to send ajax requests and handle responses is the zf2 module WasabiLib https://github.com/WasabiLib/wasabilib_zf2_skeleton_application
You only need to add "ajax_element" to the class-attribute to the element which you want to cause the ajax request. It does not matter if it is a form submit or a link or a button. Visit the examples page http://www.wasabilib.org/application/pages/examples
If your application does a lot of ajax I recommend this module.
Take a look at this module. www.wasabilib.org
Seems that you it manages ajax very well.
If you do not have a application you can use the Wasabilib Skeleton https://github.com/WasabiLib/wasabilib_zf2_skeleton_application. It comes with all necessary assets in the right place.
If you already have an application you should clone the module: https://github.com/WasabiLib/wasabilib
Minimal requirements: jQuery, ZF2
Add the module to application.config.php.
Include the wasabilib.min.js after jquery in the head of your layout.phtml
How it works
in your .phtml-file you have a form like this:
<form id="simpleForm" class="ajax_element" action="simpleFormExample" method="POST">
<input type="text" name="written_text">
<input type="submit" value="try it">
</form>
Anywhere else in your phtml you can place an element where the response is shown.
In your Controller the following method:
public function simpleFormExampleAction(){
$postArray = $this->getRequest()->getPost();
$input = $postArray['written_text'];
$response = new Response(new InnerHtml("#element_simple_form","Server Response: ".$input));
return $this->getResponse()->setContent($response);
}
The form has a class "ajax_element" this will say the the library that the request will be done with an xmlhttp-request. It wont work if you do not give an id to the requesting element. So the form has the ID "simpleForm". The action is the "path/to/controller" just like a normal request.
In the controller action a new WasabiLib\Ajax\Response object is instanciated.
The InnerHtml class is for replace, prepend and append html or normal text to a selector.
In this case the selector is an ID "element_simple_form". The first parameter of the InnerHtml class is the selector. Make sure that you write #yourElementId or .yourClassSelector. For IDs an "#" and for class selectors "."
The second parameter is the Text you want to fill in this element.
The response object can handle a lot more responses which you can add with
$response->add($anotherResponseType);
A list of possible response types is here: http://www.wasabilib.org/application/pages/components
The module is build to handle ajax request an responses in a very simple way. Once you have understood the behavior you can handle almost every practical ajax need.
This works for me:
public function ajaxAction(){
$data = array(
'var1' => 'var1Value',
'var2' => 'var2Value',
);
$response = $this->getResponse();
$response->setStatusCode(200);
$response->setContent(json_encode($data));
$headers = $response->getHeaders();
$headers->addHeaderLine('Content-Type', 'application/json');
return $response;
}
Output:
{"var1":"var1Value","var2":"var2Value"}

ZEND: Cannot Access Post Data

Greets.
{{Solved}}
In order to get POST data you MUST use $this->formHidden in order to hold all the data. Even though variables are inside the they don't get passed if they aren't in some sort of form item.
I am unable to access post data in ZEND.
Path of User -
START
INDEX PAGE
->Submit Page
->Pay Page
I created a controller, extended the Zend Controller, and added an action called payAction. The user can go from the Index Page to the Submit Page. After I have all their data inside variables, I used a form and a submit button to go to the "pay page". However, I cannot get any of the POST data.
public function payAction()
{
$data = $this->getRequest();
}
I have tried putting getRequest, getParam, getRawBody inside that controller function.
In the page itself I have tried.
echo 'Hello';
echo $request;
echo $data;
echo $_POST['payZip'];
echo $_POST['data'];
echo $_POST[$data];
echo $request;
echo $this->values['payZip'];
echo $payZip;
echo $this->values['shippingDone'];
echo $stuff;
Is there ANYTHING I can place in my controller or in my view in order to get my post data? I used a form method="post" and a button and it DOES allow me to get to the page. I can see Hello. But NONE of the post data is available.
Any assistance would be appreciated.
Thank you.
-- Update
$data = $this->getRequest();
$param = $this->_request->getParam('payZip');
if($this->getRequest()->isPost())
{
print_r($this->_getAllParams());
echo $param;
}
Doing that gives me -
HelloArray ( [controller] => wheel [action] => pay [module] => default [shipping] => UPS Ground [payPal] => Secure Payment System )
But I still can't print payZip... I did echo and nothing comes out.
To get parameters from Zend Framework you need to do this in the Action Controller:
$data = $this->_request->getParams();
You can also get individual params like this
$param = $this->_request->getParam('payZip');
What it appears your doing wrong is you're only getting the "request object". You need to then call that objects method to get the request data.
Here's some simple code I often use when testing parameters:
public function indexAction()
{
#::DEBUG::
echo '<pre>'; print_r($this->_request->getParams()); echo '</pre>';
#::DEBUG::
}
This will show all your parameters. What you will notice is that you will also get the names of the Module, Controller and Action with your params.
EDIT
Ps. If you're trying to use the parameter in the view script you need to do this:
echo $this->data['payZip'];
echo $this->param;
In your Action Controller, you save your data to the "view" object by doing this:
$this->view->myVariable = 'Hello';
But when you're in a view script, you are IN the view script, so $this represents $this->view from the action controller.
So, you access the variable like this:
echo $this->myVariable;
Wrapping everything into a bigger code chunk for understanding:
Your Controller
public function indexAction()
{
// get all parameters and pass them to the view
$this->view->params = $this->_request->getParams();
// get an individual parameter and pass it to the view
$this->view->payZip = $this->_request->getParam('payZip');
}
Your View Script
<!-- Dump all parameters -->
<pre><?php print_r($this->params); ?></pre>
<!-- Print payZip -->
<p>My PayZip is: <?php echo $this->payZip; ?></p>
<!-- Print payZip from full parameter array -->
<p>My PayZip (array) is: <?php echo $this->data['payZip']; ?></p>
I hope that helps!

Categories