Pass parameter to GET request in laravel tests - php

In Laravel tests i want to send a get request with some parameters like this:
$response=$this->get(
route('orders.payment.pay',['order'=>$order->id]),
['pay_type','payment_gateway']
);
but when i run it, i have 302 Error code in response. But when use it like this it works correct:
$response=$this->get(
route('orders.payment.pay',['order'=>$order->id]).'?pay_type=payment_gateway'
);
Is there any way to pass parameter like first way?

This is the signature of the route helper:
function route($name, $parameters = [], $absolute = true)
You should add any query parameters you want to the array or parameters you are passing to the route helper:
route('orders.payment.pay', [
'order' => $order->id,
'pay_type' => 'payment_gateway',
]);
Any parameter that is not substituted for a Route Parameter is appended as a query string parameter.

Related

Send data using redirect action using Laravel 7

I need to use something like this one :
return redirect()->action([HomeController::class, 'index'])->with('data'=>$data);
but I don't know how ?
Action method accepts two parameters which are array both. Second array is associative array of key as parameter name and value of parameter value.
In your case it would be
return redirect()->action(
[HomeController::class, 'index'],
['data' => $data]
);
Docs.

php symfony setting nested parameters in container

In my php symfony app I got the following parameters.yml:
my_param: some_value
my_nested:
param: some_value2 //4 spaces here, need to set only this param
param2: some_value3 // this should NOT be changed
I can set the parameter in a container with the following code:
$container->setParameter('my_param', $some_value);
it works fine, but I need to set a nested parameters, like this:
$container->setParameter('my_nested.param', $some_value);
I get an error saying that it cannot set nested param. Any ideas how to fix that? my_nested.param2 (and other nested params here) should not be changed. Thank you.
You need to use an array-like structure, like this:
$container->setParameter('my_nested', [
'param' => $some_value_2,
]);
Have a look here: https://symfony.com/doc/current/service_container/parameters.html
An example to change a nested parameter:
$container->setParameter('my_nested', [
'top' => [
'nested' => 'a',
]
]);
$parameter = $container->getParameter('my_nested');
$parameter['top']['nested'] = 'b';
$container->setParameter('my_nested', $parameter);
you can define the value like that :
the parameters.yml :
parameters:
my_param: some_value
my_nested.param: some_value2
you can get the value as you show in your description , but modify this value is impossible .
symfony will notify you with the error :
Impossible to call set() on a frozen ParameterBag.

Laravel append URI in route

Hi I want to append the uri in laravel route function.
e.g we have /search?type=listing
//how do i can achieve this with
route('search',['type'=>'listing'])
Once the we are on the search. I want to have all the variable appended to search like
type=listing&query=blah blah
If I get you right, you want to save all query parameters. Use Request::query() to get it and then merge with your new parameters.
route('search', array_merge(\Request::query(), ['type' => 'listing'])));
If you have a named route and want to generate url with query params then:
route('route_name', ['param1' => 'value', 'param2' => 'value']);
In your case you can do this with
route('search',['type'=>'listing','subject' => ['blah'],[....]])

CURL Get Request with a parameter that contains a GET url

I'm trying to make a cURL GET to scrape a Facebook Graph object:
GET https://graph.facebook.com/?id=**OBJECT_URL**&scrape=true&method=post
In my case, OBJECT_URL contains GET parameters:
https://www.example.com/og.php?a=b&c=d
For that reason I can't have it as a GET parameter in file_get_contents() or CURLOPT_URL, as it'd turn out something like this:
https://graph.facebook.com/?id=**https://www.example.com/og.php?a=b&c=d**&scrape=true&method=post
Is there a way to pass it as a GET parameter in a way similar to CURLOPT_POSTFIELDS?
You need to escape your parameters, the http_build_query function will be useful:
$query = http_build_query([
'id' => 'http://foo?a=1&b=2',
'scrape' => true,
'method' => 'post'
]);
$url = "https://graph.facebook.com/?".$query;
var_dump($url);
This will output:
https://graph.facebook.com/?id=http%3A%2F%2Ffoo%3Fa%3D1%26b%3D2&scrape=1&method=post

