Perpanjang Laravel dengan komponen kami sendiri

Tugas


Tambahkan sistem peringatan kepada pengguna melalui pesan SMS dengan opsi memilih penyedia.

Keputusan


Solusi terbaik, menurut saya, adalah menambahkan komponen Anda sendiri.
Komponen adalah blok program dengan serangkaian tindakan (kontrak) yang terdefinisi dengan baik yang dapat menyelesaikan tugas yang diberikan kepadanya melalui berbagai driver. Sebagai contoh, built-in komponen Cache dapat menggunakan driver: file, memcachedatau redis.

Saat membangun komponen kami, kami akan menerapkan prinsip desain Jembatan, prinsip yang sama di mana komponen Laravel dibangun.

Jadi mari kita mulai.

Driver


Sebagai salah satu postulat mengatakan: program sesuai dengan antarmuka, dan bukan dengan implementasinya.

Kami akan mulai dengan itu, tetapi dalam konteks komponen itu lebih akurat untuk menggunakan istilah kontrak. Kontrak pada dasarnya adalah serangkaian antarmuka untuk menggambarkan fungsionalitas komponen.

interface SmsContract
{
    public function send();
}

Selanjutnya, tambahkan driver yang menjalankan kontrak. Kami mengambil logika umum dalam kelas abstrak.

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();
}

Dan kami akan secara langsung menggambarkan logika pengiriman di setiap kelas driver.

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)
        ]);
    }
}

Manajemen Komponen


Untuk memilih dan mengkonfigurasi driver, tambahkan kelas yang SmsManagerdiwarisi dari kelas 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']
        );
    }

}

Sekarang cukup untuk menentukan parameter yang diperlukan dalam file konfigurasi dan kelas SmsManager akan memberi tahu komponen kami melalui driver mana untuk mengirim pesan SMS.

Tatapan


Untuk mengakses fungsionalitas komponen dari mana saja dalam aplikasi, tambahkan fasad .
Pertama, buat kelas fasad itu sendiri:

use Illuminate\Support\Facades\Facade;

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

Selanjutnya, kami mengasosiasikan kelas SmsManager dengan fasad menggunakan penyedia layanan dan mendaftarkan 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'];
    }
}

Dan terakhir, daftarkan penyedia layanan kami bersama dengan penyedia lainnya di file konfigurasi ( app/config/app.php).

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

Aplikasi


Ketika fasad dibuat untuk komponen kami dan parameternya ditentukan dalam file konfigurasi, untuk mengirim pesan SMS, cukup tambahkan kode berikut:

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

Atau, jika Anda perlu menentukan driver secara eksplisit:

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

Kesimpulan


Komponen kami dibangun berdasarkan prinsip merancang Jembatan, yaitu implementasi dan abstraksi dipisahkan sedemikian rupa sehingga mereka dapat diubah secara independen. Kami dapat mengelola driver melalui kelas SmsManager, sementara kode aplikasi itu sendiri tetap tidak berubah.
Fasad menyediakan akses mudah ke fungsionalitas komponen kami.

Pendekatan desain komponen ini memberikan kesederhanaan dan fleksibilitas dalam penggunaannya.

Referensi


Komponen Laravel Socialite untuk otentikasi melalui berbagai jejaring sosial

All Articles