Skip to content

Commit 805aec7

Browse files
committed
Add plugintype and additional docs SMS subsystem
1 parent 91c724d commit 805aec7

File tree

2 files changed

+165
-0
lines changed

2 files changed

+165
-0
lines changed

docs/apis/plugintypes/sms/index.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
---
2+
title: SMS gateway plugin
3+
tags:
4+
- SMS
5+
- Gateway
6+
- SMS gateway
7+
- Notification
8+
---
9+
10+
<Since version="4.5" issueNumber="MDL-83406" />
11+
12+
SMS gateway plugins allows you to create SMS gateway provider, which can be used to send SMS notification to users from your Moodle instance.
13+
For example, you use MFA (Multi-Factor Authentication) to user authentication in Moodle and you use AWS as your SMS gateway provider. You can
14+
now build more SMS Gateway providers to allow sending SMS to your users.
15+
16+
## File structure
17+
18+
SMS gateway plugins are located in the /sms/gateway directory. A plugin should not include any custom files outside its own
19+
plugin folder.
20+
21+
Each plugin is in a separate subdirectory and consists of a number of _mandatory files_ and any other files the developer is going to use.
22+
23+
:::important
24+
25+
Some important files are described below. See the [common plugin files](../../commonfiles/index.mdx) documentation for details of other
26+
files which may be useful in your plugin.
27+
28+
:::
29+
30+
<details>
31+
<summary>The directory layout for the `smsgateway` plugin.</summary>
32+
33+
```console
34+
sms/gateway/example
35+
├── classes
36+
│   ├── gateway.php
37+
│   ├── hook_listener.php
38+
│   └── privacy
39+
│   └── provider.php
40+
├── lang
41+
│   └── en
42+
│   └── smsgateway_example.php
43+
├── settings.php
44+
└── version.php
45+
```
46+
47+
</details>
48+
49+
## Key files
50+
51+
There are a number of key files within the plugin, described below.
52+
53+
### gateway.php
54+
Each plugin must implement this class and should have the exact class name. The core_sms api will pick the extended methods from this class.
55+
56+
```php title="Implementing the base SMS gateway"
57+
58+
class gateway extends \core_sms\gateway {
59+
60+
#[\Override]
61+
public function send(
62+
message $message,
63+
): message {
64+
// Sample code to send an SMS message.
65+
$config = (object)json_decode($awsconfig, true, 512, JSON_THROW_ON_ERROR);
66+
$class = '\smsgateway_aws\local\service\\' . $config->gateway;
67+
$recipientnumber = manager::format_number(
68+
phonenumber: $message->recipientnumber,
69+
countrycode: isset($config->countrycode) ?? null,
70+
);
71+
if (class_exists($class)) {
72+
$status = call_user_func(
73+
$class . '::send_sms_message',
74+
$message->content,
75+
$recipientnumber,
76+
$config,
77+
);
78+
}
79+
return $message->with(
80+
status: $status,
81+
);
82+
}
83+
84+
#[\Override]
85+
public function get_send_priority(message $message): int {
86+
return 50;
87+
}
88+
}
89+
90+
```
91+
### hook_listener.php
92+
There a couple of hooks dispatched from the core_sms API which can be listened by the plugin. It is necessary for plugins developers to assess
93+
these hooks and implement accordingly.
94+
95+
#### after_sms_gateway_form_hook
96+
This hook will allow plugins to add their relevant form field from the plugin to allow users to add required configs for the SMS gateway.
97+
98+
99+
```php title="Listener method for after_sms_gateway_form_hook"
100+
101+
public static function set_form_definition_for_aws_sms_gateway(after_sms_gateway_form_hook $hook): void {
102+
if ($hook->plugin !== 'smsgateway_example') {
103+
return;
104+
}
105+
106+
$gateways = [
107+
'smsgateway_example' => get_string('list', 'smsgateway_example'),
108+
];
109+
$mform->addElement(
110+
'select',
111+
'gateway',
112+
get_string('gateway', 'smsgateway_example'),
113+
$gateways,
114+
);
115+
}
116+
117+
```
118+
:::info
119+
120+
For a real plugin example, please look at the [AWS SMS Gateway plugin](https://github.com/moodle/moodle/tree/main/sms/gateway/aws).
121+
122+
:::

docs/apis/subsystems/sms/index.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ $message = \core\di::get(\core_sms\manager::class)
2020
recipientuserid: $user->id,
2121
issensitive: false,
2222
async: false,
23+
gatewayid: 22,
2324
);
2425
```
2526

@@ -122,3 +123,45 @@ graph TD
122123
GQ --> |Gateway failed to send the message| GF
123124
end
124125
```
126+
127+
## Getting the list of SMS gateways
128+
129+
Once the gateway is configured from UI, any component implementing the core_sms API can get the list of gateways. The list can also be filtered.
130+
131+
```php title="Getting the list of enabled gateways"
132+
$manager = \core\di::get(\core_sms\manager::class);
133+
$gatewayrecords = $manager->get_gateway_records();
134+
135+
// It is also possible to filter the requst.
136+
$gatewayrecords = $manager->get_gateway_records(['id' => $id]);
137+
138+
// To get all the enabled gateway instances.
139+
$gatewayrecords = $manager->get_enabled_gateway_instances();
140+
```
141+
142+
## Some important hooks to be aware of
143+
SMS API dispatches some hooks which should be assessed and used when this API is implemented in a plugin/component. These hooks helps with
144+
managing the data, like save them from deletion or accidental deactivation from the SMS Gateway management UI while a specific gateway is
145+
being used by a component.
146+
147+
### before_gateway_deleted & before_gateway_disabled
148+
Before deleting or disabling an SMS gateway, these two hooks are dispatched from the core_sms API to allow the components using that specific
149+
gateway to stop that action or do necessary cleanup. It is important to listed to these hooks to prevent data loss or potential issues with a
150+
gateway being used which is deleted or disabled by accident.
151+
152+
```php title="Implement the hooks to check for usage before deletion or deactivation"
153+
154+
public static function check_gateway_usage_in_example_plugin(
155+
before_gateway_deleted|before_gateway_disabled $hook,
156+
): void {
157+
try {
158+
$smsgatewayid = (int)get_config('example_plugin', 'smsgateway');
159+
if ($smsgatewayid && $smsgatewayid === (int)$hook->gateway->id) {
160+
$hook->stop_propagation();
161+
}
162+
} catch (\dml_exception $exception) {
163+
$hook->stop_propagation();
164+
}
165+
}
166+
167+
```

0 commit comments

Comments
 (0)