From 4bc23afc6586ab94a9733ea0e2816efc1e9fa856 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Wed, 29 Nov 2023 17:05:37 +1300 Subject: [PATCH 1/5] Add constants for message types --- app/controllers/api/account.php | 6 +++--- app/controllers/api/users.php | 12 ++++++------ app/init.php | 10 +++++++--- src/Appwrite/Platform/Workers/Messaging.php | 16 ++++++++-------- src/Appwrite/Utopia/Response/Model/Provider.php | 2 +- 5 files changed, 25 insertions(+), 21 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index eda29656f..6a06e2a09 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -157,7 +157,7 @@ App::post('/v1/account') ], 'userId' => $user->getId(), 'userInternalId' => $user->getInternalId(), - 'providerType' => 'email', + 'providerType' => MESSAGE_TYPE_EMAIL, 'identifier' => $email, ]))); $user->setAttribute('targets', [$target]); @@ -678,7 +678,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') ], 'userId' => $userDoc->getId(), 'userInternalId' => $userDoc->getInternalId(), - 'providerType' => 'email', + 'providerType' => MESSAGE_TYPE_EMAIL, 'identifier' => $email, ])); } catch (Duplicate) { @@ -1732,7 +1732,7 @@ App::post('/v1/account/targets/push') ], 'providerId' => $providerId ?? null, 'providerInternalId' => $provider->getInternalId() ?? null, - 'providerType' => 'push', + 'providerType' => MESSAGE_TYPE_PUSH, 'userId' => $user->getId(), 'userInternalId' => $user->getInternalId(), 'identifier' => $identifier, diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 0c1edb6a9..92af97f95 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -396,7 +396,7 @@ App::post('/v1/users/:userId/targets') ->label('sdk.response.model', Response::MODEL_TARGET) ->param('targetId', '', new CustomId(), 'Target ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.') ->param('userId', '', new UID(), 'User ID.') - ->param('providerType', '', new WhiteList(['email', 'sms', 'push']), 'The target provider type. Can be one of the following: `email`, `sms` or `push`.') + ->param('providerType', '', new WhiteList([MESSAGE_TYPE_EMAIL, MESSAGE_TYPE_SMS, MESSAGE_TYPE_PUSH]), 'The target provider type. Can be one of the following: `email`, `sms` or `push`.') ->param('identifier', '', new Text(Database::LENGTH_KEY), 'The target identifier (token, email, phone etc.)') ->param('providerId', '', new UID(), 'Provider ID. Message will be sent to this target from the specified provider ID. If no provider ID is set the first setup provider will be used.', true) ->inject('queueForEvents') @@ -407,7 +407,7 @@ App::post('/v1/users/:userId/targets') $provider = new Document(); - if ($providerType === 'push') { + if ($providerType === MESSAGE_TYPE_PUSH) { $provider = $dbForProject->getDocument('providers', $providerId); if ($provider->isEmpty()) { @@ -422,13 +422,13 @@ App::post('/v1/users/:userId/targets') throw new Exception(Exception::GENERAL_INVALID_EMAIL); } break; - case 'sms': + case MESSAGE_TYPE_SMS: $validator = new Phone(); if (!$validator->isValid($identifier)) { throw new Exception(Exception::GENERAL_INVALID_PHONE); } break; - case 'push': + case MESSAGE_TYPE_PUSH: break; default: throw new Exception(Exception::PROVIDER_INCORRECT_TYPE); @@ -1298,13 +1298,13 @@ App::patch('/v1/users/:userId/targets/:targetId') throw new Exception(Exception::GENERAL_INVALID_EMAIL); } break; - case 'sms': + case MESSAGE_TYPE_SMS: $validator = new Phone(); if (!$validator->isValid($identifier)) { throw new Exception(Exception::GENERAL_INVALID_PHONE); } break; - case 'push': + case MESSAGE_TYPE_PUSH: break; default: throw new Exception(Exception::PROVIDER_INCORRECT_TYPE); diff --git a/app/init.php b/app/init.php index 6f61b955f..800b32fdd 100644 --- a/app/init.php +++ b/app/init.php @@ -190,6 +190,10 @@ const MAX_OUTPUT_CHUNK_SIZE = 2 * 1024 * 1024; // 2MB // Function headers const FUNCTION_ALLOWLIST_HEADERS_REQUEST = ['content-type', 'agent', 'content-length', 'host']; const FUNCTION_ALLOWLIST_HEADERS_RESPONSE = ['content-type', 'content-length']; +// Message types +const MESSAGE_TYPE_EMAIL = 'email'; +const MESSAGE_TYPE_SMS = 'sms'; +const MESSAGE_TYPE_PUSH = 'push'; // Usage metrics const METRIC_TEAMS = 'teams'; const METRIC_USERS = 'users'; @@ -607,11 +611,11 @@ Database::addFilter( $data = \json_decode($message->getAttribute('data', []), true); if (\array_key_exists('subject', $data)) { - $searchValues = \array_merge($searchValues, [$data['subject'], 'email']); + $searchValues = \array_merge($searchValues, [$data['subject'], MESSAGE_TYPE_EMAIL]); } elseif (\array_key_exists('content', $data)) { - $searchValues = \array_merge($searchValues, [$data['content'], 'sms']); + $searchValues = \array_merge($searchValues, [$data['content'], MESSAGE_TYPE_SMS]); } else { - $searchValues = \array_merge($searchValues, [$data['title'], 'push']); + $searchValues = \array_merge($searchValues, [$data['title'], MESSAGE_TYPE_PUSH]); } $search = \implode(' ', \array_filter($searchValues)); diff --git a/src/Appwrite/Platform/Workers/Messaging.php b/src/Appwrite/Platform/Workers/Messaging.php index 8488d8a9e..200bb0621 100644 --- a/src/Appwrite/Platform/Workers/Messaging.php +++ b/src/Appwrite/Platform/Workers/Messaging.php @@ -67,7 +67,7 @@ class Messaging extends Action } if (!\is_null($payload['message']) && !\is_null($payload['recipients'])) { - if ($payload['providerType'] === 'SMS') { + if ($payload['providerType'] === MESSAGE_TYPE_SMS) { $this->processInternalSMSMessage(new Document($payload['message']), $payload['recipients']); } } else { @@ -155,9 +155,9 @@ class Messaging extends Action $identifiers = $identifiersByProviderId[$providerId]; $adapter = match ($provider->getAttribute('type')) { - 'sms' => $this->sms($provider), - 'push' => $this->push($provider), - 'email' => $this->email($provider), + MESSAGE_TYPE_SMS => $this->sms($provider), + MESSAGE_TYPE_PUSH => $this->push($provider), + MESSAGE_TYPE_EMAIL => $this->email($provider), default => throw new Exception(Exception::PROVIDER_INCORRECT_TYPE) }; @@ -173,9 +173,9 @@ class Messaging extends Action $messageData->setAttribute('to', $batch); $data = match ($provider->getAttribute('type')) { - 'sms' => $this->buildSMSMessage($messageData, $provider), - 'push' => $this->buildPushMessage($messageData), - 'email' => $this->buildEmailMessage($messageData, $provider), + MESSAGE_TYPE_SMS => $this->buildSMSMessage($messageData, $provider), + MESSAGE_TYPE_PUSH => $this->buildPushMessage($messageData), + MESSAGE_TYPE_EMAIL => $this->buildEmailMessage($messageData, $provider), default => throw new Exception(Exception::PROVIDER_INCORRECT_TYPE) }; @@ -245,7 +245,7 @@ class Messaging extends Action $provider = new Document([ '$id' => ID::unique(), 'provider' => $host, - 'type' => 'sms', + 'type' => MESSAGE_TYPE_SMS, 'name' => 'Internal SMS', 'enabled' => true, 'credentials' => match ($host) { diff --git a/src/Appwrite/Utopia/Response/Model/Provider.php b/src/Appwrite/Utopia/Response/Model/Provider.php index f8a051402..d3de061aa 100644 --- a/src/Appwrite/Utopia/Response/Model/Provider.php +++ b/src/Appwrite/Utopia/Response/Model/Provider.php @@ -50,7 +50,7 @@ class Provider extends Model 'type' => self::TYPE_STRING, 'description' => 'Type of provider.', 'default' => '', - 'example' => 'sms', + 'example' => MESSAGE_TYPE_SMS, ]) ->addRule('credentials', [ 'type' => self::TYPE_JSON, From 82c86c0ae2e9a0d44a1c18cd6c4e8252023544b9 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Wed, 29 Nov 2023 17:08:25 +1300 Subject: [PATCH 2/5] `deliveryTime` -> `scheduledAt` --- app/config/collections.php | 2 +- app/controllers/api/messaging.php | 68 +++++++++++++++---------------- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/app/config/collections.php b/app/config/collections.php index 7e715baa2..d1db57c42 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -1572,7 +1572,7 @@ $commonCollections = [ 'filters' => [], ], [ - '$id' => ID::custom('deliveryTime'), + '$id' => ID::custom('scheduledAt'), 'type' => Database::VAR_DATETIME, 'format' => '', 'size' => 0, diff --git a/app/controllers/api/messaging.php b/app/controllers/api/messaging.php index f13b037b0..85be4242c 100644 --- a/app/controllers/api/messaging.php +++ b/app/controllers/api/messaging.php @@ -101,7 +101,7 @@ App::post('/v1/messaging/providers/mailgun') '$id' => $providerId, 'name' => $name, 'provider' => 'mailgun', - 'type' => 'email', + 'type' => MESSAGE_TYPE_EMAIL, 'enabled' => $enabled, 'credentials' => $credentials, 'options' => $options, @@ -172,7 +172,7 @@ App::post('/v1/messaging/providers/sendgrid') '$id' => $providerId, 'name' => $name, 'provider' => 'sendgrid', - 'type' => 'email', + 'type' => MESSAGE_TYPE_EMAIL, 'enabled' => $enabled, 'credentials' => $credentials, 'options' => $options, @@ -249,7 +249,7 @@ App::post('/v1/messaging/providers/msg91') '$id' => $providerId, 'name' => $name, 'provider' => 'msg91', - 'type' => 'sms', + 'type' => MESSAGE_TYPE_SMS, 'enabled' => $enabled, 'credentials' => $credentials, 'options' => $options, @@ -326,7 +326,7 @@ App::post('/v1/messaging/providers/telesign') '$id' => $providerId, 'name' => $name, 'provider' => 'telesign', - 'type' => 'sms', + 'type' => MESSAGE_TYPE_SMS, 'enabled' => $enabled, 'credentials' => $credentials, 'options' => $options, @@ -403,7 +403,7 @@ App::post('/v1/messaging/providers/textmagic') '$id' => $providerId, 'name' => $name, 'provider' => 'textmagic', - 'type' => 'sms', + 'type' => MESSAGE_TYPE_SMS, 'enabled' => $enabled, 'credentials' => $credentials, 'options' => $options, @@ -480,7 +480,7 @@ App::post('/v1/messaging/providers/twilio') '$id' => $providerId, 'name' => $name, 'provider' => 'twilio', - 'type' => 'sms', + 'type' => MESSAGE_TYPE_SMS, 'enabled' => $enabled, 'credentials' => $credentials, 'options' => $from, @@ -557,7 +557,7 @@ App::post('/v1/messaging/providers/vonage') '$id' => $providerId, 'name' => $name, 'provider' => 'vonage', - 'type' => 'sms', + 'type' => MESSAGE_TYPE_SMS, 'enabled' => $enabled, 'credentials' => $credentials, 'options' => $options, @@ -617,7 +617,7 @@ App::post('/v1/messaging/providers/fcm') '$id' => $providerId, 'name' => $name, 'provider' => 'fcm', - 'type' => 'push', + 'type' => MESSAGE_TYPE_PUSH, 'enabled' => $enabled, 'credentials' => $credentials ]); @@ -703,7 +703,7 @@ App::post('/v1/messaging/providers/apns') '$id' => $providerId, 'name' => $name, 'provider' => 'apns', - 'type' => 'push', + 'type' => MESSAGE_TYPE_PUSH, 'enabled' => $enabled, 'credentials' => $credentials, ]); @@ -2211,7 +2211,7 @@ App::post('/v1/messaging/messages/email') ->label('scope', 'messages.write') ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') - ->label('sdk.method', 'createEmail') + ->label('sdk.method', 'createEmailMessage') ->label('sdk.description', '/docs/references/messaging/create-email.md') ->label('sdk.response.code', Response::STATUS_CODE_CREATED) ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) @@ -2225,13 +2225,13 @@ App::post('/v1/messaging/messages/email') ->param('description', '', new Text(256), 'Description for message.', true) ->param('status', 'processing', new WhiteList(['draft', 'processing']), 'Message Status. Value must be either draft or processing.', true) ->param('html', false, new Boolean(), 'Is content of type HTML', true) - ->param('deliveryTime', null, new DatetimeValidator(requireDateInFuture: true), 'Delivery time for message in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future.', true) + ->param('scheduledAt', null, new DatetimeValidator(requireDateInFuture: true), 'Scheduled delivery time for message in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future.', true) ->inject('queueForEvents') ->inject('dbForProject') ->inject('project') ->inject('queueForMessaging') ->inject('response') - ->action(function (string $messageId, string $subject, string $content, array $topics, array $users, array $targets, string $description, string $status, bool $html, ?string $deliveryTime, Event $queueForEvents, Database $dbForProject, Document $project, Messaging $queueForMessaging, Response $response) { + ->action(function (string $messageId, string $subject, string $content, array $topics, array $users, array $targets, string $description, string $status, bool $html, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Document $project, Messaging $queueForMessaging, Response $response) { $messageId = $messageId == 'unique()' ? ID::unique() : $messageId; if (\count($topics) === 0 && \count($users) === 0 && \count($targets) === 0) { @@ -2276,7 +2276,7 @@ App::post('/v1/messaging/messages/sms') ->label('scope', 'messages.write') ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') - ->label('sdk.method', 'createSMS') + ->label('sdk.method', 'createSMSMessage') ->label('sdk.description', '/docs/references/messaging/create-sms.md') ->label('sdk.response.code', Response::STATUS_CODE_CREATED) ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) @@ -2288,13 +2288,13 @@ App::post('/v1/messaging/messages/sms') ->param('targets', [], new ArrayList(new Text(Database::LENGTH_KEY), 1), 'List of Targets IDs.', true) ->param('description', '', new Text(256), 'Description for Message.', true) ->param('status', 'processing', new WhiteList(['draft', 'processing']), 'Message Status. Value must be either draft or processing.', true) - ->param('deliveryTime', null, new DatetimeValidator(requireDateInFuture: true), 'Delivery time for message in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future.', true) + ->param('scheduledAt', null, new DatetimeValidator(requireDateInFuture: true), 'Scheduled delivery time for message in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future.', true) ->inject('queueForEvents') ->inject('dbForProject') ->inject('project') ->inject('queueForMessaging') ->inject('response') - ->action(function (string $messageId, string $content, array $topics, array $users, array $targets, string $description, string $status, ?string $deliveryTime, Event $queueForEvents, Database $dbForProject, Document $project, Messaging $queueForMessaging, Response $response) { + ->action(function (string $messageId, string $content, array $topics, array $users, array $targets, string $description, string $status, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Document $project, Messaging $queueForMessaging, Response $response) { $messageId = $messageId == 'unique()' ? ID::unique() : $messageId; if (\count($topics) === 0 && \count($users) === 0 && \count($targets) === 0) { @@ -2337,7 +2337,7 @@ App::post('/v1/messaging/messages/push') ->label('scope', 'messages.write') ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') - ->label('sdk.method', 'createPushNotification') + ->label('sdk.method', 'createPushMessage') ->label('sdk.description', '/docs/references/messaging/create-push-notification.md') ->label('sdk.response.code', Response::STATUS_CODE_CREATED) ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) @@ -2357,13 +2357,13 @@ App::post('/v1/messaging/messages/push') ->param('tag', '', new Text(256), 'Tag for push notification. Available only for Android Platform.', true) ->param('badge', '', new Text(256), 'Badge for push notification. Available only for IOS Platform.', true) ->param('status', 'processing', new WhiteList(['draft', 'processing']), 'Message Status. Value must be either draft or processing.', true) - ->param('deliveryTime', null, new DatetimeValidator(requireDateInFuture: true), 'Delivery time for message in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future.', true) + ->param('scheduledAt', null, new DatetimeValidator(requireDateInFuture: true), 'Scheduled delivery time for message in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future.', true) ->inject('queueForEvents') ->inject('dbForProject') ->inject('project') ->inject('queueForMessaging') ->inject('response') - ->action(function (string $messageId, string $title, string $body, array $topics, array $users, array $targets, string $description, ?array $data, string $action, string $icon, string $sound, string $color, string $tag, string $badge, string $status, ?string $deliveryTime, Event $queueForEvents, Database $dbForProject, Document $project, Messaging $queueForMessaging, Response $response) { + ->action(function (string $messageId, string $title, string $body, array $topics, array $users, array $targets, string $description, ?array $data, string $action, string $icon, string $sound, string $color, string $tag, string $badge, string $status, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Document $project, Messaging $queueForMessaging, Response $response) { $messageId = $messageId == 'unique()' ? ID::unique() : $messageId; if (\count($topics) === 0 && \count($users) === 0 && \count($targets) === 0) { @@ -2409,7 +2409,7 @@ App::post('/v1/messaging/messages/push') 'users' => $users, 'targets' => $targets, 'description' => $description, - 'deliveryTime' => $deliveryTime, + 'scheduledAt' => $scheduledAt, 'data' => $pushData, 'status' => $status, ])); @@ -2603,13 +2603,13 @@ App::patch('/v1/messaging/messages/email/:messageId') ->param('content', '', new Text(64230), 'Email Content.', true) ->param('status', '', new WhiteList(['draft', 'processing']), 'Message Status. Value must be either draft or processing.', true) ->param('html', false, new Boolean(), 'Is content of type HTML', true) - ->param('deliveryTime', null, new DatetimeValidator(requireDateInFuture: true), 'Delivery time for message in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future.', true) + ->param('scheduledAt', null, new DatetimeValidator(requireDateInFuture: true), 'Scheduled delivery time for message in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future.', true) ->inject('queueForEvents') ->inject('dbForProject') ->inject('project') ->inject('queueForMessaging') ->inject('response') - ->action(function (string $messageId, ?array $topics, ?array $users, ?array $targets, string $subject, string $description, string $content, string $status, bool $html, ?string $deliveryTime, Event $queueForEvents, Database $dbForProject, Document $project, Messaging $queueForMessaging, Response $response) { + ->action(function (string $messageId, ?array $topics, ?array $users, ?array $targets, string $subject, string $description, string $content, string $status, bool $html, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Document $project, Messaging $queueForMessaging, Response $response) { $message = $dbForProject->getDocument('messages', $messageId); if ($message->isEmpty()) { @@ -2620,7 +2620,7 @@ App::patch('/v1/messaging/messages/email/:messageId') throw new Exception(Exception::MESSAGE_ALREADY_SENT); } - if (!is_null($message->getAttribute('deliveryTime')) && $message->getAttribute('deliveryTime') < new \DateTime()) { + if (!is_null($message->getAttribute('scheduledAt')) && $message->getAttribute('scheduledAt') < new \DateTime()) { throw new Exception(Exception::MESSAGE_ALREADY_SCHEDULED); } @@ -2660,8 +2660,8 @@ App::patch('/v1/messaging/messages/email/:messageId') $message->setAttribute('status', $status); } - if (!is_null($deliveryTime)) { - $message->setAttribute('deliveryTime', $deliveryTime); + if (!is_null($scheduledAt)) { + $message->setAttribute('scheduledAt', $scheduledAt); } $message = $dbForProject->updateDocument('messages', $message->getId(), $message); @@ -2701,13 +2701,13 @@ App::patch('/v1/messaging/messages/sms/:messageId') ->param('description', '', new Text(256), 'Description for Message.', true) ->param('content', '', new Text(64230), 'Email Content.', true) ->param('status', '', new WhiteList(['draft', 'processing']), 'Message Status. Value must be either draft or processing.', true) - ->param('deliveryTime', null, new DatetimeValidator(requireDateInFuture: true), 'Delivery time for message in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future.', true) + ->param('scheduledAt', null, new DatetimeValidator(requireDateInFuture: true), 'Scheduled delivery time for message in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future.', true) ->inject('queueForEvents') ->inject('dbForProject') ->inject('project') ->inject('queueForMessaging') ->inject('response') - ->action(function (string $messageId, ?array $topics, ?array $users, ?array $targets, string $description, string $content, string $status, ?string $deliveryTime, Event $queueForEvents, Database $dbForProject, Document $project, Messaging $queueForMessaging, Response $response) { + ->action(function (string $messageId, ?array $topics, ?array $users, ?array $targets, string $description, string $content, string $status, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Document $project, Messaging $queueForMessaging, Response $response) { $message = $dbForProject->getDocument('messages', $messageId); if ($message->isEmpty()) { @@ -2718,7 +2718,7 @@ App::patch('/v1/messaging/messages/sms/:messageId') throw new Exception(Exception::MESSAGE_ALREADY_SENT); } - if (!is_null($message->getAttribute('deliveryTime')) && $message->getAttribute('deliveryTime') < new \DateTime()) { + if (!is_null($message->getAttribute('scheduledAt')) && $message->getAttribute('scheduledAt') < new \DateTime()) { throw new Exception(Exception::MESSAGE_ALREADY_SCHEDULED); } @@ -2750,8 +2750,8 @@ App::patch('/v1/messaging/messages/sms/:messageId') $message->setAttribute('description', $description); } - if (!is_null($deliveryTime)) { - $message->setAttribute('deliveryTime', $deliveryTime); + if (!is_null($scheduledAt)) { + $message->setAttribute('scheduledAt', $scheduledAt); } $message = $dbForProject->updateDocument('messages', $message->getId(), $message); @@ -2798,13 +2798,13 @@ App::patch('/v1/messaging/messages/push/:messageId') ->param('color', '', new Text(256), 'Color for push notification. Available only for Android Platform.', true) ->param('tag', '', new Text(256), 'Tag for push notification. Available only for Android Platform.', true) ->param('badge', '', new Text(256), 'Badge for push notification. Available only for IOS Platform.', true) ->param('status', 'processing', new WhiteList(['draft', 'processing']), 'Message Status. Value must be either draft or processing.', true) - ->param('deliveryTime', null, new DatetimeValidator(requireDateInFuture: true), 'Delivery time for message in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future.', true) + ->param('scheduledAt', null, new DatetimeValidator(requireDateInFuture: true), 'Scheduled delivery time for message in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future.', true) ->inject('queueForEvents') ->inject('dbForProject') ->inject('project') ->inject('queueForMessaging') ->inject('response') - ->action(function (string $messageId, ?array $topics, ?array $users, ?array $targets, string $description, string $title, string $body, ?array $data, string $action, string $icon, string $sound, string $color, string $tag, string $badge, string $status, ?string $deliveryTime, Event $queueForEvents, Database $dbForProject, Document $project, Messaging $queueForMessaging, Response $response) { + ->action(function (string $messageId, ?array $topics, ?array $users, ?array $targets, string $description, string $title, string $body, ?array $data, string $action, string $icon, string $sound, string $color, string $tag, string $badge, string $status, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Document $project, Messaging $queueForMessaging, Response $response) { $message = $dbForProject->getDocument('messages', $messageId); if ($message->isEmpty()) { @@ -2815,7 +2815,7 @@ App::patch('/v1/messaging/messages/push/:messageId') throw new Exception(Exception::MESSAGE_ALREADY_SENT); } - if (!is_null($message->getAttribute('deliveryTime')) && $message->getAttribute('deliveryTime') < new \DateTime()) { + if (!is_null($message->getAttribute('scheduledAt')) && $message->getAttribute('scheduledAt') < new \DateTime()) { throw new Exception(Exception::MESSAGE_ALREADY_SCHEDULED); } @@ -2879,8 +2879,8 @@ App::patch('/v1/messaging/messages/push/:messageId') $message->setAttribute('description', $description); } - if (!is_null($deliveryTime)) { - $message->setAttribute('deliveryTime', $deliveryTime); + if (!is_null($scheduledAt)) { + $message->setAttribute('scheduledAt', $scheduledAt); } $message = $dbForProject->updateDocument('messages', $message->getId(), $message); From 4b58d08fd8f0b6609c7d6292018cdd50bb494755 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Wed, 29 Nov 2023 17:09:44 +1300 Subject: [PATCH 3/5] Add `providerType` to `Message` --- app/config/collections.php | 11 +++++ app/controllers/api/messaging.php | 38 ++++------------ src/Appwrite/Event/Messaging.php | 14 +++--- .../Utopia/Response/Model/Message.php | 8 +++- tests/e2e/Services/GraphQL/Base.php | 44 ++++++++++--------- 5 files changed, 57 insertions(+), 58 deletions(-) diff --git a/app/config/collections.php b/app/config/collections.php index d1db57c42..cbaed36f7 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -1505,6 +1505,17 @@ $commonCollections = [ '$id' => ID::custom('messages'), 'name' => 'Messages', 'attributes' => [ + [ + '$id' => ID::custom('providerType'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => true, + 'default' => null, + 'array' => false, + 'filters' => [], + ], [ '$id' => ID::custom('description'), 'type' => Database::VAR_STRING, diff --git a/app/controllers/api/messaging.php b/app/controllers/api/messaging.php index 85be4242c..411243d7b 100644 --- a/app/controllers/api/messaging.php +++ b/app/controllers/api/messaging.php @@ -2240,6 +2240,7 @@ App::post('/v1/messaging/messages/email') $message = $dbForProject->createDocument('messages', new Document([ '$id' => $messageId, + 'providerType' => MESSAGE_TYPE_EMAIL, 'topics' => $topics, 'users' => $users, 'targets' => $targets, @@ -2303,6 +2304,7 @@ App::post('/v1/messaging/messages/sms') $message = $dbForProject->createDocument('messages', new Document([ '$id' => $messageId, + 'providerType' => MESSAGE_TYPE_SMS, 'topics' => $topics, 'users' => $users, 'targets' => $targets, @@ -2370,41 +2372,19 @@ App::post('/v1/messaging/messages/push') throw new Exception(Exception::MESSAGE_MISSING_TARGET); } - $pushData = [ - 'title' => $title, - 'body' => $body, - ]; + $pushData = []; - if (!is_null($data)) { - $pushData['data'] = $data; - } + $keys = ['title', 'body', 'data', 'action', 'icon', 'sound', 'color', 'tag', 'badge']; - if ($action) { - $pushData['action'] = $action; - } - - if ($icon) { - $pushData['icon'] = $icon; - } - - if ($sound) { - $pushData['sound'] = $sound; - } - - if ($color) { - $pushData['color'] = $color; - } - - if ($tag) { - $pushData['tag'] = $tag; - } - - if ($badge) { - $pushData['badge'] = $badge; + foreach ($keys as $key) { + if (!empty($$key)) { + $pushData[$key] = $$key; + } } $message = $dbForProject->createDocument('messages', new Document([ '$id' => $messageId, + 'providerType' => MESSAGE_TYPE_PUSH, 'topics' => $topics, 'users' => $users, 'targets' => $targets, diff --git a/src/Appwrite/Event/Messaging.php b/src/Appwrite/Event/Messaging.php index 62d41f8c3..920179935 100644 --- a/src/Appwrite/Event/Messaging.php +++ b/src/Appwrite/Event/Messaging.php @@ -11,7 +11,7 @@ class Messaging extends Event protected ?string $messageId = null; protected ?Document $message = null; protected ?array $recipients = null; - protected ?string $deliveryTime = null; + protected ?string $scheduledAt = null; protected ?string $providerType = null; @@ -117,14 +117,14 @@ class Messaging extends Event } /** - * Sets Delivery time for the messaging event. + * Sets Scheduled delivery time for the messaging event. * - * @param string $deliveryTime + * @param string $scheduledAt * @return self */ - public function setDeliveryTime(string $deliveryTime): self + public function setScheduledAt(string $scheduledAt): self { - $this->deliveryTime = $deliveryTime; + $this->scheduledAt = $scheduledAt; return $this; } @@ -134,9 +134,9 @@ class Messaging extends Event * * @return string */ - public function getDeliveryTime(): string + public function getScheduledAt(): string { - return $this->deliveryTime; + return $this->scheduledAt; } /** diff --git a/src/Appwrite/Utopia/Response/Model/Message.php b/src/Appwrite/Utopia/Response/Model/Message.php index 27c70d707..32c67b693 100644 --- a/src/Appwrite/Utopia/Response/Model/Message.php +++ b/src/Appwrite/Utopia/Response/Model/Message.php @@ -29,6 +29,12 @@ class Message extends Any 'default' => '', 'example' => self::TYPE_DATETIME_EXAMPLE, ]) + ->addRule('providerType', [ + 'type' => self::TYPE_STRING, + 'description' => 'Message provider type.', + 'default' => '', + 'example' => MESSAGE_TYPE_EMAIL, + ]) ->addRule('topics', [ 'type' => self::TYPE_STRING, 'description' => 'Topic IDs set as recipients.', @@ -50,7 +56,7 @@ class Message extends Any 'array' => true, 'example' => ['5e5ea5c16897e'], ]) - ->addRule('deliveryTime', [ + ->addRule('scheduledAt', [ 'type' => self::TYPE_DATETIME, 'description' => 'The scheduled time for message.', 'required' => false, diff --git a/tests/e2e/Services/GraphQL/Base.php b/tests/e2e/Services/GraphQL/Base.php index 6939e6a9b..2854d0bf4 100644 --- a/tests/e2e/Services/GraphQL/Base.php +++ b/tests/e2e/Services/GraphQL/Base.php @@ -2098,13 +2098,13 @@ trait Base } }'; case self::$CREATE_EMAIL: - return 'mutation createEmail($messageId: String!, $topics: [String!], $users: [String!], $targets: [String!], $subject: String!, $content: String!, $status: String, $description: String, $html: Boolean, $deliveryTime: String) { - messagingCreateEmail(messageId: $messageId, topics: $topics, users: $users, targets: $targets, subject: $subject, content: $content, status: $status, description: $description, html: $html, deliveryTime: $deliveryTime) { + return 'mutation createEmail($messageId: String!, $topics: [String!], $users: [String!], $targets: [String!], $subject: String!, $content: String!, $status: String, $description: String, $html: Boolean, $scheduledAt: String) { + messagingCreateEmail(messageId: $messageId, topics: $topics, users: $users, targets: $targets, subject: $subject, content: $content, status: $status, description: $description, html: $html, scheduledAt: $scheduledAt) { _id topics users targets - deliveryTime + scheduledAt deliveredAt deliveryErrors deliveredTotal @@ -2113,13 +2113,13 @@ trait Base } }'; case self::$CREATE_SMS: - return 'mutation createSMS($messageId: String!, $topics: [String!], $users: [String!], $targets: [String!], $content: String!, $status: String, $description: String, $deliveryTime: String) { - messagingCreateSMS(messageId: $messageId, topics: $topics, users: $users, targets: $targets, content: $content, status: $status, description: $description, deliveryTime: $deliveryTime) { + return 'mutation createSMS($messageId: String!, $topics: [String!], $users: [String!], $targets: [String!], $content: String!, $status: String, $description: String, $scheduledAt: String) { + messagingCreateSMS(messageId: $messageId, topics: $topics, users: $users, targets: $targets, content: $content, status: $status, description: $description, scheduledAt: $scheduledAt) { _id topics users targets - deliveryTime + scheduledAt deliveredAt deliveryErrors deliveredTotal @@ -2128,13 +2128,13 @@ trait Base } }'; case self::$CREATE_PUSH_NOTIFICATION: - return 'mutation createPushNotification($messageId: String!, $topics: [String!], $users: [String!], $targets: [String!], $title: String!, $body: String!, $data: Json, $action: String, $icon: String, $sound: String, $color: String, $tag: String, $badge: String, $status: String, $description: String, $deliveryTime: String) { - messagingCreatePushNotification(messageId: $messageId, topics: $topics, users: $users, targets: $targets, title: $title, body: $body, data: $data, action: $action, icon: $icon, sound: $sound, color: $color, tag: $tag, badge: $badge, status: $status, description: $description, deliveryTime: $deliveryTime) { + return 'mutation createPushNotification($messageId: String!, $topics: [String!], $users: [String!], $targets: [String!], $title: String!, $body: String!, $data: Json, $action: String, $icon: String, $sound: String, $color: String, $tag: String, $badge: String, $status: String, $description: String, $scheduledAt: String) { + messagingCreatePushNotification(messageId: $messageId, topics: $topics, users: $users, targets: $targets, title: $title, body: $body, data: $data, action: $action, icon: $icon, sound: $sound, color: $color, tag: $tag, badge: $badge, status: $status, description: $description, scheduledAt: $scheduledAt) { _id topics users targets - deliveryTime + scheduledAt deliveredAt deliveryErrors deliveredTotal @@ -2148,10 +2148,11 @@ trait Base total messages { _id + providerType topics users targets - deliveryTime + scheduledAt deliveredAt deliveryErrors deliveredTotal @@ -2164,10 +2165,11 @@ trait Base return 'query getMessage($messageId: String!) { messagingGetMessage(messageId: $messageId) { _id + providerType topics users targets - deliveryTime + scheduledAt deliveredAt deliveryErrors deliveredTotal @@ -2176,13 +2178,13 @@ trait Base } }'; case self::$UPDATE_EMAIL: - return 'mutation updateEmail($messageId: String!, $topics: [String!], $users: [String!], $targets: [String!], $subject: String, $content: String, $status: String, $description: String, $html: Boolean, $deliveryTime: String) { - messagingUpdateEmail(messageId: $messageId, topics: $topics, users: $users, targets: $targets, subject: $subject, content: $content, status: $status, description: $description, html: $html, deliveryTime: $deliveryTime) { + return 'mutation updateEmail($messageId: String!, $topics: [String!], $users: [String!], $targets: [String!], $subject: String, $content: String, $status: String, $description: String, $html: Boolean, $scheduledAt: String) { + messagingUpdateEmail(messageId: $messageId, topics: $topics, users: $users, targets: $targets, subject: $subject, content: $content, status: $status, description: $description, html: $html, scheduledAt: $scheduledAt) { _id topics users targets - deliveryTime + scheduledAt deliveredAt deliveryErrors deliveredTotal @@ -2191,13 +2193,13 @@ trait Base } }'; case self::$UPDATE_SMS: - return 'mutation updateSMS($messageId: String!, $topics: [String!], $users: [String!], $targets: [String!], $content: String, $status: String, $description: String, $deliveryTime: String) { - messagingUpdateSMS(messageId: $messageId, topics: $topics, users: $users, targets: $targets, content: $content, status: $status, description: $description, deliveryTime: $deliveryTime) { + return 'mutation updateSMS($messageId: String!, $topics: [String!], $users: [String!], $targets: [String!], $content: String, $status: String, $description: String, $scheduledAt: String) { + messagingUpdateSMS(messageId: $messageId, topics: $topics, users: $users, targets: $targets, content: $content, status: $status, description: $description, scheduledAt: $scheduledAt) { _id topics users targets - deliveryTime + scheduledAt deliveredAt deliveryErrors deliveredTotal @@ -2206,13 +2208,13 @@ trait Base } }'; case self::$UPDATE_PUSH_NOTIFICATION: - return 'mutation updatePushNotification($messageId: String!, $topics: [String!], $users: [String!], $targets: [String!], $title: String, $body: String, $data: Json, $action: String, $icon: String, $sound: String, $color: String, $tag: String, $badge: String, $status: String, $description: String, $deliveryTime: String) { - messagingUpdatePushNotification(messageId: $messageId, topics: $topics, users: $users, targets: $targets, title: $title, body: $body, data: $data, action: $action, icon: $icon, sound: $sound, color: $color, tag: $tag, badge: $badge, status: $status, description: $description, deliveryTime: $deliveryTime) { + return 'mutation updatePushNotification($messageId: String!, $topics: [String!], $users: [String!], $targets: [String!], $title: String, $body: String, $data: Json, $action: String, $icon: String, $sound: String, $color: String, $tag: String, $badge: String, $status: String, $description: String, $scheduledAt: String) { + messagingUpdatePushNotification(messageId: $messageId, topics: $topics, users: $users, targets: $targets, title: $title, body: $body, data: $data, action: $action, icon: $icon, sound: $sound, color: $color, tag: $tag, badge: $badge, status: $status, description: $description, scheduledAt: $scheduledAt) { _id topics users targets - deliveryTime + scheduledAt deliveredAt deliveryErrors deliveredTotal @@ -2472,7 +2474,7 @@ trait Base protected string $stdout = ''; protected string $stderr = ''; - protected function packageCode($folder) + protected function packageCode($folder): void { Console::execute('cd ' . realpath(__DIR__ . "/../../../resources/functions") . "/$folder && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->stdout, $this->stderr); } From 042c1a725f7a7add6e77afcc381729e4c46a92c9 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Wed, 29 Nov 2023 17:10:53 +1300 Subject: [PATCH 4/5] `Message` extends `Model` instead of `Any` so rules are applied since `data` is not hoisted --- src/Appwrite/Utopia/Response/Model/Message.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Appwrite/Utopia/Response/Model/Message.php b/src/Appwrite/Utopia/Response/Model/Message.php index 32c67b693..bd9c8c6c5 100644 --- a/src/Appwrite/Utopia/Response/Model/Message.php +++ b/src/Appwrite/Utopia/Response/Model/Message.php @@ -5,8 +5,9 @@ namespace Appwrite\Utopia\Response\Model; use Appwrite\Utopia\Response; use Appwrite\Utopia\Response\Model; use Utopia\Database\DateTime; +use Utopia\Database\Document as DatabaseDocument; -class Message extends Any +class Message extends Model { public function __construct() { From 739cc36fdc88a032f6f6d66d090fd85dae79fca7 Mon Sep 17 00:00:00 2001 From: prateek banga Date: Wed, 29 Nov 2023 15:22:26 +0530 Subject: [PATCH 5/5] updated providerType wherever left to update --- app/controllers/api/account.php | 6 +-- app/init.php | 5 ++- composer.lock | 75 +++++++++++++++++---------------- 3 files changed, 44 insertions(+), 42 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index c80d2d438..68e3261a8 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -1315,7 +1315,7 @@ App::post('/v1/account/sessions/phone') $target = Authorization::skip(fn() => $dbForProject->createDocument('targets', new Document([ 'userId' => $user->getId(), 'userInternalId' => $user->getInternalId(), - 'providerType' => 'sms', + 'providerType' => MESSAGE_TYPE_SMS, 'identifier' => $phone, ]))); $user->setAttribute('targets', [...$user->getAttribute('targets', []), $target]); @@ -1374,7 +1374,7 @@ App::post('/v1/account/sessions/phone') $queueForMessaging ->setMessage($messageDoc) ->setRecipients([$phone]) - ->setProviderType('SMS') + ->setProviderType(MESSAGE_TYPE_SMS) ->setProject($project) ->trigger(); @@ -3100,7 +3100,7 @@ App::post('/v1/account/verification/phone') $queueForMessaging ->setMessage($messageDoc) ->setRecipients([$user->getAttribute('phone')]) - ->setProviderType('SMS') + ->setProviderType(MESSAGE_TYPE_SMS) ->setProject($project) ->trigger(); diff --git a/app/init.php b/app/init.php index 800b32fdd..4dfdcaf10 100644 --- a/app/init.php +++ b/app/init.php @@ -609,10 +609,11 @@ Database::addFilter( ]; $data = \json_decode($message->getAttribute('data', []), true); + $providerType = $message->getAttribute('providerType', ''); - if (\array_key_exists('subject', $data)) { + if ($providerType === MESSAGE_TYPE_EMAIL) { $searchValues = \array_merge($searchValues, [$data['subject'], MESSAGE_TYPE_EMAIL]); - } elseif (\array_key_exists('content', $data)) { + } elseif ($providerType === MESSAGE_TYPE_SMS) { $searchValues = \array_merge($searchValues, [$data['content'], MESSAGE_TYPE_SMS]); } else { $searchValues = \array_merge($searchValues, [$data['title'], MESSAGE_TYPE_PUSH]); diff --git a/composer.lock b/composer.lock index afa71aaf2..16f44a635 100644 --- a/composer.lock +++ b/composer.lock @@ -156,11 +156,11 @@ }, { "name": "appwrite/php-runtimes", - "version": "0.13.1", + "version": "0.13.2", "source": { "type": "git", "url": "https://github.com/appwrite/runtimes.git", - "reference": "b584d19cdcd82737d0ee5c34d23de791f5ed3610" + "reference": "214a37c2c66e0f2bc9c30fdfde66955d9fd084a1" }, "require": { "php": ">=8.0", @@ -195,7 +195,7 @@ "php", "runtimes" ], - "time": "2023-10-16T15:39:53+00:00" + "time": "2023-11-22T15:36:00+00:00" }, { "name": "chillerlan/php-qrcode", @@ -1465,7 +1465,7 @@ }, { "name": "symfony/deprecation-contracts", - "version": "v3.3.0", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", @@ -1512,7 +1512,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.3.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0" }, "funding": [ { @@ -2217,16 +2217,16 @@ }, { "name": "utopia-php/logger", - "version": "0.3.1", + "version": "0.3.2", "source": { "type": "git", "url": "https://github.com/utopia-php/logger.git", - "reference": "de623f1ec1c672c795d113dd25c5bf212f7ef4fc" + "reference": "ba763c10688fe2ed715ad2bed3f13d18dfec6253" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/logger/zipball/de623f1ec1c672c795d113dd25c5bf212f7ef4fc", - "reference": "de623f1ec1c672c795d113dd25c5bf212f7ef4fc", + "url": "https://api.github.com/repos/utopia-php/logger/zipball/ba763c10688fe2ed715ad2bed3f13d18dfec6253", + "reference": "ba763c10688fe2ed715ad2bed3f13d18dfec6253", "shasum": "" }, "require": { @@ -2264,9 +2264,9 @@ ], "support": { "issues": "https://github.com/utopia-php/logger/issues", - "source": "https://github.com/utopia-php/logger/tree/0.3.1" + "source": "https://github.com/utopia-php/logger/tree/0.3.2" }, - "time": "2023-02-10T15:52:50+00:00" + "time": "2023-11-22T14:45:43+00:00" }, { "name": "utopia-php/messaging", @@ -3136,16 +3136,16 @@ "packages-dev": [ { "name": "appwrite/sdk-generator", - "version": "0.35.2", + "version": "0.35.3", "source": { "type": "git", "url": "https://github.com/appwrite/sdk-generator.git", - "reference": "2dfe0430a64ffd2a07078d83b20144b871acac3b" + "reference": "4c431d5324a8f8cd2cab9a5515c170a5b427d44c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/2dfe0430a64ffd2a07078d83b20144b871acac3b", - "reference": "2dfe0430a64ffd2a07078d83b20144b871acac3b", + "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/4c431d5324a8f8cd2cab9a5515c170a5b427d44c", + "reference": "4c431d5324a8f8cd2cab9a5515c170a5b427d44c", "shasum": "" }, "require": { @@ -3181,9 +3181,9 @@ "description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms", "support": { "issues": "https://github.com/appwrite/sdk-generator/issues", - "source": "https://github.com/appwrite/sdk-generator/tree/0.35.2" + "source": "https://github.com/appwrite/sdk-generator/tree/0.35.3" }, - "time": "2023-09-14T14:59:50+00:00" + "time": "2023-11-12T05:56:27+00:00" }, { "name": "doctrine/deprecations", @@ -3890,16 +3890,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.24.2", + "version": "1.24.4", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "bcad8d995980440892759db0c32acae7c8e79442" + "reference": "6bd0c26f3786cd9b7c359675cb789e35a8e07496" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/bcad8d995980440892759db0c32acae7c8e79442", - "reference": "bcad8d995980440892759db0c32acae7c8e79442", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/6bd0c26f3786cd9b7c359675cb789e35a8e07496", + "reference": "6bd0c26f3786cd9b7c359675cb789e35a8e07496", "shasum": "" }, "require": { @@ -3931,9 +3931,9 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.24.2" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.24.4" }, - "time": "2023-09-26T12:28:12+00:00" + "time": "2023-11-26T18:29:22+00:00" }, { "name": "phpunit/php-code-coverage", @@ -5676,16 +5676,16 @@ }, { "name": "theseer/tokenizer", - "version": "1.2.1", + "version": "1.2.2", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b2ad5003ca10d4ee50a12da31de12a5774ba6b96", + "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96", "shasum": "" }, "require": { @@ -5714,7 +5714,7 @@ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "support": { "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + "source": "https://github.com/theseer/tokenizer/tree/1.2.2" }, "funding": [ { @@ -5722,30 +5722,31 @@ "type": "github" } ], - "time": "2021-07-28T10:34:58+00:00" + "time": "2023-11-20T00:12:19+00:00" }, { "name": "twig/twig", - "version": "v3.7.1", + "version": "v3.8.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "a0ce373a0ca3bf6c64b9e3e2124aca502ba39554" + "reference": "9d15f0ac07f44dc4217883ec6ae02fd555c6f71d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/a0ce373a0ca3bf6c64b9e3e2124aca502ba39554", - "reference": "a0ce373a0ca3bf6c64b9e3e2124aca502ba39554", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/9d15f0ac07f44dc4217883ec6ae02fd555c6f71d", + "reference": "9d15f0ac07f44dc4217883ec6ae02fd555c6f71d", "shasum": "" }, "require": { "php": ">=7.2.5", "symfony/polyfill-ctype": "^1.8", - "symfony/polyfill-mbstring": "^1.3" + "symfony/polyfill-mbstring": "^1.3", + "symfony/polyfill-php80": "^1.22" }, "require-dev": { "psr/container": "^1.0|^2.0", - "symfony/phpunit-bridge": "^5.4.9|^6.3" + "symfony/phpunit-bridge": "^5.4.9|^6.3|^7.0" }, "type": "library", "autoload": { @@ -5781,7 +5782,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.7.1" + "source": "https://github.com/twigphp/Twig/tree/v3.8.0" }, "funding": [ { @@ -5793,7 +5794,7 @@ "type": "tidelift" } ], - "time": "2023-08-28T11:09:02+00:00" + "time": "2023-11-21T18:54:41+00:00" } ], "aliases": [],