Laravel get route by locale - php

Currently, I've got the following route in my web app.
Route::get(__('routes.account.dogs'),
[DogController::class, 'index'])->name('dog.index')->middleware('auth');
I specify the URL translation for the route in two different language files.
return [
//Account
'account' => [
'dogs' => 'honden',
]
];
When I send a queued email with this link, I want to translate the link on the user's locale (saved in the database). So I want to get this route based on the user's locale, but app()->setLocale($user->locale); cannot be used because it's a queued job. How can I fix this?
In a perfect world it would be something like:
route('dog.index', [], $user->locale);

laravel __() helper function also accepts the optional 3rd argument $locale for setting the locale to translate.
So you could use the $user->locale in the helper as follows.
url(__('account.dogs', [], $user->locale));

As #Vincent Decaux suggested, you need a library to make your life easier. You could use the one they use or the one I use arcanedev/localization.
Once you set a middleware, everything will be taken care of. But I am concerned regarding your comment:
Yes indeed! but then I still need to do something with the domain. For example .de or .com
Why not use the current domain (.com?) and simply add a directory /en or whatever locale you need instead? It seems inconvenient to me to change the entire domain.

When you use Mail::to(), you can use locale() to choose the translation
Mail::to($user->email)
->locale($user->locale)
->queue(new YourEmail());
https://laravel.com/docs/9.x/mail#localizing-mailables

Related

PHP, JWT passthrough path and method

I'm building an application via slim framework and it's slim-jwt-auth middleware.
I installed it, and it works fine but I'm a bit confused with the passthrough possibility.
My RequestPathRule:
new \Slim\Middleware\JwtAuthentication\RequestPathRule([
"path" => ["/api"],
"passthrough" => ["/api/auth", "/api/users", "/api/products", "/api/orders", "/api/streets",
"/api/reservations", "/api/feedbacks", "api/menu"]
])
And my RequestMethodRule:
new \Slim\Middleware\JwtAuthentication\RequestMethodRule([
"passthrough" => ["POST", "GET"]
])
But it allows these methods to all endpoints. Actually, I want to let POST only to /api/auth, /api/orders, /api/reservations and /api/feedbacks, and GET for every endpoint except /api/users.
How is this possible?
Thank you in advance.
It would be interesting to see which are your routes, but basically in your current configuration your are saying:
1) DON'T Authenticate "/api/auth", "/api/users", "/api/products", "/api/orders", "/api/streets", "/api/reservations", "/api/feedbacks" and "api/menu" (rest of endpoints under /api MUST be authenticated)
2) AND also dont authenticate whatever POST or GET request
some examples:
PUT /api/users NEVER will be authenticate since /api/users is in
RequestPathRule
GET /api/users NEVER will be authenticate since /api/users is in
RequestPathRule AND GET is in RequestMehtodRule
PUT /api/whatever ALWAYS will be authenticate since /api/users is
NOT in RequestPathRule AND GET is NOT in RequestMethodRule
Basically rules work like an OR comparison operator and in the right moment an endpoint is in RequestPathRule OR a request method is in RequestMethodRule the request will be not authenticated.
A better approach could be trying not to use RequestMethodRule as much as possible (generally you just include OPTIONS method) and play with different paths.
In a normal web application you will provide a public API path to your clients under /api and the only endpoint you don't generally authenticate is /api/login (or /api/auth in your example) the rest of the endpoint under /api are authenticated. If your provide another set of endpoints which you don't want to authenticate you provide another different path like /service and your don't include it as "path" in RequestPathRule. If you need a set of endpoint ALL authenticated you create all of then under a new path, let's say /admin and you include on path in RequestPathRule and you don't add any "passthrough" for them.
So the idea is play with different path and just add those methods under RequestMethodRule for specific use cases. Moreover, in that way you will have a better clear and organized API.
Looking at your endpoints I recommend you create different path for most of them, so instead of having "/api/auth", "/api/users", "/api/products", "/api/orders" I would suggest you to have "/auth", "/user", "/product", "/order"... and you can add a RequestPathRule and RequestMethodRule for every path.
To be honest, as the slim-jwt-auth middleware is thought, it's difficult to provide CRUD operations over same endpoint, let's say you have GET, POST, PUT and DELETE over /user and you want just authenticate POST, PUT and DELETE. For that case you could have 2 options:
create differen endpoint for each verb like: GET /user/all, POST /user/add, PUT /user/edit and DELETE /user/delete (which is a bad practice
Create or extend your RequestPathRule and RequestMethodRule callable with the only conditions that they must implement RuleInterface and adapt them to your needs (highly recommended)
If you choose the 2nd option you only have to add those callable to the rules option. Something like this:
$app->add(new \Slim\Middleware\JwtAuthentication([
"rules" => [
new \My\Auth\Rules\RequestPathRule([
"path" => "/",
"passthrough" => []
]),
new \My\Auth\Rules\RequestMethodRule([
"passthrough" => ["OPTIONS"]
])
]
]));

cakephp 3 prefix routing

I'm trying to set up a routing prefix in cakephp 3 so any URLs starting with /json/ get the prefix key set and I can change the layout accordingly in the app controller. Other than that, they should use the usual controller and action. I have added the following to routes.php
$routes->prefix('json', function($routes) {
$routes->connect(
'/:controller/:action/*',
[],
['routeClass' => 'InflectedRoute']
);
});
I want to direct all requests with json as first url segment to controller specified in second url segment. e.g. /json/users/add_account_type/ goes to users controller. However when accessing this URL I get the message:
Error: Create the class UsersController below in file:
src/Controller/Json/UsersController.php
whereas I want it to be using
src/Controller/UsersController.php
I think this should be possible but I can't quite see what I'm doing wrong when consulting the book. Have partly based my code on: CakePHP3.x controller name in url when using prefix routing
Thanks a lot in advance
That's simply how prefix routing now works in 3.x, as explained in the docs, prefixes are being mapped to subnamespaces, and thus to separate controllers in subfolders.
http://book.cakephp.org/3.0/en/development/routing.html#prefix-routing
If you'd wanted to change that behavior (I don't really see why), one way would be to implement a custom ControllerFactory dispatcher filter.
http://book.cakephp.org/3.0/en/development/dispatch-filters.html
On a side note, the RequestHandler component supports layout/template switching out of the box, so maybe you should give that a try.
http://book.cakephp.org/3.0/en/controllers/components/request-handling.html
http://book.cakephp.org/3.0/en/views/json-and-xml-views.html
Prefix routing is a way of namespacing parts of your routes to a dedicated controller. It seem that what you want is a scope and not a prefix, for what you describe:
Router::scope('/json', function($routes) {
$routes->fallbacks('InfledtedRoute')
});

