laravel request return message keys translations - laravel

I have a Laravel Application and another APP making calls via API to Laravel. These 2 projects are separated.
Laravel and App have their own multilanguage system. They work independently but uses the same key translations.
So my idea was that all Laravel responses must be translations key, like: 'messages.success'.
With this response, the App can translate it.
All of these are working fine.
The problem appeared when I started working with Laravel Requests for validating forms.
In this case, the validation errors are automatically translated so the App receives the response translated with the default language of the Laravel application.
So what can I do?
I thought with 2 ideas but I don't know if they can work.
1: Passing the language into params. Don't know if it can work, how can I set the language before Laravel validates the Request?
2: Override the functionality of Requests to return messages without translate, so instead of "Felicidades" return "messages.success". I really like this approach. But how can I do it for all the rules? Overriding the messages function like this:
public function messages()
{
return [
'unique' => 'validation.unique'
];
}
For every rule works... but I feel bad.
Another approaches?
What is the best way to fix this problem?

I would suggest that you use this hacky solution in 2 lines of code. Go to /resources/lang/{code}/validation.php. You can see that it returns an array of messages by default. Modify it like so:
// Replace return in the first line
$ret = [
/* all the translations go here as normal */
];
// Add this as the last line. This will replace all values with their keys.
return array_combine(array_keys($ret), array_keys($ret));
After that you can use validation as per usual and you'll get validation message keys instead of messages. Cheers and hope this helps.

Related

Laravel - retrieve data inside controller – POST x PATCH

First important information: I’m new to laravel, so your patience is appreciated.
I’m currently migrating a framework of mine to laravel, so I’m in the early stages.
Currently, I’m trying to set up an API endpoint to make small changes on some records. I’ve already managed to set up a API for inserting records and works perfectly. However, for setting up an API for small changes (patch), I’m having difficulties, probably because I’m not fully familiar with laravel’s Request class.
My successful insert set up looks like this:
\routes\api.php
Route::post('/categories/',[ApiCategoriesInsertController::class, 'insertCategories'], function($insertCategoriesResults) {
return response()->json($insertCategoriesResults);
})->name('api.categories.insert');
\app\Http\Controllers\ApiCategoriesInsertController.php
// some code
public function insertCategories(Request $req): array
{
$this->arrCategoriesInsertParameters['_tblCategoriesIdParent'] = $req->post('id_parent');
// some code
}
With this set up, I’m able to retrieve “id_parent” data set through POST.
So, I tried to do exactly the same architecture for patch, but doesn’t seem to work:
\routes\api.php
Route::patch('/records/',[ApiRecordsPatchController::class, 'patchRecords'], function($patchRecordsResults) {
return response()->json($patchRecordsResults);
})->name('api.records.patch');
\app\Http\Controllers\ApiRecordsPatchController.php
// some code
public function patchRecords(Request $req): array
{
$this->arrRecordsPatchParameters['_strTable'] = $req->post('strTable');
// some code
}
In this case, I´m using postman (PATCH request), testing the data in the "Body tab" with key "strTable" and value "123xxx" and I´m receiving “strTable” as null.
Any idea of why this is happening or if I should use another method in the Request class?
Thanks!
You can access parameters on the Request object using one of the following methods:
$req->strTable;
// or
$req->input('strTable');
The input method also accepts a second parameter which will be used as the default return value if the key is not present in the Request.
If you want to check whether or not the Request contains a value before you attempt to access it, you can use filled:
if ($req->filled('strTable')) {
// The request contains a value
}
Turns out that the way I had set up was in fact working and retrieving data:
$req->post('strTable');
The problem was in how I was testing it. In postman, there are several options to configure:
form-data
x-www-form-urlencoded
raw
binary
I had already switched to x-www-form-urlencoded to test it, but I forgot to fill the “key” and “value” information again. I didn’t realize that the fields blank as we switch between them.
Summing it up: It works when x-www-form-urlencoded selected but doesn’t work with form-data selected. Don’t know what the difference between them yet, but I’ll research it further.
By the way, it worked also with the suggestion from Rube Hart:

How does a Laravel controller method handle multiple Form Request parameters?

