Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
namespace core_communication;
18
 
19
use core\context;
20
use core_communication\task\add_members_to_room_task;
21
use core_communication\task\create_and_configure_room_task;
22
use core_communication\task\delete_room_task;
23
use core_communication\task\remove_members_from_room;
24
use core_communication\task\synchronise_provider_task;
25
use core_communication\task\update_room_task;
26
use core_communication\task\update_room_membership_task;
27
use stdClass;
28
 
29
/**
30
 * Class api is the public endpoint of the communication api. This class is the point of contact for api usage.
31
 *
32
 * Communication api allows to add ad-hoc tasks to the queue to perform actions on the communication providers. This api will
33
 * not allow any immediate actions to be performed on the communication providers. It will only add the tasks to the queue. The
34
 * exception has been made for deletion of members in case of deleting the user. This is because the user will not be available.
35
 * The member management api part allows run actions immediately if required.
36
 *
37
 * Communication api does allow to have form elements related to communication api in the required forms. This is done by using
38
 * the form_definition method. This method will add the form elements to the form.
39
 *
40
 * @package    core_communication
41
 * @copyright  2023 Safat Shahin <safat.shahin@moodle.com>
42
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
43
 */
44
class api {
45
    /**
46
     * @var null|processor $communication The communication settings object
47
     */
48
    private ?processor $communication;
49
 
50
    /**
51
     * Communication handler constructor to manage and handle all communication related actions.
52
     *
53
     * This class is the entrypoint for all kinda usages.
54
     * It will be used by the other api to manage the communication providers.
55
     *
56
     * @param context $context The context of the item for the instance
57
     * @param string $component The component of the item for the instance
58
     * @param string $instancetype The type of the item for the instance
59
     * @param int $instanceid The id of the instance
60
     * @param string|null $provider The provider type - if null will load for this context's active provider.
61
     *
62
     */
63
    private function __construct(
64
        private context $context,
65
        private string $component,
66
        private string $instancetype,
67
        private int $instanceid,
68
        private ?string $provider = null,
69
    ) {
70
        $this->communication = processor::load_by_instance(
71
            context: $context,
72
            component: $component,
73
            instancetype: $instancetype,
74
            instanceid: $instanceid,
75
            provider: $provider,
76
        );
77
    }
78
 
79
    /**
80
     * Get the communication processor object.
81
     *
82
     * @param context $context The context of the item for the instance
83
     * @param string $component The component of the item for the instance
84
     * @param string $instancetype The type of the item for the instance
85
     * @param int $instanceid The id of the instance
86
     * @param string|null $provider The provider type - if null will load for this context's active provider.
87
     * @return api
88
     */
89
    public static function load_by_instance(
90
        context $context,
91
        string $component,
92
        string $instancetype,
93
        int $instanceid,
94
        ?string $provider = null,
95
    ): self {
96
        return new self(
97
            context: $context,
98
            component: $component,
99
            instancetype: $instancetype,
100
            instanceid: $instanceid,
101
            provider: $provider,
102
        );
103
    }
104
 
105
    /**
106
     * Reload in the internal instance data.
107
     */
108
    public function reload(): void {
109
        $this->communication = processor::load_by_instance(
110
            context: $this->context,
111
            component: $this->component,
112
            instancetype: $this->instancetype,
113
            instanceid: $this->instanceid,
114
            provider: $this->provider,
115
        );
116
    }
117
 
118
    /**
119
     * Return the underlying communication processor object.
120
     *
121
     * @return ?processor
122
     */
123
    public function get_processor(): ?processor {
124
        return $this->communication;
125
    }
126
 
127
    /**
128
     * Return the room provider.
129
     *
130
     * @return \core_communication\room_chat_provider
131
     */
132
    public function get_room_provider(): \core_communication\room_chat_provider {
133
        return $this->communication->get_room_provider();
134
    }
135
 
136
    /**
137
     * Return the user provider.
138
     *
139
     * @return \core_communication\user_provider
140
     */
141
    public function get_user_provider(): \core_communication\user_provider {
142
        return $this->communication->get_user_provider();
143
    }
144
 
145
    /**
146
     * Return the room user provider.
147
     *
148
     * @return \core_communication\room_user_provider
149
     */
150
    public function get_room_user_provider(): \core_communication\room_user_provider {
151
        return $this->communication->get_room_user_provider();
152
    }
153
 
154
    /**
155
     * Return the form provider.
156
     *
157
     * @return \core_communication\form_provider
158
     */
159
    public function get_form_provider(): \core_communication\form_provider {
160
        return $this->communication->get_form_provider();
161
    }
162
 
163
    /**
164
     * Check if the communication api is enabled.
165
     */
166
    public static function is_available(): bool {
167
        return (bool) get_config('core', 'enablecommunicationsubsystem');
168
    }
169
 
170
    /**
171
     * Get the communication room url.
172
     *
173
     * @return string|null
174
     */
175
    public function get_communication_room_url(): ?string {
176
        return $this->communication?->get_room_url();
177
    }
178
 
179
    /**
180
     * Get the list of plugins for form selection.
181
     *
182
     * @return array
183
     */
184
    public static function get_communication_plugin_list_for_form(): array {
185
        // Add the option to have communication disabled.
186
        $selection[processor::PROVIDER_NONE] = get_string('nocommunicationselected', 'communication');
187
        $communicationplugins = \core\plugininfo\communication::get_enabled_plugins();
188
        foreach ($communicationplugins as $pluginname => $notusing) {
189
            $provider = 'communication_' . $pluginname;
190
            if (processor::is_provider_available($provider)) {
191
                $selection[$provider] = get_string('pluginname', 'communication_' . $pluginname);
192
            }
193
        }
194
        return $selection;
195
    }
196
 
197
    /**
198
     * Get the enabled communication providers and default provider according to the selected provider.
199
     *
200
     * @param string|null $selecteddefaulprovider
201
     * @return array
202
     */
203
    public static function get_enabled_providers_and_default(string $selecteddefaulprovider = null): array {
204
        $communicationproviders = self::get_communication_plugin_list_for_form();
205
        $defaulprovider = processor::PROVIDER_NONE;
206
        if (!empty($selecteddefaulprovider) && array_key_exists($selecteddefaulprovider, $communicationproviders)) {
207
            $defaulprovider = $selecteddefaulprovider;
208
        }
209
        return [$communicationproviders, $defaulprovider];
210
    }
211
 
212
    /**
213
     * Define the form elements for the communication api.
214
     * This method will be called from the form definition method of the instance.
215
     *
216
     * @param \MoodleQuickForm $mform The form element
217
     * @param string $selectdefaultcommunication The default selected communication provider in the form field
218
     */
219
    public function form_definition(
220
        \MoodleQuickForm $mform,
221
        string $selectdefaultcommunication = processor::PROVIDER_NONE
222
    ): void {
223
        global $PAGE;
224
 
225
        [$communicationproviders, $defaulprovider] = self::get_enabled_providers_and_default($selectdefaultcommunication);
226
 
227
        $PAGE->requires->js_call_amd('core_communication/providerchooser', 'init');
228
 
229
        // List the communication providers.
230
        $mform->addElement(
231
            'select',
232
            'selectedcommunication',
233
            get_string('selectcommunicationprovider', 'communication'),
234
            $communicationproviders,
235
            ['data-communicationchooser-field' => 'selector'],
236
        );
237
        $mform->addHelpButton('selectedcommunication', 'selectcommunicationprovider', 'communication');
238
        $mform->setDefault('selectedcommunication', $defaulprovider);
239
 
240
        $mform->registerNoSubmitButton('updatecommunicationprovider');
241
        $mform->addElement(
242
            'submit',
243
            'updatecommunicationprovider',
244
            'update communication',
245
            ['data-communicationchooser-field' => 'updateButton', 'class' => 'd-none']
246
        );
247
 
248
        // Just a placeholder for the communication options.
249
        $mform->addElement('hidden', 'addcommunicationoptionshere');
250
        $mform->setType('addcommunicationoptionshere', PARAM_BOOL);
251
    }
252
 
253
    /**
254
     * Set the form definitions for the plugins.
255
     *
256
     * @param \MoodleQuickForm $mform The moodle form
257
     * @param string $provider The provider name
258
     */
259
    public function form_definition_for_provider(\MoodleQuickForm $mform, string $provider = processor::PROVIDER_NONE): void {
260
        if ($provider === processor::PROVIDER_NONE) {
261
            return;
262
        }
263
 
264
        // Room name for the communication provider.
265
        $mform->insertElementBefore(
266
            $mform->createElement(
267
                'text',
11 efrain 268
                $provider . 'roomname',
1 efrain 269
                get_string('communicationroomname', 'communication'),
270
                'maxlength="100" size="20"'
271
            ),
272
            'addcommunicationoptionshere'
273
        );
11 efrain 274
        $mform->setType($provider . 'roomname', PARAM_TEXT);
1 efrain 275
 
276
        $mform->insertElementBefore(
277
            $mform->createElement(
278
                'static',
279
                'communicationroomnameinfo',
280
                '',
281
                get_string('communicationroomnameinfo', 'communication'),
282
            ),
283
            'addcommunicationoptionshere',
284
        );
285
 
286
        processor::set_provider_specific_form_definition($provider, $mform);
287
    }
288
 
289
    /**
290
     * Get the avatar file.
291
     *
292
     * @return null|\stored_file
293
     */
294
    public function get_avatar(): ?\stored_file {
295
        $filename = $this->communication->get_avatar_filename();
296
        if ($filename === null) {
297
            return null;
298
        }
299
        $fs = get_file_storage();
300
        $args = (array) $this->get_avatar_filerecord($filename);
301
        return $fs->get_file(...$args) ?: null;
302
    }
303
 
304
    /**
305
     * Get the avatar file record for the avatar for filesystem.
306
     *
307
     * @param string $filename The filename of the avatar
308
     * @return stdClass
309
     */
310
    protected function get_avatar_filerecord(string $filename): stdClass {
311
        return (object) [
312
            'contextid' => \core\context\system::instance()->id,
313
            'component' => 'core_communication',
314
            'filearea' => 'avatar',
315
            'itemid' => $this->communication->get_id(),
316
            'filepath' => '/',
317
            'filename' => $filename,
318
        ];
319
    }
320
 
321
    /**
322
     * Get the avatar file.
323
     *
324
     * If null is set, then delete the old area file and set the avatarfilename to null.
325
     * This will make sure the plugin api deletes the avatar from the room.
326
     *
327
     * @param null|\stored_file $avatar The stored file for the avatar
328
     * @return bool
329
     */
330
    public function set_avatar(?\stored_file $avatar): bool {
331
        $currentfilename = $this->communication->get_avatar_filename();
332
        if ($avatar === null && empty($currentfilename)) {
333
            return false;
334
        }
335
 
336
        $currentfilerecord = $this->get_avatar();
337
        if ($avatar && $currentfilerecord) {
338
            $currentfilehash = $currentfilerecord->get_contenthash();
339
            $updatedfilehash = $avatar->get_contenthash();
340
 
341
            // No update required.
342
            if ($currentfilehash === $updatedfilehash) {
343
                return false;
344
            }
345
        }
346
 
347
        $context = \core\context\system::instance();
348
 
349
        $fs = get_file_storage();
350
        $fs->delete_area_files(
351
            $context->id,
352
            'core_communication',
353
            'avatar',
354
            $this->communication->get_id()
355
        );
356
 
357
        if ($avatar) {
358
            $fs->create_file_from_storedfile(
359
                $this->get_avatar_filerecord($avatar->get_filename()),
360
                $avatar,
361
            );
362
            $this->communication->set_avatar_filename($avatar->get_filename());
363
        } else {
364
            $this->communication->set_avatar_filename(null);
365
        }
366
 
367
        // Indicate that we need to sync the avatar when the update task is run.
368
        $this->communication->set_avatar_synced_flag(false);
369
 
370
        return true;
371
    }
372
 
373
    /**
374
     * A helper to fetch the room name
375
     *
376
     * @return string
377
     */
378
    public function get_room_name(): string {
11 efrain 379
        if (!$this->communication) {
380
            return '';
381
        }
1 efrain 382
        return $this->communication->get_room_name();
383
    }
384
 
385
    /**
386
     * Set the form data if the data is already available.
387
     *
388
     * @param \stdClass $instance The instance object
389
     */
390
    public function set_data(\stdClass $instance): void {
391
        if (!empty($instance->id) && $this->communication) {
392
            $instance->selectedcommunication = $this->communication->get_provider();
11 efrain 393
            $roomnameidentifier = $this->get_provider() . 'roomname';
394
            $instance->$roomnameidentifier = $this->communication->get_room_name();
1 efrain 395
 
396
            $this->communication->get_form_provider()->set_form_data($instance);
397
        }
398
    }
399
 
400
    /**
401
     * Get the communication provider.
402
     *
403
     * @return string
404
     */
405
    public function get_provider(): string {
406
        if (!$this->communication) {
407
            return '';
408
        }
409
        return $this->communication->get_provider();
410
    }
411
 
412
    /**
413
     * Configure the room and membership by provider selected for the communication instance.
414
     *
415
     * This method will add a task to the queue to configure the room and membership by comparing the change of provider.
416
     * There are some major cases to consider for this method to allow minimum duplication when this api is used.
417
     * Some of the major cases are:
418
     * 1. If the communication instance is not created at all, then create it and add members.
419
     * 2. If the current provider is none and the new provider is also none, then nothing to do.
420
     * 3. If the current and existing provider is the same, don't need to do anything.
421
     * 4. If provider set to none, remove all the members.
422
     * 5. If previous provider was not none and current provider is not none, but a different provider, remove members and add
423
     * for the new one.
424
     * 6. If previous provider was none and current provider is not none, don't need to remove, just
425
     * update the selected provider and add users to that provider. Do not queue the task to add members to room as the room
426
     * might not have created yet. The add room task adds the task to add members to room anyway.
427
     * 7. If it's a new provider, never used/created, now create the room after considering all these cases for a new provider.
428
     *
429
     * @param string $provider The provider name
430
     * @param \stdClass $instance The instance object
431
     * @param string $communicationroomname The communication room name
432
     * @param array $users The user ids to add to the room
433
     * @param null|\stored_file $instanceimage The stored file for the avatar
434
     * @param bool $queue Queue the task for the provider room or not
435
     */
436
    public function configure_room_and_membership_by_provider(
437
        string $provider,
438
        stdClass $instance,
439
        string $communicationroomname,
440
        array $users,
441
        ?\stored_file $instanceimage = null,
442
        bool $queue = true,
443
    ): void {
444
        // If the current provider is inactive and the new provider is also none, then nothing to do.
445
        if (
446
            $this->communication !== null &&
447
            $this->communication->get_provider_status() === processor::PROVIDER_INACTIVE &&
448
            $provider === processor::PROVIDER_NONE
449
        ) {
450
            return;
451
        }
452
 
453
        // If provider set to none, remove all the members.
454
        if (
455
            $this->communication !== null &&
456
            $this->communication->get_provider_status() === processor::PROVIDER_ACTIVE &&
457
            $provider === processor::PROVIDER_NONE
458
        ) {
459
            $this->remove_all_members_from_room();
460
            $this->update_room(
461
                active: processor::PROVIDER_INACTIVE,
462
                communicationroomname: $communicationroomname,
463
                avatar: $instanceimage,
464
                instance: $instance,
465
                queue: $queue,
466
            );
467
            return;
468
        }
469
 
470
        if (
471
            // If previous provider was active and not none and current provider is not none, but a different provider,
472
            // remove members and de-activate the previous provider.
473
            $this->communication !== null &&
474
            $this->communication->get_provider_status() === processor::PROVIDER_ACTIVE &&
475
            $provider !== $this->get_provider()
476
        ) {
477
            $this->remove_all_members_from_room();
478
            // Now deactivate the previous provider.
479
            $this->update_room(
480
                active: processor::PROVIDER_INACTIVE,
481
                instance: $instance,
482
                queue: $queue,
483
            );
484
        }
485
 
486
        // Now re-init the constructor for the new provider.
487
        $this->__construct(
488
            context: $this->context,
489
            component: $this->component,
490
            instancetype: $this->instancetype,
491
            instanceid: $this->instanceid,
492
            provider: $provider,
493
        );
494
 
495
        // If it's a new provider, never used/created, now create the room.
496
        if ($this->communication === null) {
497
            $this->create_and_configure_room(
498
                communicationroomname: $communicationroomname,
499
                avatar: $instanceimage,
500
                instance: $instance,
501
                queue: $queue,
502
            );
503
            $queueusertask = false;
504
        } else {
505
            // Otherwise update the room.
506
            $this->update_room(
507
                active: processor::PROVIDER_ACTIVE,
508
                communicationroomname: $communicationroomname,
509
                avatar: $instanceimage,
510
                instance: $instance,
511
                queue: $queue,
512
            );
513
            $queueusertask = true;
514
        }
515
 
516
        // Now add the members.
517
        $this->add_members_to_room(
518
            userids: $users,
519
            queue: $queueusertask,
520
        );
521
 
522
    }
523
 
524
    /**
525
     * Create a communication ad-hoc task for create operation.
526
     * This method will add a task to the queue to create the room.
527
     *
528
     * @param string $communicationroomname The communication room name
529
     * @param null|\stored_file $avatar The stored file for the avatar
530
     * @param \stdClass|null $instance The actual instance object
531
     * @param bool $queue Whether to queue the task or not
532
     */
533
    public function create_and_configure_room(
534
        string $communicationroomname,
535
        ?\stored_file $avatar = null,
536
        ?\stdClass $instance = null,
537
        bool $queue = true,
538
    ): void {
539
        if ($this->provider === processor::PROVIDER_NONE || $this->provider === '') {
540
            return;
541
        }
542
        // Create communication record.
543
        $this->communication = processor::create_instance(
544
            context: $this->context,
545
            provider: $this->provider,
546
            instanceid: $this->instanceid,
547
            component: $this->component,
548
            instancetype: $this->instancetype,
549
            roomname: $communicationroomname,
550
        );
551
 
552
        // Update provider record from form data.
553
        if ($instance !== null) {
554
            $this->communication->get_form_provider()->save_form_data($instance);
555
        }
556
 
557
        // Set the avatar.
558
        if (!empty($avatar)) {
559
            $this->set_avatar($avatar);
560
        }
561
 
562
        // Nothing else to do if the queue is false.
563
        if (!$queue) {
564
            return;
565
        }
566
 
567
        // Add ad-hoc task to create the provider room.
568
        create_and_configure_room_task::queue(
569
            $this->communication,
570
        );
571
    }
572
 
573
    /**
574
     * Create a communication ad-hoc task for update operation.
575
     * This method will add a task to the queue to update the room.
576
     *
577
     * @param null|int $active The selected active state of the provider
578
     * @param null|string $communicationroomname The communication room name
579
     * @param null|\stored_file $avatar The stored file for the avatar
580
     * @param \stdClass|null $instance The actual instance object
581
     * @param bool $queue Whether to queue the task or not
582
     */
583
    public function update_room(
584
        ?int $active = null,
585
        ?string $communicationroomname = null,
586
        ?\stored_file $avatar = null,
587
        ?\stdClass $instance = null,
588
        bool $queue = true,
589
    ): void {
590
        if (!$this->communication) {
591
            return;
592
        }
593
 
594
        // If the provider is none, we don't need to do anything from room point of view.
595
        if ($this->communication->get_provider() === processor::PROVIDER_NONE) {
596
            return;
597
        }
598
 
599
        $roomnamechange = null;
600
        $activestatuschange = null;
601
 
602
        // Check if the room name is being changed.
603
        if (
604
            $communicationroomname !== null &&
605
            $communicationroomname !== $this->communication->get_room_name()
606
        ) {
607
            $roomnamechange = $communicationroomname;
608
        }
609
 
610
        // Check if the active status of the provider is being changed.
611
        if (
612
            $active !== null &&
613
            $active !== $this->communication->is_instance_active()
614
        ) {
615
            $activestatuschange = $active;
616
        }
617
 
618
        if ($roomnamechange !== null || $activestatuschange !== null) {
619
            $this->communication->update_instance(
620
                active: $active,
621
                roomname: $communicationroomname,
622
            );
623
        }
624
 
625
        // Update provider record from form data.
626
        if ($instance !== null) {
627
            $this->communication->get_form_provider()->save_form_data($instance);
628
        }
629
 
630
        // Update the avatar.
631
        // If the value is `null`, then unset the avatar.
632
        $this->set_avatar($avatar);
633
 
634
        // Nothing else to do if the queue is false.
635
        if (!$queue) {
636
            return;
637
        }
638
 
639
        // Always queue a room update, even if none of the above standard fields have changed.
640
        // It is possible for providers to have custom fields that have been updated.
641
        update_room_task::queue(
642
            $this->communication,
643
        );
644
    }
645
 
646
    /**
647
     * Create a communication ad-hoc task for delete operation.
648
     * This method will add a task to the queue to delete the room.
649
     */
650
    public function delete_room(): void {
651
        if ($this->communication !== null) {
652
            // Add the ad-hoc task to remove the room data from the communication table and associated provider actions.
653
            delete_room_task::queue(
654
                $this->communication,
655
            );
656
        }
657
    }
658
 
659
    /**
660
     * Create a communication ad-hoc task for add members operation and add the user mapping.
661
     *
662
     * This method will add a task to the queue to add the room users.
663
     *
664
     * @param array $userids The user ids to add to the room
665
     * @param bool $queue Whether to queue the task or not
666
     */
667
    public function add_members_to_room(array $userids, bool $queue = true): void {
668
        // No communication object? something not done right.
669
        if (!$this->communication) {
670
            return;
671
        }
672
 
673
        // No user IDs or this provider does not manage users? No action required.
674
        if (empty($userids) || !$this->communication->supports_user_features()) {
675
            return;
676
        }
677
 
678
        $this->communication->create_instance_user_mapping($userids);
679
 
680
        if ($queue) {
681
            add_members_to_room_task::queue(
682
                $this->communication
683
            );
684
        }
685
    }
686
 
687
    /**
688
     * Create a communication ad-hoc task for updating members operation and update the user mapping.
689
     *
690
     * This method will add a task to the queue to update the room users.
691
     *
692
     * @param array $userids The user ids to add to the room
693
     * @param bool $queue Whether to queue the task or not
694
     */
695
    public function update_room_membership(array $userids, bool $queue = true): void {
696
        // No communication object? something not done right.
697
        if (!$this->communication) {
698
            return;
699
        }
700
 
701
        // No userids? don't bother doing anything.
702
        if (empty($userids)) {
703
            return;
704
        }
705
 
706
        $this->communication->reset_users_sync_flag($userids);
707
 
708
        if ($queue) {
709
            update_room_membership_task::queue(
710
                $this->communication
711
            );
712
        }
713
    }
714
 
715
    /**
716
     * Create a communication ad-hoc task for remove members operation or action immediately.
717
     *
718
     * This method will add a task to the queue to remove the room users.
719
     *
720
     * @param array $userids The user ids to remove from the room
721
     * @param bool $queue Whether to queue the task or not
722
     */
723
    public function remove_members_from_room(array $userids, bool $queue = true): void {
724
        // No communication object? something not done right.
725
        if (!$this->communication) {
726
            return;
727
        }
728
 
729
        $provider = $this->communication->get_provider();
730
 
731
        if ($provider === processor::PROVIDER_NONE) {
732
            return;
733
        }
734
 
735
        // No user IDs or this provider does not manage users? No action required.
736
        if (empty($userids) || !$this->communication->supports_user_features()) {
737
            return;
738
        }
739
 
740
        $this->communication->add_delete_user_flag($userids);
741
 
742
        if ($queue) {
743
            remove_members_from_room::queue(
744
                $this->communication
745
            );
746
        }
747
    }
748
 
749
    /**
750
     * Remove all users from the room.
751
     *
752
     * @param bool $queue Whether to queue the task or not
753
     */
754
    public function remove_all_members_from_room(bool $queue = true): void {
755
        // No communication object? something not done right.
756
        if (!$this->communication) {
757
            return;
758
        }
759
 
760
        if ($this->communication->get_provider() === processor::PROVIDER_NONE) {
761
            return;
762
        }
763
 
764
        // This provider does not manage users? No action required.
765
        if (!$this->communication->supports_user_features()) {
766
            return;
767
        }
768
 
769
        $this->communication->add_delete_user_flag($this->communication->get_all_userids_for_instance());
770
 
771
        if ($queue) {
772
            remove_members_from_room::queue(
773
                $this->communication
774
            );
775
        }
776
    }
777
 
778
    /**
779
     * Display the communication room status notification.
780
     */
781
    public function show_communication_room_status_notification(): void {
782
        // No communication, no room.
783
        if (!$this->communication) {
784
            return;
785
        }
786
 
787
        if ($this->communication->get_provider() === processor::PROVIDER_NONE) {
788
            return;
789
        }
790
 
791
        $roomstatus = $this->get_communication_room_url()
792
            ? constants::COMMUNICATION_STATUS_READY
793
            : constants::COMMUNICATION_STATUS_PENDING;
794
        $pluginname = get_string('pluginname', $this->get_provider());
795
        $message = get_string('communicationroom' . $roomstatus, 'communication', $pluginname);
796
 
797
        // We only show the ready notification once per user.
798
        // We check this with a custom user preference.
799
        $roomreadypreference = "{$this->component}_{$this->instancetype}_{$this->instanceid}_room_ready";
800
 
801
        switch ($roomstatus) {
802
            case constants::COMMUNICATION_STATUS_PENDING:
803
                \core\notification::add($message, \core\notification::INFO);
804
                unset_user_preference($roomreadypreference);
805
                break;
806
 
807
            case constants::COMMUNICATION_STATUS_READY:
808
                if (empty(get_user_preferences($roomreadypreference))) {
809
                    \core\notification::add($message, \core\notification::SUCCESS);
810
                    set_user_preference($roomreadypreference, true);
811
                }
812
                break;
813
        }
814
    }
815
 
816
    /**
817
     * Add the task to sync the provider data with local Moodle data.
818
     */
819
    public function sync_provider(): void {
820
        // No communication, return.
821
        if (!$this->communication) {
822
            return;
823
        }
824
 
825
        if ($this->communication->get_provider() === processor::PROVIDER_NONE) {
826
            return;
827
        }
828
 
829
        synchronise_provider_task::queue(
830
            $this->communication
831
        );
832
    }
833
}