Skip to content

Commit

Permalink
Merge pull request #588 from bakaphp/unsubscribe-0.2
Browse files Browse the repository at this point in the history
[0.2] Unsubscribe
  • Loading branch information
dasdo authored Jan 20, 2021
2 parents 16fae0b + 4f52954 commit 87f8505
Show file tree
Hide file tree
Showing 8 changed files with 279 additions and 1 deletion.
1 change: 1 addition & 0 deletions routes/api.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
Route::crud('/apps-keys')->controller('AppsKeysController'),
Route::post('/apps-keys/regenerate')->controller('AppsKeysController')->action('regenerateKeys'),
Route::crud('/users')->notVia('post'),
Route::post('/users/{id}/unsubscribe')->controller('UsersController')->action('unsubscribe'),
Route::crud('/companies'),
Route::crud('/roles'),
Route::crud('/locales'),
Expand Down
36 changes: 36 additions & 0 deletions src/Api/Controllers/UsersController.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
use Canvas\Dto\User as UserDto;
use Canvas\Mapper\UserMapper;
use Canvas\Models\Users;
use Canvas\Models\NotificationType;
use Canvas\Models\Notifications;
use Canvas\Models\UsersAssociatedApps;
use Phalcon\Http\Response;
use Phalcon\Validation\Validator\PresenceOf;
Expand Down Expand Up @@ -244,4 +246,38 @@ public function changeAppUserActiveStatus(int $id, int $appsId) : Response
$userAssociatedToApp->updateOrFail();
return $this->response($userAssociatedToApp);
}

/**
* unsubscribe from notification
*
* @param int $id
* @throws InternalServerErrorException
*
* @return Response
*/
public function unsubscribe(int $id) : Response
{
$request = $this->request->getPostData();


if (!isset($request['notification_types'])) {
throw new Exception("Error Processing Request", 1);
}

//none admin users can only edit themselves
if (!$this->userData->hasRole('Default.Admins') || $id == 0) {
$id = $this->userData->getId();
}

$user = $this->model->findFirstOrFail([
'id = ?0 AND is_deleted = 0',
'bind' => [$id],
]);
$unsubscribe = [];
foreach ($request['notification_types'] as $typeId) {
$unsubscribe[] = $user->unsubscribe((int) $typeId);
}

return $this->response($unsubscribe);
}
}
12 changes: 12 additions & 0 deletions src/Models/Notifications.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,16 @@ public static function totalUnRead(Users $user) : int
]
]);
}

/**
* unsubscribe user for NotificationType
* @param Users $user
* @param int $notificationTypeId
* @param int $systemModulesId
* @return NotificationsUnsubscribe
*/
public static function unsubscribe(Users $user, int $notificationTypeId, int $systemModulesId) : NotificationsUnsubscribe
{
return NotificationsUnsubscribe::unsubscribe($user, $notificationTypeId, $systemModulesId);
}
}
101 changes: 101 additions & 0 deletions src/Models/NotificationsUnsubscribe.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<?php
declare(strict_types=1);

namespace Canvas\Models;

use Phalcon\Di;

class NotificationsUnsubscribe extends AbstractModel
{
public ?int $users_id = 0;
public ?int $companies_id = 0;
public ?int $apps_id = 0;
public ?int $system_modules_id = 0;
public ?int $notification_type_id = 0;
public ?string $email = null;

/**
* Initialize method for model.
*/
public function initialize()
{
$this->setSource('notifications_unsubscribe');

$this->belongsTo(
'users_id',
'Canvas\Models\Users',
'id',
['alias' => 'user']
);

$this->belongsTo(
'notification_type_id',
'Canvas\Models\NotificationType',
'id',
['alias' => 'type']
);
}

/**
* get NotificationsUnsubscribe by NotificationType
* @param Users $user
* @param int $notificationTypeId
* @return NotificationsUnsubscribe
*/
public static function getByNotificationType(Users $user, int $notificationTypeId) : ?NotificationsUnsubscribe
{
return NotificationsUnsubscribe::findFirst([
'conditions' => 'users_id = ?0 AND companies_id = ?1 AND apps_id = ?2 AND \notification_type_id = ?3 AND is_deleted = 0',
'bind' => [
0 => $user->getId(),
1 => $user->currentCompanyId(),
2 => Di::getDefault()->getApp()->getId(),
3 => $notificationTypeId
]
]);
}

/**
* Verify that the user is unsubscribed
* @param Users $user
* @param int $notificationType
* @return bool
*/
public static function isUnsubscribe(Users $user, int $notificationTypeId) : bool
{
//-1 means it is out of all lists
$userNotification = NotificationsUnsubscribe::getByNotificationType($user, -1);

if (!$userNotification) {
$userNotification = NotificationsUnsubscribe::getByNotificationType($user, $notificationTypeId);
}

return $userNotification ? true : false;
}

/**
* unsubscribe user for NotificationType
* @param Users $user
* @param int $notificationTypeId
* @param int $systemModulesId
* @return NotificationsUnsubscribe
*/
public static function unsubscribe(Users $user, int $notificationTypeId, int $systemModulesId) : NotificationsUnsubscribe
{
$userNotification = NotificationsUnsubscribe::getByNotificationType($user, $notificationTypeId);

if (!$userNotification) {
$userNotification = new NotificationsUnsubscribe();
$userNotification->users_id = $user->getId();
$userNotification->companies_id = $user->currentCompanyId();
$userNotification->apps_id = Di::getDefault()->getApp()->getId();
$userNotification->notification_type_id = $notificationTypeId;
$userNotification->system_modules_id = $systemModulesId;
$userNotification->email = $user->getEmail();
}

$userNotification->is_deleted = 0;
$userNotification->saveOrFail();
return $userNotification;
}
}
22 changes: 22 additions & 0 deletions src/Models/Users.php
Original file line number Diff line number Diff line change
Expand Up @@ -739,4 +739,26 @@ protected function throwErrorMessages() : void
current($this->getMessages())->getMessage()
);
}

