diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..8c88da8 Binary files /dev/null and b/.DS_Store differ diff --git a/README.md b/README.md new file mode 100644 index 0000000..ede0747 --- /dev/null +++ b/README.md @@ -0,0 +1,30 @@ +# Laravel Zoho +A lightweight (for now) wrapper around the Zoho PHP SDK + +## Installation + +``` +composer require purplemountain/laravel-zoho +``` + +## Setup +1. If you haven't already, you need to create an Oauth2 client within Zoho. This can be done [here](https://api-console.zoho.com/). + +2. You want to choose a "Server-based Application" client within Zoho. + +3. For the "Authorized Redirect URIs" entry, you need to add `your-app-domain.tld/oauth/zoho`. Don't worry we handle this route for you within your app. + +## Env +You will need to add the following details to your `.env` file and paste in the values from Zoho. + +``` +ZOHO_CLIENT_ID= +ZOHO_CLIENT_SECRET= +ZOHO_USER_EMAIL= +``` + +## Authorization +You need to authorize your app to access Zoho. You can do this by simply running `php artisan zoho:url` which will generate the url to authorize the app. Follow the prompts and you'll be be all set. + +## Refreshing Tokens +Zoho tokens last for aprox 1 hour. To refresh the token using the refresh token provided, you can run `php artisan zoho:refresh`. We reccomend setting this up to be run every 5 minutes in your `App\Console\Kernel.php` file. diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..45ae7c8 --- /dev/null +++ b/composer.json @@ -0,0 +1,29 @@ +{ + "name": "purplemountain/sns-communication-records", + "description": "Store records of communications through AWS sns.", + "authors": [ + { + "name": "Christian Braybrooke", + "email": "chris@purplemountmedia.com" + } + ], + "require": { + "aws/aws-php-sns-message-validator": "^1.6", + "aws/aws-sdk-php": "^3.147" + }, + "autoload": { + "psr-4": { + "PurpleMountain\\SNSCommunicationRecords\\": "src/" + } + }, + "extra": { + "laravel": { + "providers": [ + "PurpleMountain\\SNSCommunicationRecords\\ServiceProvider" + ], + "aliases": { + "SNSCommunicationRecords": "PurpleMountain\\SNSCommunicationRecords\\Facade" + } + } + } +} diff --git a/config/snscommunicationrecords.php b/config/snscommunicationrecords.php new file mode 100644 index 0000000..52c5cc3 --- /dev/null +++ b/config/snscommunicationrecords.php @@ -0,0 +1,7 @@ + PurpleMountain\SNSCommunicationRecords\Models\SNSCommunicationRecord::class, + + 'to_class' => App\User::class +]; \ No newline at end of file diff --git a/database/.DS_Store b/database/.DS_Store new file mode 100644 index 0000000..4b20b89 Binary files /dev/null and b/database/.DS_Store differ diff --git a/database/migrations/.DS_Store b/database/migrations/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/database/migrations/.DS_Store differ diff --git a/database/migrations/2020_08_01_130327_create_sns_communication_records_table.php.stub b/database/migrations/2020_08_01_130327_create_sns_communication_records_table.php.stub new file mode 100644 index 0000000..f77af73 --- /dev/null +++ b/database/migrations/2020_08_01_130327_create_sns_communication_records_table.php.stub @@ -0,0 +1,54 @@ +uuid('id')->primary(); + $table->string('channel_id')->nullable()->default(null); + $table->string('internal_ref')->nullable()->default(null); + $table->string('internal_id')->nullable()->default(null); + $table->uuid('to_id')->nullable()->default(null); + $table->string('to_type')->nullable()->default(null); + $table->string('from')->nullable()->default(null); + $table->string('bcc')->nullable()->default(null); + $table->string('cc')->nullable()->default(null); + $table->string('reply_to')->nullable()->default(null); + $table->string('content_type')->nullable()->default(null); + $table->string('type'); + $table->integer('priority')->nullable()->default(null); + $table->string('name')->nullable(); + $table->string('subject')->nullable(); + $table->longText('content')->nullable()->default(null); + $table->dateTime('sent_at')->nullable()->default(null); + $table->dateTime('delivered_at')->nullable()->default(null); + $table->dateTime('read_at')->nullable()->default(null); + $table->dateTime('clicked_at')->nullable()->default(null); + $table->dateTime('bounced_at')->nullable()->default(null); + $table->dateTime('complaint_at')->nullable()->default(null); + $table->dateTime('rejected_at')->nullable()->default(null); + $table->json('extra')->nullable()->default(null); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('sns_communication_records'); + } +} diff --git a/routes/api.php b/routes/api.php new file mode 100644 index 0000000..125ff8b --- /dev/null +++ b/routes/api.php @@ -0,0 +1,13 @@ +get('communication-records', 'SNSCommunicationRecordsController'); \ No newline at end of file diff --git a/routes/web.php b/routes/web.php new file mode 100644 index 0000000..4ef5259 --- /dev/null +++ b/routes/web.php @@ -0,0 +1,15 @@ +prefix('webhooks')->group(function () { + Route::post('sns', 'SNSCommunicationsWebhookController')->name('sns'); +}); \ No newline at end of file diff --git a/src/.DS_Store b/src/.DS_Store new file mode 100644 index 0000000..1d5e58d Binary files /dev/null and b/src/.DS_Store differ diff --git a/src/Concerns/LogAsEmail.php b/src/Concerns/LogAsEmail.php new file mode 100644 index 0000000..4da68c5 --- /dev/null +++ b/src/Concerns/LogAsEmail.php @@ -0,0 +1,8 @@ +snsCommunicationRecord = $snsCommunicationRecord; + } + + /** + * Get the channels the event should broadcast on. + * + * @return \Illuminate\Broadcasting\Channel|array + */ + public function broadcastOn() + { + return new PrivateChannel('sns-communication-records'); + } +} diff --git a/src/Events/SNSCommunicationClicked.php b/src/Events/SNSCommunicationClicked.php new file mode 100644 index 0000000..eae2e29 --- /dev/null +++ b/src/Events/SNSCommunicationClicked.php @@ -0,0 +1,44 @@ +snsCommunicationRecord = $snsCommunicationRecord; + } + + /** + * Get the channels the event should broadcast on. + * + * @return \Illuminate\Broadcasting\Channel|array + */ + public function broadcastOn() + { + return new PrivateChannel('sns-communication-records'); + } +} diff --git a/src/Events/SNSCommunicationComplaint.php b/src/Events/SNSCommunicationComplaint.php new file mode 100644 index 0000000..e25b097 --- /dev/null +++ b/src/Events/SNSCommunicationComplaint.php @@ -0,0 +1,44 @@ +snsCommunicationRecord = $snsCommunicationRecord; + } + + /** + * Get the channels the event should broadcast on. + * + * @return \Illuminate\Broadcasting\Channel|array + */ + public function broadcastOn() + { + return new PrivateChannel('sns-communication-records'); + } +} diff --git a/src/Events/SNSCommunicationDelivered.php b/src/Events/SNSCommunicationDelivered.php new file mode 100644 index 0000000..58e4800 --- /dev/null +++ b/src/Events/SNSCommunicationDelivered.php @@ -0,0 +1,44 @@ +snsCommunicationRecord = $snsCommunicationRecord; + } + + /** + * Get the channels the event should broadcast on. + * + * @return \Illuminate\Broadcasting\Channel|array + */ + public function broadcastOn() + { + return new PrivateChannel('sns-communication-records'); + } +} diff --git a/src/Events/SNSCommunicationOpened.php b/src/Events/SNSCommunicationOpened.php new file mode 100644 index 0000000..22a7855 --- /dev/null +++ b/src/Events/SNSCommunicationOpened.php @@ -0,0 +1,44 @@ +snsCommunicationRecord = $snsCommunicationRecord; + } + + /** + * Get the channels the event should broadcast on. + * + * @return \Illuminate\Broadcasting\Channel|array + */ + public function broadcastOn() + { + return new PrivateChannel('sns-communication-records'); + } +} diff --git a/src/Events/SNSCommunicationRecordCreated.php b/src/Events/SNSCommunicationRecordCreated.php new file mode 100644 index 0000000..8798447 --- /dev/null +++ b/src/Events/SNSCommunicationRecordCreated.php @@ -0,0 +1,44 @@ +snsCommunicationRecord = $snsCommunicationRecord; + } + + /** + * Get the channels the event should broadcast on. + * + * @return \Illuminate\Broadcasting\Channel|array + */ + public function broadcastOn() + { + return new PrivateChannel('sns-communication-records'); + } +} diff --git a/src/Events/SNSCommunicationRecordDeleted.php b/src/Events/SNSCommunicationRecordDeleted.php new file mode 100644 index 0000000..d4c26c9 --- /dev/null +++ b/src/Events/SNSCommunicationRecordDeleted.php @@ -0,0 +1,44 @@ +snsCommunicationRecord = $snsCommunicationRecord; + } + + /** + * Get the channels the event should broadcast on. + * + * @return \Illuminate\Broadcasting\Channel|array + */ + public function broadcastOn() + { + return new PrivateChannel('sns-communication-records'); + } +} diff --git a/src/Events/SNSCommunicationRecordUpdated.php b/src/Events/SNSCommunicationRecordUpdated.php new file mode 100644 index 0000000..c55629e --- /dev/null +++ b/src/Events/SNSCommunicationRecordUpdated.php @@ -0,0 +1,44 @@ +snsCommunicationRecord = $snsCommunicationRecord; + } + + /** + * Get the channels the event should broadcast on. + * + * @return \Illuminate\Broadcasting\Channel|array + */ + public function broadcastOn() + { + return new PrivateChannel('sns-communication-records'); + } +} diff --git a/src/Events/SNSCommunicationRejected.php b/src/Events/SNSCommunicationRejected.php new file mode 100644 index 0000000..88c7b51 --- /dev/null +++ b/src/Events/SNSCommunicationRejected.php @@ -0,0 +1,44 @@ +snsCommunicationRecord = $snsCommunicationRecord; + } + + /** + * Get the channels the event should broadcast on. + * + * @return \Illuminate\Broadcasting\Channel|array + */ + public function broadcastOn() + { + return new PrivateChannel('sns-communication-records'); + } +} diff --git a/src/Events/SNSCommunicationSent.php b/src/Events/SNSCommunicationSent.php new file mode 100644 index 0000000..58434bf --- /dev/null +++ b/src/Events/SNSCommunicationSent.php @@ -0,0 +1,44 @@ +snsCommunicationRecord = $snsCommunicationRecord; + } + + /** + * Get the channels the event should broadcast on. + * + * @return \Illuminate\Broadcasting\Channel|array + */ + public function broadcastOn() + { + return new PrivateChannel('sns-communication-records'); + } +} diff --git a/src/Exceptions/.DS_Store b/src/Exceptions/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/src/Exceptions/.DS_Store differ diff --git a/src/Facade.php b/src/Facade.php new file mode 100644 index 0000000..6f27c25 --- /dev/null +++ b/src/Facade.php @@ -0,0 +1,15 @@ +with ?: []) + ->paginate() + ); + } +} diff --git a/src/Http/Controllers/Controller.php b/src/Http/Controllers/Controller.php new file mode 100644 index 0000000..57dea39 --- /dev/null +++ b/src/Http/Controllers/Controller.php @@ -0,0 +1,13 @@ +getContent()); + $validator = new MessageValidator(); + + if ($validator->isValid($snsMessage)) { + // Format the incoming message + $eventData = $snsMessage->toArray(); + $this->message = json_decode($eventData['Message'], true); + $this->messageType = $this->message['eventType'] ?? null; + $this->messageMail = $this->message['mail'] ?? null; + + // If this is the first request from AWS, we have to subscribe to the topic + if ($eventData['SubscribeURL'] ?? null) { + Http::get($eventData['SubscribeURL']); + } + + // If this is an email event + if ($this->messageMail) { + // Find the communication record for this email in our database + $snsCommunicationRecords = config('snscommunicationrecords.record_class')::whereChannelId($this->messageMail['messageId'])->get(); + + // Calculate the method that needs to be called for this event + $method = 'handle' . ucfirst(Str::camel(Str::replaceFirst('.', '_', $this->messageType))); + + // Foreach communication record, call the correct method + if (method_exists($this, $method) && $snsCommunicationRecords->count() > 0) { + foreach ($snsCommunicationRecords as $snsCommunicationRecord) { + $this->{$method}($snsCommunicationRecord, $eventData); + } + } + } + } + + return new Response; + } + + /** + * Handle the send event from SES. + * + * @param \PurpleMountain\SNSCommunicationRecords\Models $snsCommunicationRecord + * @param array $eventData + * @return void + */ + protected function handleSend(SNSCommunicationRecord $snsCommunicationRecord, $eventData) + { + LogSNSCommunicationEvent::dispatch('EVENT_SEND', $snsCommunicationRecord, $eventData); + } + + /** + * Handle the delivery event from SES. + * + * @param \PurpleMountain\SNSCommunicationRecords\Models $snsCommunicationRecord + * @param array $eventData + * @return void + */ + protected function handleDelivery(SNSCommunicationRecord $snsCommunicationRecord, $eventData) + { + LogSNSCommunicationEvent::dispatch('EVENT_DELIVERY', $snsCommunicationRecord, $eventData); + } + + /** + * Handle the open event from SES. + * + * @param \PurpleMountain\SNSCommunicationRecords\Models $snsCommunicationRecord + * @param array $eventData + * @return void + */ + protected function handleOpen(SNSCommunicationRecord $snsCommunicationRecord, $eventData) + { + LogSNSCommunicationEvent::dispatch('EVENT_OPEN', $snsCommunicationRecord, $eventData); + } + + /** + * Handle the click event from SES. + * + * @param \PurpleMountain\SNSCommunicationRecords\Models $snsCommunicationRecord + * @param array $eventData + * @return void + */ + protected function handleClick(SNSCommunicationRecord $snsCommunicationRecord, $eventData) + { + LogSNSCommunicationEvent::dispatch('EVENT_CLICK', $snsCommunicationRecord, $eventData); + } + + /** + * Handle the bounce event from SES. + * + * @param \PurpleMountain\SNSCommunicationRecords\Models $snsCommunicationRecord + * @param array $eventData + * @return void + */ + protected function handleBounce(SNSCommunicationRecord $snsCommunicationRecord, $eventData) + { + LogSNSCommunicationEvent::dispatch('EVENT_BOUNCE', $snsCommunicationRecord, $eventData); + } + + /** + * Handle the complaint event from SES. + * + * @param \PurpleMountain\SNSCommunicationRecords\Models $snsCommunicationRecord + * @param array $eventData + * @return void + */ + protected function handleComplaint(SNSCommunicationRecord $snsCommunicationRecord, $eventData) + { + LogSNSCommunicationEvent::dispatch('EVENT_COMPLAINT', $snsCommunicationRecord, $eventData); + } + + /** + * Handle the reject event from SES. + * + * @param \PurpleMountain\SNSCommunicationRecords\Models $snsCommunicationRecord + * @param array $eventData + * @return void + */ + protected function handleReject(SNSCommunicationRecord $snsCommunicationRecord, $eventData) + { + LogSNSCommunicationEvent::dispatch('EVENT_REJECT', $snsCommunicationRecord, $eventData); + } +} diff --git a/src/Http/Resources/SNSCommunicationRecord.php b/src/Http/Resources/SNSCommunicationRecord.php new file mode 100644 index 0000000..6348a1f --- /dev/null +++ b/src/Http/Resources/SNSCommunicationRecord.php @@ -0,0 +1,43 @@ + $this->id, + 'channel_id' => $this->channel_id, + 'internal_id' => $this->internal_id, + 'internal_ref' => $this->internal_ref, + 'type' => $this->type, + 'type_label' => SNSCommunicationRecordModel::types()[$this->type], + 'name' => $this->name, + 'subject' => $this->subject, + 'sent_at' => $this->sent_at, + 'delivered_at' => $this->delivered_at, + 'read_at' => $this->read_at, + 'clicked_at' => $this->clicked_at, + 'bounced_at' => $this->bounced_at, + 'complaint_at' => $this->complaint_at, + 'rejected_at' => $this->rejected_at, + 'to' => new SNSCommunicationRecordTo($this->to), + 'from_email' => $this->from, + 'bcc_email' => $this->bcc, + 'cc_email' => $this->cc, + 'reply_to_email' => $this->reply_to, + 'content_type' => $this->content_type, + 'extra' => $this->extra + ]; + } +} diff --git a/src/Http/Resources/SNSCommunicationRecordTo.php b/src/Http/Resources/SNSCommunicationRecordTo.php new file mode 100644 index 0000000..f31b5de --- /dev/null +++ b/src/Http/Resources/SNSCommunicationRecordTo.php @@ -0,0 +1,24 @@ + $this->id, + 'name' => $this->name, + 'email' => $this->email, + 'type' => get_class($this->resource) + ]; + } +} diff --git a/src/Jobs/LogSNSCommunicationEvent.php b/src/Jobs/LogSNSCommunicationEvent.php new file mode 100644 index 0000000..e81a113 --- /dev/null +++ b/src/Jobs/LogSNSCommunicationEvent.php @@ -0,0 +1,99 @@ +eventType = $eventType; + $this->snsCommunicationRecord = $snsCommunicationRecord; + $this->eventData = $eventData; + } + + /** + * Execute the job. + * + * @return void + */ + public function handle() + { + if ($this->eventType === 'EVENT_SEND') { + $this->snsCommunicationRecord->update([ + 'sent_at' => now() + ]); + $this->snsCommunicationRecord->fireSentEvent(); + } + if ($this->eventType === 'EVENT_DELIVERY') { + $this->snsCommunicationRecord->update([ + 'delivered_at' => now() + ]); + $this->snsCommunicationRecord->fireDeliveredEvent(); + } + if ($this->eventType === 'EVENT_OPEN') { + $this->snsCommunicationRecord->update([ + 'read_at' => now() + ]); + $this->snsCommunicationRecord->fireOpenEvent(); + } + if ($this->eventType === 'EVENT_CLICK') { + $this->snsCommunicationRecord->update([ + 'clicked_at' => now() + ]); + $this->snsCommunicationRecord->fireClickEvent(); + } + if ($this->eventType === 'EVENT_BOUNCE') { + $this->snsCommunicationRecord->update([ + 'bounced_at' => now() + ]); + $this->snsCommunicationRecord->fireBounceEvent(); + } + if ($this->eventType === 'EVENT_COMPLAINT') { + $this->snsCommunicationRecord->update([ + 'complaint_at' => now() + ]); + $this->snsCommunicationRecord->fireComplaintEvent(); + } + if ($this->eventType === 'EVENT_REJECT') { + $this->snsCommunicationRecord->update([ + 'rejected_at' => now() + ]); + $this->snsCommunicationRecord->fireRejectEvent(); + } + } +} diff --git a/src/Listeners/CreateSNSCommunicationRecord.php b/src/Listeners/CreateSNSCommunicationRecord.php new file mode 100644 index 0000000..5c3243c --- /dev/null +++ b/src/Listeners/CreateSNSCommunicationRecord.php @@ -0,0 +1,42 @@ +data['__laravel_notification'] ?? false) { + $implements = class_implements($event->data['__laravel_notification']); + $name = Str::afterLast($event->data['__laravel_notification'], '\\'); + $internalId = $event->data['__laravel_notification_id']; + $sesId = $event->message->getHeaders()->get('X-SES-Message-ID')->getValue(); + + if (Arr::has($implements, LogNotification::class)) { + // Work out the type of notification this is. + $type = Arr::first(array_keys(SNSCommunicationRecord::types()), function ($type) use ($implements) { + return Arr::has($implements, $type); + }, LogAsEmail::class); + + foreach ($event->message->getTo() as $toEmail => $toName) { + config('snscommunicationrecords.record_class')::createFromSentEvent($event, $toEmail, $toName, $type, $name, $internalId, $sesId); + } + } + } + } +} diff --git a/src/Models/SNSCommunicationRecord.php b/src/Models/SNSCommunicationRecord.php new file mode 100644 index 0000000..e68d567 --- /dev/null +++ b/src/Models/SNSCommunicationRecord.php @@ -0,0 +1,238 @@ + 'datetime', + 'delivered_at' => 'datetime', + 'read_at' => 'datetime', + 'clicked_at' => 'datetime', + 'bounced_at' => 'datetime', + 'complaint_at' => 'datetime', + 'rejected_at' => 'datetime', + 'extra' => 'array' + ]; + + /** + * The event map for the model. + * + * Allows for object-based events for native Eloquent events. + * + * @var array + */ + protected $dispatchesEvents = [ + 'created' => SNSCommunicationRecordCreated::class, + 'updated' => SNSCommunicationRecordUpdated::class, + 'deleted' => SNSCommunicationRecordDeleted::class + ]; + + /** + * Hook into the boot method on the model and register any event listeners. + * + * @return void + */ + public static function boot() + { + parent::boot(); + + static::creating(function ($model) { + $model->id = Str::orderedUuid(); + }); + } + + /** + * Get the types of communcations we want to record. + * + * @return array + */ + public static function types(): array + { + return [ + LogAsEmail::class => 'Email', + LogAsTransactional::class => 'Transactional Email', + LogAsMarketing::class => 'Marketing Email', + LogAsSMS::class => 'SMS Message', + LogAsPhone::class => 'Phone Call', + ]; + } + + /** + * Create a record of the communication from the message sent event. + * + * @param \Illuminate\Mail\Events\MessageSent $event + * @param string $toEmail + * @param string $toName + * + * @return \PurpleMountain\SNSCommunicationRecords\Models\SNSCommunicationRecord + */ + public static function createFromSentEvent($event, $toEmail, $toName, $type, $name, $internalId, $sesId) + { + $message = $event->message; + $user = config('snscommunicationrecords.to_class')::whereEmail($toEmail)->first(); + + return self::create([ + 'channel_id' => $sesId, + 'internal_id' => $internalId, + 'internal_ref' => $message->getId(), + 'to_id' => optional($user)->id, + 'to_type' => $user ? get_class($user) : null, + 'from' => array_key_first($message->getFrom() ?: []), + 'bcc' => array_key_first($message->getBcc() ?: []), + 'cc' => array_key_first($message->getCc() ?: []), + 'reply_to' => array_key_first($message->getReplyTo() ?: []), + 'content_type' => $message->getContentType(), + 'type' => $type, + 'name' => $name, + 'subject' => $message->getSubject(), + 'content' => $message->getBody() + ]); + } + + /** + * Get the owning commentable model. + * + * @return \Illuminate\Database\Eloquent\Relations\MorphTo + */ + public function to(): MorphTo + { + return $this->morphTo(); + } + + /** + * Fire an event when this communication has been sent. + * + * @return \App\CommunicationRecord + */ + public function fireSentEvent() + { + event(new SNSCommunicationSent($this)); + } + + /** + * Fire an event when this communication has been delivered. + * + * @return \App\CommunicationRecord + */ + public function fireDeliveredEvent() + { + event(new SNSCommunicationDelivered($this)); + } + + /** + * Fire an event when this communication has been opened. + * + * @return \App\CommunicationRecord + */ + public function fireOpenEvent() + { + event(new SNSCommunicationOpened($this)); + } + + /** + * Fire an event when this communication has been clicked. + * + * @return \App\CommunicationRecord + */ + public function fireClickEvent() + { + event(new SNSCommunicationClicked($this)); + } + + /** + * Fire an event when this communication has been clicked. + * + * @return \App\CommunicationRecord + */ + public function fireBounceEvent() + { + event(new SNSCommunicationBounced($this)); + } + + /** + * Fire an event when this communication has been clicked. + * + * @return \App\CommunicationRecord + */ + public function fireComplaintEvent() + { + event(new SNSCommunicationComplaint($this)); + } + + /** + * Fire an event when this communication has been clicked. + * + * @return \App\CommunicationRecord + */ + public function fireRejectEvent() + { + event(new SNSCommunicationRejected($this)); + } + +} diff --git a/src/Providers/EventServiceProvider.php b/src/Providers/EventServiceProvider.php new file mode 100644 index 0000000..319d1b8 --- /dev/null +++ b/src/Providers/EventServiceProvider.php @@ -0,0 +1,34 @@ + [ + CreateSNSCommunicationRecord::class + ] + ]; + + /** + * Register any events for your application. + * + * @return void + */ + public function boot() + { + parent::boot(); + + // + } +} \ No newline at end of file diff --git a/src/SNSCommunicationRecords.php b/src/SNSCommunicationRecords.php new file mode 100644 index 0000000..c19e678 --- /dev/null +++ b/src/SNSCommunicationRecords.php @@ -0,0 +1,12 @@ +handleRoutes(); + $this->handleConfigs(); + + if (env('APP_ENV') === 'local') { + $this->handleMigrations(); + } + + if ($this->app->runningInConsole()) { + $this->commands([ + // + ]); + } + } + + /** + * Register anything this package needs. + * + * @return void + */ + public function register() + { + $this->mergeConfigFrom($this->configPath(), 'snscommunicationrecords'); + $this->app->register(EventServiceProvider::class); + } + + /** + * Register any migrations. + * + * @return void + */ + private function handleMigrations() + { + $this->publishes([ + __DIR__.'/../database/migrations/2020_08_01_130327_create_sns_communication_records_table.php.stub' => database_path('migrations/2020_08_01_130327_create_sns_communication_records_table.php') + ], $this->shortName() . '-migrations'); + } + + /** + * Register any routes this package needs. + * + * @return void + */ + private function handleRoutes() + { + Route::group([ + 'name' => $this->shortName(), + 'namespace' => 'PurpleMountain\SNSCommunicationRecords\Http\Controllers', + 'middleware' => ['web'] + ], function () { + $this->loadRoutesFrom(__DIR__.'/../routes/web.php'); + }); + + Route::group([ + 'name' => $this->shortName() . '-api', + 'prefix' => 'api', + 'namespace' => 'PurpleMountain\SNSCommunicationRecords\Http\Controllers\Api', + 'middleware' => ['api'] + ], function () { + $this->loadRoutesFrom(__DIR__.'/../routes/api.php'); + }); + } + + /** + * Register any config files this package needs. + * + * @return void + */ + private function handleConfigs() + { + $this->publishes([ + $this->configPath() => config_path('snscommunicationrecords.php') + ], 'snscommunicationrecords'); + } +} \ No newline at end of file diff --git a/src/Traits/HasCommunicationRecords.php b/src/Traits/HasCommunicationRecords.php new file mode 100644 index 0000000..c087db8 --- /dev/null +++ b/src/Traits/HasCommunicationRecords.php @@ -0,0 +1,18 @@ +morphOne(config('snscommunicationrecords.record_class'), 'to'); + } +} \ No newline at end of file