I'm trying to emulate ajax style uploading of a file in my test. Is it possible to use sendPUT to send a file and return the response? The controller receives the value via Input::file() -- I cannot seem to access what sendPUT sends via Input::file.
$I->sendPUT('/upload_image', array('file' => 'files.jpg'));
You are not using the function correctly.
Everything is explained in the official documentation:
sendPUT
Sends PUT request to given uri.
param $url
param array $params
param array $files
The third parameter is what you are looking for. Your code should look like this:
$I->sendPUT('/upload_image', array(), array('file' => 'files.jpg'));
Related
I am receiving an auth code from Microsoft that looks like this:
localhost:8000/token#auth=123456
In Laravel I have a route that points to a controller:
Route::get('/token', 'AuthController#getToken');
The function looks like this:
public function getToken(Request $request) {
session([
'request' => $request->fullUrl(),
]);
}
The problem is that fullUrl() returns localhost:8000/token so I can't see the auth token.
Is there a way round this?
Assuming you get that URL as a string, you can use parse_​url to get the fragment part:
<?php
$url = 'localhost:8000/token#auth=123456';
var_dump(parse_url($url, PHP_URL_FRAGMENT));
will output: string(11) "auth=123456"
If you want to get the value after the hash mark (#) as shown in a user's browser: This isn't possible with "standard" HTTP as this value is never sent to the server (hence it won't be available in $_SERVER["REQUEST_URI"] or similar predefined variables). You would need some sort of JavaScript magic on the client side, e.g. to include this value as a POST parameter.
So when you call :
localhost:8000/token#auth=123456
Your server get this :
localhost:8000/token
The browser delete everything from the hash (#) of your url, then it pass to the server http process
I am trying to do a redirect with query parameters, using the redirect() helper:
$link = 'https://example.com' . '?key1=value1&key2=value2';
return redirect()->to($link);
The problem is that when the $link is passed to the to() method Laravel removes the question mark leading the query string, so it turns this:
https://example.com?key1=value1&key2=value2
into this:
https://example.comkey1=value1&key2=value2
(again, notice the missing ? in the final link).
How do I make a redirect with query params appended to a custom URL?
Use:
return redirect($link);
If you want to redirect a named route with query string, use:
return redirect()->route('route_name',['key'=> $value]);
Documentation
The approved answer explains it all, according to the documentation. However, if you are still interested in finding some kind of "hard-coded" alternative:
$link = "https://example.com?key1={$value1}&key2={$value2}";
Then,
return redirect($link);
Reference
If the link is to a page on your domain, you don't need to re-write the domain name, just:
$link = "?key1=${value1}&key2=${value2}";
Laravel will automatically prepend the URL with your APP_URL (.env)
If you're building a Single Page Application (SPA) and you want to redirect to a specific page within your app from a server request, you can use the query method from the Arr helper class. Here is an example:
$result = Arr::query([
'result' => 'success',
'code' => '200'
]);
return redirect("/purchase?$result");
This will redirect the user to the /purchase page with the query parameters result=success and code=200.
For example, the final url would be:
http://example.com/purchase?result=success&code=200
I have a URL like http://localhost:8000/assessment/3/199
Where 3 represents assignment id and 199 represents assessor id, in short they both represents two models.
I'm sending such URL into email. I want to first encrypt the URL and then send it to the email.
I want URL like http://localhost:8000/assessment/{some-long-random-string}
So, I want to merge both the parameters, make an encrypted string, send into email, upon accessing the URL decrypt it and get both actual parameters.
I would like a solution which uses Laravel to implement that.
May be using these:
https://laravel.com/docs/5.3/encryption
https://laravel.com/docs/5.3/hashing
The way I would tackle this, is by manually implementing it in a controller.
Generate the URL like this:
$url = URL::action('AssessmentController#decrypt', json_encode([
'assessment' => $assessment_id,
'assessor' => $assessor_id
]);
//now, use $url in your email
Create a route like:
Route::get('/assessment/{ciphertext}', 'AssessmentController#decrypt');
In the controller:
public function decrypt($ciphertext){
$params = json_decode(decrypt($ciphertext));
return $this->getAssessment($params['assessment'], $params['assessor']);
}
Of course, you will need more integrity-checks and some error handling, but you probably get the idea.
I am using Laravel 4.
I have an old url that needs to be routable. It doesn't really matter what it's purpose is but it exists within the paypal systems and will be called regularly but cannot be changed (which is ridiculous I know).
I realise that this isn't the format url's are supposed to take in Laravel, but this is the url that will be called and I need to find a way to route it:
http://domain.com/forum/index.php?app=subscriptions&r_f_g=xxx-paypal
(xxx will be different on every request)
I can't figure out how to route this with laravel, i'd like to route it to the method PaypalController#ipbIpn so i've tried something like this:
Route::post('forum/index.php?app=subscriptions&r_f_g={id}-paypal', 'PaypalController#ipbIpn');
But this doesn't work, infact I can't even get this to work:
Route::post('forum/index.php', 'PaypalController#ipbIpn');
But this will:
Route::post('forum/index', 'PaypalController#ipbIpn');
So the question is how can I route the url, as it is at the top of this question, using Laravel?
For completeness I should say that this will always be a post not a get, but that shouldn't really make any difference to the solution.
Use this:
Route::post('forum/{file}', 'PaypalController#ipbIpn');
And then in the controller, use
public function forum($file) {
$request = Route::getRequest();
$q = (array) $request->query; // GET
$parameters = array();
foreach($q as $key => $pararr) {
$parameters = array_merge($parameters, $pararr);
}
}
You can then access the get parameters via e.g.
echo $parameters['app'];
you can use route redirection to mask and ending .php route ex:
Route::get('forum/index', ['uses'=> 'PaypalController#ipbIpn']);
Route::redirect('forum/index.php', 'forum/index');
EDIT: See below for my current problem. The top portion is a previous issue that I've solved but is somewhat related
I need to modify the input values passed to my controller before it actually gets there. I am building a web app that I want to be able to support multiple request input types (JSON and XML initially). I want to be able to catch the input BEFORE it goes to my restful controller, and modify it into an appropriate StdClass object.
I can't, for the life of me, figure out how to intercept and modify that input. Help?
For example, I'd like to be able to have filters like this:
Route::filter('json', function()
{
//modify input here into common PHP object format
});
Route::filter('xml', function()
{
//modify input here into common PHP object format
});
Route::filter('other', function()
{
//modify input here into common PHP object format
});
Route::when('*.json', 'json'); //Any route with '.json' appended uses json filter
Route::when('*.xml', 'xml'); //Any route with '.json' appended uses json filter
Route::when('*.other', 'other'); //Any route with '.json' appended uses json filter
Right now I'm simply doing a Input::isJson() check in my controller function, followed by the code below - note that this is a bit of a simplification of my code.
$data = Input::all();
$objs = array();
foreach($data as $key => $content)
{
$objs[$key] = json_decode($content);
}
EDIT: I've actually solved this, but have another issue now. Here's how I solved it:
Route::filter('json', function()
{
$new_input = array();
if (Input::isJson())
{
foreach(Input::all() as $key => $content)
{
//Do any input modification needed here
//Save it in $new_input
}
Input::replace($new_input);
}
else
{
return "Input provided was not JSON";
}
});
Route::when('*.json', 'json'); //Any route with '.json' appended uses json filter
The issue I have now is this: The path that the Router attempts to go to after the filter, contains .json from the input URI. The only option I've seen for solving this is to replace Input::replace($new_input) with
$new_path = str_replace('.json', '', Request::path());
Redirect::to($new_path)->withInput($new_input);
This however leads to 2 issues. Firstly I can't get it to redirect with a POST request - it's always a GET request. Second, the data being passed in is being flashed to the session - I'd rather have it available via the Input class as it would be with Input::replace().
Any suggestions on how to solve this?
I managed to solve the second issue as well - but it involved a lot of extra work and poking around... I'm not sure if it's the best solution, but it allows for suffixing routes similar to how you would prefix them.
Here's the github commit for how I solved it:
https://github.com/pcockwell/AuToDo/commit/dd269e756156f1e316825f4da3bfdd6930bd2e85
In particular, you should be looking at:
app/config/app.php
app/lib/autodo/src/Autodo/Routing/RouteCompiler.php
app/lib/autodo/src/Autodo/Routing/Router.php
app/lib/autodo/src/Autodo/Routing/RoutingServiceProvider.php
app/routes.php
composer.json
After making these modifications, I needed to run composer dumpautoload and php artisan optimize. The rest of those files are just validation for my data models and the result of running those 2 commands.
I didn't split the commit up because I'd been working on it for several hours and just wanted it in.
I'm going to hopefully look to extend the suffix tool to allow an array of suffixes so that any match will proceed. For example,
Route::group(array('suffix' => array('.json', '.xml', 'some_other_url_suffix')), function()
{
// Controller for base API function.
Route::controller('api', 'ApiController');
});
And this would ideally accept any call matching
{base_url}/api/{method}{/{v1?}/{v2?}/{v3?}/{v4?}/{v5?}?}{suffix}`
Where:
base_url is the domain base url
method is a function defined in ApiController
{/{v1?}/{v2?}/{v3?}/{v4?}/{v5?}?} is a series of up to 5 optional variables as are added when registering a controller with Route::controller()
suffix is one of the values in the suffix array passed to Route::group()
This example in particular should accept all of the following (assuming localhost is the base url, and the methods available are getMethod1($str1 = null, $str2 = null) and postMethod2()):
GET request to localhost/api/method1.json
GET request to localhost/api/method1.xml
GET request to localhost/api/method1some_other_url_suffix
POST request to localhost/api/method2.json
POST request to localhost/api/method2.xml
POST request to localhost/api/method2some_other_url_suffix
GET request to localhost/api/method1/hello/world.json
GET request to localhost/api/method1/hello/world.xml
GET request to localhost/api/method1/hello/worldsome_other_url_suffix
The last three requests would pass $str1 = 'hello' and $str2 = 'world' to getMethod1 as parameters.
EDIT: The changes to allow multiple suffixes was fairly easy. Commit located below (please make sure you get BOTH commit changes to get this working):
https://github.com/pcockwell/AuToDo/commit/864187981a436b60868aa420f7d212aaff1d3dfe
Eventually, I'm also hoping to submit this to the laravel/framework project.