How to reconstruct a url using cakephp while removing selected query parameters?

I am using CakePHP 2.4
I have a url for e.g. /sent?note=123&test=abc
I want to remove the note parameter while giving me the rest of the url back. i.e.
/sent?test=abc
I have a piece of code that works but only for query parameters. I would like to find out how to improve my code so that it works with:
named parameters
passed parameters
hashtag
E.g.
/sent/name1:value1?note=123&test=abc#top
This is the code I have written so far. https://github.com/simkimsia/UtilityComponents/blob/master/Controller/Component/RequestExtrasHandlerComponent.php#L79
UPDATE PART III:
Let me illustrate with more examples to demonstrate what I mean by a more generic answer.
The more generic answer should assume no prior knowledge about the url patterns.
Assuming given this url
/sent/name1:value1?note=123&test=abc
I want to get rid of only the query parameter note and get back
/sent/name1:value1?test=abc
The more generic solution should work to give me back this url.
Another example. This time to get rid of named parameters.
Assuming given this url again
/sent/name1:value1?note=123&test=abc
I want to get rid of name1 and get back:
/sent?note=123&test=abc
Once again, the more generic solution should be able to accomplish this as well.
UPDATE PART II:
I am looking for a more generic answer. Assuming the web app does not know the url is called sent. You also do not know if the query parameters contain the word note or test. How do I still accomplish the above?
I want to be able to use the same code for any actions. That way, I can package it into a Component to be reused easily.
UPDATE PART I:
I understand that hashtag will not be passed to PHP. So please ignore that.
Clues on how to get the values from the hashtag:
https://stackoverflow.com/a/7817134/80353
https://stackoverflow.com/a/940996/80353
What about using mod_rewrite ?
You can handle your URLS in an other way :
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^/sent/name:(.*)?note=(.*)&test=([az-AZ])(#(.*))$ /sent/name:$1/note:$2/test:$3$4
</IfModule>
I'm not sure about the regex, but this may pass variables to cakePHP in a clean way (but I haven't tested it, though)
[EDIT]
But if you want to work without knowing urls patterns, then you can use the $this->request array : with an URL like
action/id:10/test:sample?sothertest=othersample&lorem=ipsum
I can get all the arguments using this in my controller :
// In your controller's method
$arguments= array_merge_recursive($this->request->named,$this->request->query);
Then, $arguments will be an array containing both named and passed params :
array(
'id' => '10',
'test' => 'sample',
'sothertest' => 'othersample',
'lorem' => 'ipsum'
)
Is it better ?
[EDIT 2]
If you know which parameter you have to get rid of, and directly redirect to the new URL, this should work:
action/id:10/test:sample?knownParam=value&lorem=ipsum
or with
action/id:10/knownParam:value?othertest=othersample&lorem=ipsum
In your controller/appController action:
// Name of the known param
$knownParam = 'knownParam';
// Arguments
$arguments = array_merge_recursive($this->request->named, $this->request->query);
if (key_exists($knownParam, $arguments)) {
// Unset in named params:
unset($arguments[$knownParam]);
// Creating url:
$url = array(
'admin' => $this->request->params['prefix'],
'plugin' => $this->request->params['plugin'],
'controller' => $this->request->params['controller'],
'action' => $this->request->params['action']
);
// Adding args
foreach ($arguments as $k => $v) {
$url[$k] = $v;
}
// Redirect
$this->redirect($url);
}
This will redirect both urls to
action/id:10/param1:value1/param2:value2
without the "know param"...
Let us say you have created the following routes:
Router::connect('/projects/:id/quotations/:quotation_id/*',
array(
'controller' => 'quotations',
'action' => 'get_all_by_project', "[method]" => "GET"),
array(
'pass' => array('id', 'quotation_id'),
'id' => '[0-9]+',
'quotation_id' => '[0-9]+'
),
array(
'named' => array(
'name1',
'name2',
'name3'
)
)
);
In this route:
Passed parameters will be the compulsory parameters id and quotation_id obeying the order as the first and second passed parameter
Named parameters will be the optional parameters name1, name2, and name3.
Query parameters will, of course, be optional as well and depend on what you actually have in the url.
you need the asterisk at the end so that the named parameters can pass through
Let us assume the following pretty url and the ugly url of the same action:
/projects/1/quotations/23/name2:value2/name3:value3/name1:value1?note=abc&test=123 (pretty)
/quotations/get_all_by_project/1/23/name2:value2/name3:value3/name1:value1?note=abc&test=123 (ugly)
First part of the answer:
Let us consider only the scenario of removing the query parameter note.
We should get back
/projects/1/quotations/23/name2:value2/name3:value3/name1:value1?test=123 (pretty)
/quotations/get_all_by_project/1/23/name2:value2/name3:value3/name1:value1?test=123 (ugly)
The following Component method will work. I have tested it on both the ugly and pretty urls.
public function removeQueryParameters($parameters, $here = '') {
if (empty($here)) {
$here = $this->controller->request->here;
}
$query = $this->controller->request->query;
$validQueryParameters = array();
foreach($query as $param=>$value) {
if (!in_array($param, $parameters)) {
$validQueryParameters[$param] = $value;
}
}
$queryString = $this->_reconstructQueryString($validQueryParameters);
return $here . $queryString;
}
protected function _reconstructQueryString($queryParameters = array()) {
$queryString = '';
foreach($queryParameters as $param => $value) {
$queryString .= $param . '=' . $value . '&';
}
if (strlen($queryString) > 0) {
$queryString = substr($queryString, 0, strlen($queryString) - 1);
$queryString = '?' . $queryString;
}
return $queryString;
}
This is how you call the Component method.
$newUrl = $this->RequestExtrasHandler->removeQueryParameters(array('note'));
RequestExtrasHandler is the name of Component I wrote that has the above method.
Second part of the answer:
Let us consider only the scenario of removing the named parameter name2.
We should get back
/projects/1/quotations/23/name3:value3/name1:value1?test=123 (pretty)
/quotations/get_all_by_project/1/23/name3:value3/name1:value1?test=123 (ugly)
The following Component method will work. I have tested it on both the ugly and pretty urls.
public function removeNamedParameters($parameters, $here = '') {
if (empty($here)) {
$here = $this->controller->request->here;
}
$query = $this->controller->request->query;
$named = $this->controller->request->params['named'];
$newHere = $here;
foreach($named as $param=>$value) {
if (in_array($param, $parameters)) {
$namedString = $param . ':' . $value;
$newHere = str_replace($namedString, "", $newHere);
}
}
$queryString = $this->_reconstructQueryString($query);
return $newHere . $queryString;
}
This is how you call the Component method.
$newUrl = $this->RequestExtrasHandler->removeNamedParameters(array('name2'));
RequestExtrasHandler is the name of Component I wrote that has the above method.
Third part of the answer:
After I realized that passed parameters are compulsory, I found that there is no real business need to remove passed parameters if at all.
Another problem is that unlike named parameters and query parameters, passed parameters tend not to have the keys present in the $this->controller->request->params['pass']
$this->controller->request->params['pass'] is usually in the form of a numerically indexed array.
Hence, there is huge challenge to take out the correct passed parameters.
Because of that, I will not create any method to remove passed parameters.
Check out the code here in details:
https://github.com/simkimsia/UtilityComponents/blob/d044da690c7b83c72a50ab97bfa1843c14355507/Controller/Component/RequestExtrasHandlerComponent.php#L89
maybe simple php functions can do what you want
$url = '/sent?note=123&test=abc'; //for example
$unwanted_string = substr($url, 0,strrpos($url,'&') + 1);
$unwanted_string = str_replace('/sent?', '', $unwanted_string);
$url = str_replace($unwanted_string, '', $url);

Categories