I am getting back to Laravel after several years and trying to understand how an already existing REST API coded in Laravel works. I can't understand how a particular controller method with multiple Form Request parameters works (or if it actually does).
The REST API was coded in Laravel 5.1. I've looked at the official documentation (both 5.1 and the latest) and tried to search the web and SO for related topics (e.g., "laravel controller multiple form requests", "laravel controller multiple type-hint requests", etc.), but I can't seem to find a clear explanation. Maybe I'm looking at it from a wrong angle.
public function store(ProductRequest $productRequest, PromoRequest $promoRequest)
{
// Validate product
$product = new Product($productRequest->all());
// Validate promo
if ($promoRequest->get('promo')) {
$promo = new Promo($promoRequest->get('promo'));
}
...
}
In most documentation, the controller would accept only one Request object. I did actually see some examples that have multiple Form Request parameters, but often they were recommended to use only one Form Request. But best practice aside, how does this code work? When this method is called, how does Laravel know how to split the Request into two separate Form Request classes?
Please feel free to let me know if and how I can explain my question more clearly.
you can write like this:
function example(Request $request) {
$productRequest = new ProductRequest($request->all());
$promoRequest = new PromoRequest($request->all());
}
but on validate you should change the way to this:
$data = $productRequest->validate($productRequest->rules());
another way that i test in laravel 8 is to add both form request object in methd parameters like :
function example(ProductRequest $productRequest,PromoRequest $promoRequest) {
$productRequest->validated();
$promoRequest->validated();
}
The Laravel service container is a powerful tool for managing class
dependencies and performing dependency injection. Dependency injection
is a fancy phrase that essentially means this: class dependencies are
"injected" into the class via the constructor or, in some cases,
"setter" methods.
You can read more about it here: https://laravel.com/docs/5.8/container
Edit: Additional question: Still, I can't understand how the HTTP request (which is only one) can be split into two different Request classes?
The HTTP request isn't split; it is merely sent through both classes.
Ex:
function example(Request $request) {
$productRequest = new ProductRequest($request);
$promoRequest = new PromoRequest($request);
}
Would be the same.

Laravel: form method != save method?

I am new to Laravel coming from CakePHP where the form and save method for a form is one and the same function name. I saw in many Laravel tutorials that the from method (that displays the form) is different than the method to save form (that actually saves data). Why using 2 different method names?
For example what's wrong with:
pub function xyz(Request $request)
{
if($results->isMethod('post')){
... then save and return redirect
}
... the code for showing the form in case there is no POST.
then having 2 routes one for GET and one for POST on the same url?
It is because people like to filter out things at route level not in controller, Also it helps developer to apply middleware grouping for each route separately. so that they can apply roles and permission etc. easily at route level.
It will looks horrible if mix all things in controller.
Think about middleware and groups in your code.
It is because you don't wanna mix a lot of logic in the same method . The case you have simple is the simple scenario . But there will be case where you wanna pass initial data in the create form . You have to write logic for that also in the same method and while you store the data you need to do the validation and calculate other business logic . If you combine all those things in one method it will mix all the things in one method and code difficult to read

Custom filters - how do I make them fail?

I'm creating a package that allows users to use a custom filter.
So far I have a method called:
public function testFilter(){
return false;
}
In my filters file, in my main app I have I have:
Route::filter('test.test', MyPackage::testFilter());
And in my routes, in my main app I have:
'before'=>'test.test'
My question is, how do I do the filtering, I've done a return false to try and make the filter fail, do I need something else, like app abort?
According to Laravel filters documentation
If the filter returns a response, that response is considered the response to the request and the route will not execute. Any after filters on the route are also cancelled.
That means you do have to return a Response to cancel your route from proceeding.
It'll probably more logical for you have another view to be displayed to your visitor when the filter fails, and this is what Laravel is trying to do.
You can use App::abort() for that or App::abort(404) (with error codes) to show error page.

How to pass route values to controllers in Laravel 4?

I am struggling to understand something that I am sure one of you will be able to easily explain. I am somewhat new to MVC so please bear with me.
I have created a controller that handles all of the work involved with connecting to the Twitter API and processing the returned JSON into HTML.
Route::get('/about', 'TwitterController#getTweets');
I then use:
return View::make('templates.about', array('twitter_html' => $twitter_html ))
Within my controller to pass the generated HTML to my view and everything works well.
My issue is that I have multiple pages that I use to display a different Twitter user's tweets on each page. What I would like to do is pass my controller an array of values (twitter handles) which it would then use in the API call. What I do not want to have to do is have a different Controller for each user group. If I set $twitter_user_ids within my Controller I can use that array to pull the tweets, but I want to set the array and pass it into the Controller somehow. I would think there would be something like
Route::get('/about', 'TwitterController#getTweets('twitter_id')');
But that last doesn't work.
I believe that my issue is related to variable scope somehow, but I could be way off.
Am I going down the wrong track here? How do I pass my Controllers different sets of data to produce different results?
EDIT - More Info
Markus suggested using Route Parameters, but I'm not sure that will work with what I am going for. Here is my specific use case.
I have an about page that will pull my tweets from Twitters API and display them on the page.
I also have a "Tweets" page that will pull the most recent tweets from several developers accounts and display them.
In both cases I have $twitter_user_ids = array() with different values in the array.
The controller that I have built takes that array of usernames and accesses the API and generates HTML which is passed to my view.
Because I am working with an array (the second of which is a large array), I don't think that Route Parameters will work.
Thanks again for the help. I couldn't do it without you all!
First of all, here's a quick tip:
Instead of
return View::make('templates.about', array('twitter_html' => $twitter_html ))
...use
return View::make('templates.about', compact('twitter_html'))
This creates the $twitter_html automatically for you. Check it out in the PHP Manual.
 
Now to your problem:
You did the route part wrong. Try:
Route::get('/about/{twitter_id}', 'TwitterController#getTweets');
This passes the twitter_id param to your getTweets function.
Check out the Laravel Docs: http://laravel.com/docs/routing#route-parameters

Resources