I have a service named setting which fetches use's preference from somewhere. I need use it in configuring some other service. For example I need to get user's email address email host.
Using 'host' => app('setting')['email']['host']), in config/mail.php file,
does not work. It seems that the app() services are not accessible in that stage.
What is the correct way to do that?
You could change a config at runtime within a service provider.
Let's just use the app/Providers/AppServiceProvider which is shipped with Laravel. So in the boot() method you could do any changes to the config like this:
public function boot()
{
$this->app->make('config')->set('whatever.config', 'This has changed');
}
Related
im using a package called https://github.com/garygreen/pretty-routes
there is line in its service provider boot() method (here the code)
it is defining a get route with middlewares from its config file(link to the code) I just added 'auth:web' to its config file but it seems the 'auth:web' middleware is called as soon as code reaches the line before Laravel bootstraps its session and etc. when the auth('web')->user() is yet null
What I can not understand is that I do the same exact thing (here the code)with laravel/telescope but it works. why ???
also changing :
Route::get(config('pretty-routes.url'), 'PrettyRoutes\PrettyRoutesController#show')
->name('pretty-routes.show')
->middleware(config('pretty-routes.middlewares'));
to :
$this->app['router']->get(config('pretty-routes.url'), 'PrettyRoutes\PrettyRoutesController#show')
->name('pretty-routes.show')
->middleware(config('pretty-routes.middlewares'));
in service provider seems to solve the problem and make this code behave like the way telescope package use 'auth:web' as middleware.
what's happening ?
You need to have the web middleware applied to any routes you need sessions for, which is what the default authentication system is using. When you apply the auth middleware without this it can't possibly resolve a user since there is no session to be authenticated against.
You need to apply the web middleware and then what ever other middleware you want:
'middlewares' => [
'web', 'auth:web',
],
If you look at the telescope example you provided you will see they also add the web middleware. So you didn't quite "do the same exact thing" as the telescope config.
So I am developing a composer package, that adds several of my reusable code to a fresh Laravel project. So far I've managed to add core translation files and some models, routes in my service provider with $this->publishes() and $this->loadRoutesFrom() in my boot() method.
Now I want to add Gates to that package, but I'm stuck. Somehow I should register these in the project's AuthServiceProvider on run. Would be very nice if anyone could give me some advice how to perform this task.
If you want to register policies, there is no need to use the AuthServiceProvider, you can simply use Illuminate\Support\Facades\Gate::policy($key, $value).
You can do that in your own ServiceProvider of your package. If you want to define abilities, you can add a boot method like this:
use Illuminate\Contracts\Auth\Access\Gate as GateContract;
// ...
public function boot(GateContract $gate)
{
$gate->define('update-post', function ($user, $post) {
return $user->id === $post->user_id;
});
}
This will resolve the gate instance for you and allow you to define abilities. It's important to use the boot method, since this way you can be sure every service is already registered.
I'm coding a platform to generate sub-websites.
I have a route like this who works very well in local :
//Website
Route::domain('{slug}.domain.test')->group(function () {
Route::get('/','WebsitesController#show')->name('web_website_show');
});
I want to be able to make it works as well in production (other domain), so i did :
//Website
Route::domain('{slug}.{domain}')->group(function () {
Route::get('/','WebsitesController#show')->name('web_website_show');
});
And in my template :
Website
The generated URL looks amazing, but the routing doesn't work and bring me to the parent page of the main domain.
What i am doing wrong ?
Thanks
Working with domain routes like this is a little bit of a pain in Laravel.
In an application recently, I parsed the domain part from the application URL and then set it as a configuration value like this:
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
config([
'app.domain' => parse_url(config('app.url'), PHP_URL_HOST),
]);
}
}
You can then use that in your domain routes:
Route::domain('{slug}.'.config('app.domain'), function () {
// Subdomain routes that work in all environments
});
If you are using laravel homestead, you'll need to register every subdomain on the etc/hosts file and on Homestead.yaml, as you probably did with the main domain. Now, I'll recommend the structure:
app.test
subdomain1.app.test
subdomain2.app.test
I wouldn't recommend to use something like:
subdomain1.app1.test
subdomain2.app2.test
I mean, you could, but it doesn't make much sense, and you would also have to register all of this on your Homestead/Local and Production environments.
For the approach that I suggest, you could set up this on an environment variable. https://laravel.com/docs/6.x/configuration#environment-variable-types
You can add any env variable you want/need to the .env file, there's an APP_URL variable, but this includes the http protocol, you could add something like:
APP_DOMAIN=app.test
And for production
APP_DOMAIN=yourapp.com
Then on the routes file access it with the helper method env, you can omit the second parameter, or use it to setup a default value, in case you forget to put it on the .env file.
Route::domain('{slug}.' . env('APP_DOMAIN', 'default.com'))->group(function () {
Route::get('/','WebsitesController#show')->name('web_website_show');
});
BTW, this might be of help for setting up your slug value with named routes:
Setting up named routes within a subdomain group in Laravel 5.7
I am using laravel 5.2.
I would like to be able to change a parameter in the .env file like PASSWORD_VALIDATION=...
This could be either LARAVEL or PERSONAL.
If it is LARAVEL then it would use the standard Laravel authentication method with users and passwords in the db. But if I use PERSONAL, I would like that it uses a function I have created that will check if the email address is in the database then verify the password provided with the Active Directory in my company.
I looked at the various files and I can see I have:
app\Http\Controllers\Auth\AuthController.php
In there, I can see:
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
In this file:
vendor\laravel\framework\src\Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers.php
It uses
use AuthenticatesUsers, RegistersUsers {
AuthenticatesUsers::redirectPath insteadof RegistersUsers;
AuthenticatesUsers::getGuard insteadof RegistersUsers;
So I can see in the file
vendor\laravel\framework\src\Illuminate\Foundation\Auth\AuthenticatesUsers.php
My function to be changed which is:
public function postLogin(Request $request)
{
return $this->login($request);
}
I have tried to copy this one in my file app\Http\Controllers\Auth\AuthController.php but it doesn't change anything if I modify what is inside it...
Thanks
Ok, I found out why, it seems that in my routes, it is pointing to #login and not to #postLogin hence any modification applied to the function postLogin wouldn't do anything
My session config file says to use memcached, but all artisan commands are loading the "array" driver instead. I'm writing a web sockets application with Ratchet and need to connect to Memcached to get the user's session information, but seems to ignore my config.
Where and how does Laravel determine which session drivers to use for Artisan commands?
According to Illuminate\Support\ServiceProvider\SessionServiceProvider::setupDefaultDriver() Laravel will set the session driver to array if running in console.
You can easily override this by registering your custom service provider. Create a custom service provider, extend the default session service provider and override the method setupDefaultDriver). Here is my custom service provider for example:
<?php namespace App\Console;
use Illuminate\Session\SessionServiceProvider as DefaultSessionProvider;
class SessionServiceProvider extends DefaultSessionProvider
{
protected function setupDefaultDriver() {}
}
Then open up config/app.php and replace 'Illuminate\Session\SessionServiceProvider' with 'App\Console\SessionServiceProvider'.
Now artisan will also use the same session storage as Laravel app.
Since you are trying to attach the session to Ratchet, You can directly inject this session instance into Ratchet app:
$session = new \Ratchet\Session\SessionProvider(
new MyCustomRatchetApp(),
$this->getLaravel()['session.store']
);
$server = new \Ratchet\App('localhost');
$server->route('/sessDemo', $session);
$server->run();
Gufran posted a good answer, but another solution which doesn't involve swapping out a service provider, it just to set the default driver manually in your artisan command (or tests).
Like so: Session::setDefaultDriver('memcached');. You can do the same for cache: Cache::setDefaultDriver('memcached');. You do this before doing any other commands, of course, so that it doesn't start using the array.
If you need to, you can manually put in connection information: Config::set('cache.memcached', array(array('host' => '127.0.0.1', 'port' => 12345, 'weight' => 100)));