/**
* Verify that the user is unsubscribed from email
* @param int $notificationTypeId
* @return bool
*/
public function isUnsubscribe(int $notificationTypeId) : bool
{
return NotificationsUnsubscribe::isUnsubscribe($this, $notificationTypeId);
}

/**
* unsubscribe user for NotificationType
* @param int $notificationTypeId
* @return NotificationsUnsubscribe
*/
public function unsubscribe(int $notificationTypeId) : NotificationsUnsubscribe
{
$notificationType = NotificationType::findFirst($notificationTypeId);
$systemModulesId = $notificationType ? $notificationType->system_modules_id : -1;
return Notifications::unsubscribe($this, (int) $notificationTypeId, (int) $systemModulesId);
}
}
2 changes: 1 addition & 1 deletion src/Notifications/Notification.php
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ public function trigger() : bool
$notification->saveOrFail();

$toMail = $this->toMail();
if ($toMail instanceof Message) {
if ($toMail instanceof Message && !$this->toUser->isUnsubscribe($notification->notification_type_id)) {
$this->fire('notification:sendMail', $toMail);
}

Expand Down
71 changes: 71 additions & 0 deletions storage/db/migrations/20210114193743_notifications_unsubscribe.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

use Phinx\Db\Adapter\MysqlAdapter;

class NotificationsUnsubscribe extends Phinx\Migration\AbstractMigration
{
public function change()
{
$this->table('notifications_unsubscribe', [
'id' => false,
'primary_key' => ['id'],
'engine' => 'InnoDB',
'encoding' => 'latin1',
'collation' => 'latin1_swedish_ci',
'comment' => '',
'row_format' => 'DYNAMIC',
])
->addColumn('id', 'integer', [
'null' => false,
'limit' => MysqlAdapter::INT_REGULAR,
'identity' => 'enable',
])
->addColumn('users_id', 'integer', [
'null' => false,
'limit' => MysqlAdapter::INT_REGULAR,
'after' => 'id',
])
->addColumn('companies_id', 'integer', [
'null' => false,
'limit' => MysqlAdapter::INT_REGULAR,
'after' => 'users_id',
])
->addColumn('apps_id', 'integer', [
'null' => false,
'limit' => MysqlAdapter::INT_REGULAR,
'after' => 'companies_id',
])
->addColumn('notification_type_id', 'integer', [
'null' => false,
'limit' => MysqlAdapter::INT_REGULAR,
'after' => 'apps_id',
])
->addColumn('email', 'string', [
'null' => false,
'limit' => 255,
'collation' => 'latin1_swedish_ci',
'encoding' => 'latin1',
'after' => 'notification_type_id',
])
->addColumn('created_at', 'datetime', [
'null' => false,
'after' => 'email',
])
->addColumn('updated_at', 'datetime', [
'null' => true,
'default' => null,
'after' => 'created_at',
])
->addColumn('is_deleted', 'integer', [
'null' => false,
'limit' => MysqlAdapter::INT_REGULAR,
'after' => 'updated_at',
])
->addColumn('system_modules_id', 'integer', [
'null' => false,
'limit' => MysqlAdapter::INT_REGULAR,
'after' => 'is_deleted',
])
->create();
}
}
35 changes: 35 additions & 0 deletions tests/api/UsersCest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace Canvas\Tests\api;

use ApiTester;

class UsersCest
{
/**
* unsubscribe from notification
*
* @param ApiTester
*
* @return void
*/
public function unsubscribe(ApiTester $I) : void
{
$userData = $I->apiLogin();
$userName = $I->faker()->firstname;

$I->haveHttpHeader('Authorization', $userData->token);
$I->sendPost('/v1/users/0/unsubscribe', [
'notification_types' => [
-1
]
]);

$I->seeResponseIsSuccessful();
$response = $I->grabResponse();
$data = json_decode($response, true);

$I->assertTrue(isset($data[0]['notification_type_id']));
$I->assertTrue($data[0]['notification_type_id'] == -1);
}
}

0 comments on commit 87f8505

Please sign in to comment.