Reputation: 1400
In my notification service I have to send the notifications by mail, but in dev I want to send all the email to a specific adress:
if ( $this->container->get('kernel')->getEnvironment() == "dev" ) {
mail( '[email protected]', $lib, $txt, $entete );
} else {
mail( $to->getEmail(), $lib, $txt, $entete );
}
But the $this->container->get('kernel')->getEnvironment()
works only in a controller.
I think I have to add an argument in my service constructor:
notification:
class: %project.notification.class%
arguments: [@templating, @doctrine]
But I didn't find any information about this.
Upvotes: 37
Views: 77471
Reputation: 1379
You can now use autowiring using atributes:
use Symfony\Component\DependencyInjection\Attribute\Autowire;
class Something {
public function __construct(
#[Autowire('%kernel.environment%')]
private string $env,
) {}
}
Also, if you are using service dependent on env, it's generally nicer to swap services or decorate them. ( it's often though purist exercise )
So you would either have two services dev and non dev and inject one depending on env, or you would have decorator that is only added in one env.
If you are speaking strictly about email, though, using mailtrap or self hosted version is highly advised.
Upvotes: 0
Reputation: 522
You can get all environments in .env
file with $_ENV
superglobal, thanks to dotenv
$_ENV['APP_ENV']
Upvotes: 4
Reputation: 1666
If you use the Symfony Mailer component to send emails. You don't need to get the environment. Just define a new env variable that contains your specific address and put it in the EnvelopeListener
service.yaml
mailer.set_recipients:
class: Symfony\Component\Mailer\EventListener\EnvelopeListener
tags: ['kernel.event_subscriber']
arguments:
$sender: null
$recipients: '%env(json:ALL_MAIL_RECIPIENT)%'
.env
ALL_MAIL_RECIPIENT='[]'
.env.local
ALL_MAIL_RECIPIENT='["[email protected]"]'
Upvotes: 0
Reputation: 251
I would like to have a return of my code.
.env.local :
API_KEY_TOTO="azerty"
But it is possible to pass the environment variable in the service.yml file. Here is an example
config/services.yaml
App\Service\MyService:
bind:
$apiKeyToto: '%env(API_KEY_TOTO)%'
App\Service\MyService.php :
class MyService {
private $client;
private $apiKeyToto;
public function __construct(HttpClientInterface $client, string $apiKeyToto)
{
$this->client = $client;
$this->apiKeyToto= $apiKeyToto;
}
public function getAllRepository(): array
{
return $this->getApi('/users/{username}/repos?&type=all&direction=desc&per_page=100');
}
private function getApi(string $url)
{
$response = $this->client->request('GET', 'https://api.github.com' . $url, [
'auth_basic' => ['username', $this->apiKeyToto],
]
);
return $response->toArray();
}
}
If you have any other suggestions.
Upvotes: 0
Reputation: 1708
In symfony you can bind default value by $variableName.
config/services.yaml
services:
_defaults:
bind:
$kernelEnvironment: '%kernel.environment%'
NotificationService.php
private $env;
public function __construct($kernelEnvironment)
{
$this->env = $kernelEnvironment;
}
Upvotes: 2
Reputation: 4154
Actually you should not need to get the actual environment. For example if you need to send slack notifications only on production you can configure send_slack_notification
parameter and set it to true/false in the different environments.
Then in your code you can do something like:
if ($parameters->get('send_slack_notification') == true) {
//send the notifications
}
By using this approach you can later turn on/off this setting in different environments without changing your implementation. Another benefit is that when you check your parameters file you can right away see all the options in the different environments and this will make debugging easier.
NOTE
KernelInterface $kernel->getEnvironment()
can return both lowercase and uppercase results depending on how you've configured in your .env files. Another reason why you should't use it.
Upvotes: 2
Reputation: 89
If you are into a static class and don't have access to the container, you always can do this inside the AppKernel.php->registerBundles():
$_ENV['APP_ENV'] = $this->getEnvironment();
That way you will always have the environment inside the superglobal $_ENV.
It's kinda a hack, but works like a charm.
Upvotes: 0
Reputation: 909
For Symfony 4 you could do:
use Symfony\Component\HttpKernel\KernelInterface;
class SomeService
{
/**
* @var string
*/
private $environment;
/**
* Your Service constructor.
*/
public function __construct(KernelInterface $kernel)
{
$this->environment = $kernel->getEnvironment();
}
}
$this->environment now holds your environment like dev, prod or test.
Upvotes: 39
Reputation: 1852
In Symfony 4 (maybe 3.x, too) you can fetch the environment in a controller like this:
$env = $this->getParameter('kernel.environment');
(No explicit controller injection via services.yaml needed)
Upvotes: 8
Reputation: 1591
There is no need to inject container. In fact, it is not a good idea to inject container because you're making your class dependent on the DI.
You should inject environment parameter:
services.yml
notification:
class: NotificationService
arguments: ["%kernel.environment%"]
NotificationService.php
<?php
private $env;
public function __construct($env)
{
$this->env = $env;
}
public function mailStuff()
{
if ( $this->env == "dev" ) {
mail( '[email protected]', $lib, $txt, $entete );
} else {
mail( $to->getEmail(), $lib, $txt, $entete );
}
}
Upvotes: 70
Reputation: 651
The reason you can get $this->container in a controller is because it is injected into the controller that you extend.
For example, you could inject in the container and set it up in your constructor.
services.yml
notification:
class: %project.notification.class%
arguments: [@templating, @doctrine]
NotificationService.php
<?php
private $container;
public function __construct()
{
$this->container = $container;
}
public function mailStuff()
{
if ( $this->container->get('kernel')->getEnvironment() == "dev" ) {
mail( '[email protected]', $lib, $txt, $entete );
} else {
mail( $to->getEmail(), $lib, $txt, $entete );
}
}
Have a look at dependency injection for more information.
PLEASE NOTE
Generally, injecting in the container is bad and means there is a better way to do something. In this case, Symfony already has the solution that we're trying to solve.
Enter SwiftMailer.
And specifically, the section on sending all dev emails to a set address.
Give it a go at setting up Swiftmailer and add the following to your dev config.
app/config/config_dev.yml
swiftmailer:
delivery_address: '[email protected]'
Upvotes: 5