Route with name "HelloWorld" not found Zend Framework 2

I have created a new module in ZF2 named 'HelloWorld'. What I am trying to do is, simply printing HelloWorld when I click on the link 'HelloWorld':
I want to generate this link(http://mayukh.my.phpcloud.com/zf2test/HelloWorld/) by using this:
$this->url('HelloWorld', array('action' => 'index'))
But it is showing the error like this:
http://mayukh.my.phpcloud.com/zf2test/
Please suggest how to avoid this error..
This is perhaps related to one of ZF2’s “features.” It seems that if you use ZF2 functions to construct your links, the function will drop out any segment that matches the default value you have named in your router script. See How to write the ZF2 router script to allow parameters on the default action.
Temporarily change or remove the defaults from your router script and see if that doesn’t solve your issue. If it does, you might have to either reconsider the scheme for your router scripts or code your links without ZF2’s url function.

multilanguage database driven website with laravel4

im messing around with laravel to do a multilanguage website.
I am trying to implement this:
$languages = array('en','fr');
$locale = Request::segment(1);
if(in_array($locale, $languages)){
\App::setLocale($locale);
}else{
$locale = null;
}
Route::group(array('prefix' => $locale), function()
{
Route::get('/', 'Homecontroller#index');
Route::get('contact', 'Homecontroller#contact');
});
for what i can see, everythings works fine,
I understand, Laravel take locale from my url segment, check if it's in languages, if is not null he change the routing adding the prefix. I have 2 question:
1) Why all my images now is not showed properly anymore, when i go to en/contact, while when i go to en/ I can see them.
2) to use a database to pick up languages, i don't necessarly have to change App:setLocale, but i need to do a model to extract language to database and put in the right place?
3) how to pass the variable languages to blade, so i can change the description of the product?? (I used to do ?lang=en and then take it with a $_GET
Sorry i know maybe this is just a basic question, but i come from pure php and pure mysql background.
EDIT:
1) I need to use the HTML:: image facade like {{HTML::image('path')}}
To me it seems like you are linking to your images with relative
paths which will break when you start to have a different structure
in your URL. So try having absolute URL:s in your image src tags or
make them start with a slash (/). E.g. {{ HTML::image('/absolute/path/to/image.jpg') }}
I'm not sure if I understand your question, but you want to store your translations in the database instead of in files which is the default? Maybe this could be something for you: https://github.com/Waavi/translation
This is doable in a lot of different ways. For example you could
just call {{{ Request::segment(1) }}} in your blade template and
get your language (assuming it's segment number 1). But the neatest
way would probably be to wrap it in a function and put it in an appropriate place according to your application's structure.

How do I generate a friendly URL in Symfony PHP?

I always tend to forget these built-in Symfony functions for making links.
If your goal is to have user-friendly URLs throughout your application, use the following approach:
1) Create a routing rule for your module/action in the application's routing.yml file. The following example is a routing rule for an action that shows the most recent questions in an application, defaulting to page 1 (using a pager):
recent_questions:
url: questions/recent/:page
param: { module: questions, action: recent, page: 1 }
2) Once the routing rule is set, use the url_for() helper in your template to format outgoing URLs.
Recent Questions
In this example, the following URL will be constructed: http://myapp/questions/recent/1.html.
3) Incoming URLs (requests) will be analyzed by the routing system, and if a pattern match is found in the routing rule configuration, the named wildcards (ie. the :/page portion of the URL) will become request parameters.
You can also use the link_to() helper to output a URL without using the HTML <a> tag.
This advice is for symfony 1.0. It probably will work for later versions.
Within your sfAction class:
string genUrl($parameters = array(), $absolute = false)
eg.
$this->getController()->genUrl('yourmodule/youraction?key=value&key2=value', true);
In a template:
This will generate a normal link.
string link_to($name, $internal_uri, $options = array());
eg.
link_to('My link name', 'yourmodule/youraction?key=value&key2=value');
In addition, if you actually want a query string with that url, you use this:
link_to('My link name', 'yourmodule/youraction?key=value&key2=value',array('query_string'=>'page=2'));
Otherwise, it's going to try to route it as part of the url and likely break your action.
You can generate URL directly without define the rule first.
If you want to generate URL in the actions, you can use generateUrl() helper:
$this->generateUrl('default', array('module'=>'[ModuleName]','action'=>'[ActionName]'))
If you want to generate URL in the templates, you can use url_for() helper:
url_for('[ModuleName]/[ActionName]', $absolute)
set $absolute as true/false, dont forget to use echo if you want to display it.
But if you want to make a link (something like ), link_to() helper will do.

Categories