1

I am trying to use this package to push notifications to users via OneSignal. However I needed to make a little change. My API serves two (related) apps and I have two OneSignal configs. I am trying to override its ServiceProvider (using this technique).

The ServiceProvider presents itself as follows

<?php

namespace NotificationChannels\OneSignal;

use Berkayk\OneSignal\OneSignalClient;
use Illuminate\Support\ServiceProvider;
use NotificationChannels\OneSignal\Exceptions\InvalidConfiguration;

class OneSignalServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     */
    public function boot()
    {
        $this->app->when(OneSignalChannel::class)
            ->needs(OneSignalClient::class)
            ->give(function () {
                $oneSignalConfig = config('services.onesignal');

                if (is_null($oneSignalConfig)) {
                    throw InvalidConfiguration::configurationNotSet();
                }

                return new OneSignalClient(
                    $oneSignalConfig['app_id'],
                    $oneSignalConfig['rest_api_key'],
                    ''
                );
            });
    }
}

The behavior that I want to change is located in the line

$oneSignalConfig = config('services.onesignal');

As it assumes that my config/services.php has the following entry (stated in the doc) :

// config/services.php
...
'onesignal' => [
    'app_id' => env('ONESIGNAL_APP_ID'),
    'rest_api_key' => env('ONESIGNAL_REST_API_KEY')
],
...

Whereas I want to set my config/services.php as follows

// config/services.php
...
'onesignal' => [
        'app1' => [
            'app_id' => env('ONESIGNAL_1_APP_ID'),
            'rest_api_key' => env('ONESIGNAL_1_REST_API_KEY')
        ],
        'app2' => [
            'app_id' => env('ONESIGNAL_2_APP_ID'),
            'rest_api_key' => env('ONESIGNAL_2_REST_API_KEY')
        ],
    ],
...

And I want somehow to tell my ServiceProvider (through some kind of parameter) to either do

$oneSignalConfig = config('services.onesignal.app1');

OR

$oneSignalConfig = config('services.onesignal.app2');

But I didn't find any way to pass a parameter to the class, the boot function or the give method (and if I understood well I shouldn't even be doing that).

The only way I could think of is to create two classes that extend the OneSignalChannel::class and duplicate code in the boot function so it becomes as follows :

    public function boot()
    {
        $this->app->when(FirstOneSignalChannel::class)
            ->needs(OneSignalClient::class)
            ->give(function () {
                $oneSignalConfig = config('services.onesignal.app1');

                if (is_null($oneSignalConfig)) {
                    throw InvalidConfiguration::configurationNotSet();
                }

                return new OneSignalClient(
                    $oneSignalConfig['app_id'],
                    $oneSignalConfig['rest_api_key'],
                    ''
                );
            });
        $this->app->when(SecondOneSignalChannel::class)
            ->needs(OneSignalClient::class)
            ->give(function () {
                $oneSignalConfig = config('services.onesignal.app2');

                if (is_null($oneSignalConfig)) {
                    throw InvalidConfiguration::configurationNotSet();
                }

                return new OneSignalClient(
                    $oneSignalConfig['app_id'],
                    $oneSignalConfig['rest_api_key'],
                    ''
                );
            });
    }

The difference in the when provoking a difference in the config but it seems a lot of duplication and not extensible (what if I had three apps).

Should I use this method, or is there a way to pass a parameter to this ServiceProvider or is there another solution ?

Fayçal Borsali
  • 402
  • 4
  • 17

1 Answers1

1

https://stackoverflow.com/a/34224082/10371024

I could see what you need, but to pass parameter to boot method is not a good idea according to Laravel architecture. You may try to get what you want with using events as Vladislav suggested.

  • Thank you for your answer. Thank you for the link and explanation, I am working on something similar thanks to [this thread](https://laracasts.com/discuss/channels/laravel/laravel-6-pass-a-parameter-to-app-when-needs-give?page=1#reply=651942) and I will post an explanatory answer if possible – Fayçal Borsali Oct 11 '20 at 23:27