Erweitern Sie Laravel mit unseren eigenen Komponenten

Aufgabe


Fügen Sie Benutzern über SMS-Nachrichten ein Warnsystem hinzu, und wählen Sie einen Anbieter aus.

Entscheidung


Die beste Lösung ist meiner Meinung nach, eine eigene Komponente hinzuzufügen.
Eine Komponente ist ein Programmblock mit genau definierten Aktionen (Vertrag), mit denen die ihr über verschiedene Treiber zugewiesenen Aufgaben gelöst werden können. Zum Beispiel können die integrierte Komponente Cache die Treiber verwenden: file, memcachedoder redis.

Beim Bau unserer Komponente wenden wir das Prinzip des Brückendesigns an, auf dem auch Laravel-Komponenten basieren.

Also lasst uns anfangen.

Treiber


Wie eines der Postulate sagt: Programm in Übereinstimmung mit der Schnittstelle und nicht mit der Implementierung.

Wir werden damit beginnen, aber im Kontext der Komponente ist es genauer, den Begriff Vertrag zu verwenden. Ein Vertrag besteht im Wesentlichen aus einer Reihe von Schnittstellen zur Beschreibung der Funktionalität einer Komponente.

interface SmsContract
{
    public function send();
}

Fügen Sie als Nächstes die Treiber hinzu, die den Vertrag ausführen. Wir nehmen die allgemeine Logik in einer abstrakten Klasse heraus.

abstract class Driver implements SmsContract
{
    protected $message;

    protected $recipient;

    public function to($phoneNumber)
    {
        $this->recipient = $phoneNumber;
    }

    public function content($message)
    {
        $this->message = $message;
    }

    abstract public function send();
}

Und wir werden die Sendelogik in jeder Treiberklasse direkt beschreiben.

class SmsRuDriver extends Driver
{
    protected $client;

    protected $from;

    public function __construct(SmsRuClient $smsRuClient, $from)
    {
        $this->client = $smsRuClient;
        $this->from = $from;
    }

    public function send()
    {
        return $this->client->sendSms([
            'type' => 'text',
            'from' => $this->from,
            'to' => $this->recipient,
            'text' => trim($this->message)
        ]);
    }
}

class SmartSenderDriver extends Driver
{
    protected $client;

    protected $from;

    public function __construct(SmartSenderClient $smartSenderClient, $from)
    {
        $this->client = $smartSenderClient;
        $this->from = $from;
    }

    public function send()
    {
        return $this->client->message()->send([
            'type' => 'text',
            'from' => $this->from,
            'to' => $this->recipient,
            'text' => trim($this->message)
        ]);
    }
}

Komponentenverwaltung


Fügen Sie zum Auswählen und Konfigurieren von Treibern eine SmsManagervon der Klasse geerbte Klasse hinzu Manager.

use Illuminate\Support\Manager;

class SmsManager extends Manager
{
    public function setDriver($name = null)
    {
        return $this->driver($name);
    }

    public function createSmsRuDriver(): SmsContract
    {
        return new SmsRuDriver(
            $this->createSmsRuClient(),
            $this->app['config']['sms.sms_ru.from']
        );
    }

    public function createSmartSenderDriver(): SmsContract
    {
        return new SmartSenderDriver(
            $this->createSmartSenderClient(),
            $this->app['config']['sms.smart_sender.from']
        );
    }

    public function getDefaultDriver()
    {
        return $this->app['config']['sms.default'];
    }

    protected function createSmsRuClient()
    {
        return new SmsRuClient(
            $this->app['config']['sms.sms_ru.key'],
            $this->app['config']['sms.sms_ru.secret']
        );
    }

    protected function createSmartSenderClient()
    {
        return new SmartSenderClient(
            $this->app['config']['sms.smart_sender.key'],
            $this->app['config']['sms.smart_sender.secret']
        );
    }

}

Jetzt reicht es aus, die erforderlichen Parameter in der Konfigurationsdatei anzugeben, und die Klasse teilt SmsManager unserer Komponente mit, über welchen Treiber SMS-Nachrichten gesendet werden sollen.

Fassade


Fügen Sie eine Fassade hinzu, um von überall in der Anwendung auf die Funktionen der Komponente zuzugreifen .
Erstellen Sie zunächst die Fassadenklasse selbst:

use Illuminate\Support\Facades\Facade;

class Sms extends Facade
{
    protected static function getFacadeAccessor()
    {
        return 'sms';
    }
}

Als Nächstes verknüpfen wir die Klasse SmsManager mithilfe des Dienstanbieters mit der Fassade und registrieren einen Alias.

class SmsServiceProvider extends ServiceProvider
{
    protected $defer = true;
    
    public function register()
    {
        $this->app->singleton('sms', function ($app) {
            return new SmsManager($app);
        });
    }
    
    public function provides()
    {
        return ['sms'];
    }
}

Zuletzt registrieren Sie unseren Dienstanbieter zusammen mit den anderen Anbietern in der Konfigurationsdatei ( app/config/app.php).

'providers' => [
    ...
    App\Providers\SmsServiceProvider::class,
],    

Anwendung


Wenn eine Fassade für unsere Komponente erstellt wird und die Parameter in der Konfigurationsdatei angegeben sind, fügen Sie zum Senden einer SMS-Nachricht einfach den folgenden Code hinzu:

Sms::to($phone)->content('Beware! He`s not who he is')->send();

Oder wenn Sie den Treiber explizit angeben müssen:

Sms::setDriver('sms_ru')->to($phone)->content('why don`t you answer me?')->send();

Fazit


Unsere Komponente basiert auf dem Prinzip des Entwurfs einer Brücke, dh Implementierung und Abstraktion sind so getrennt, dass sie unabhängig voneinander geändert werden können. Wir können Treiber über die Klasse verwalten SmsManager, während der Anwendungscode selbst unverändert bleibt.
Die Fassade bietet einfachen Zugang zur Funktionalität unserer Komponente.

Dieser Ansatz für das Komponentendesign bietet Einfachheit und Flexibilität bei der Verwendung.

Verweise


Laravel Socialite- Komponente zur Authentifizierung über verschiedene soziale Netzwerke

All Articles