diff --git a/blocks/microsoft/block_microsoft.php b/blocks/microsoft/block_microsoft.php
index 7789faee9..28f45fd4b 100644
--- a/blocks/microsoft/block_microsoft.php
+++ b/blocks/microsoft/block_microsoft.php
@@ -191,7 +191,11 @@ protected function get_course_content() {
$items[] = html_writer::link(
$url,
$resourcename,
- ['target' => '_blank', 'class' => 'servicelink block_microsoft_' . $feature]
+ [
+ 'target' => '_blank',
+ 'rel' => 'noopener noreferrer',
+ 'class' => 'servicelink block_microsoft_' . $feature,
+ ]
);
}
@@ -342,7 +346,11 @@ protected function get_user_content_connected() {
$spsite = \local_o365\rest\sharepoint::get_tokenresource();
if (!empty($spsite)) {
$spurl = $spsite . '/' . $coursespsite->siteurl;
- $spattrs = ['class' => 'servicelink block_microsoft_sharepoint', 'target' => '_blank'];
+ $spattrs = [
+ 'class' => 'servicelink block_microsoft_sharepoint',
+ 'target' => '_blank',
+ 'rel' => 'noopener noreferrer',
+ ];
$items[] = html_writer::link($spurl, $sharepointstr, $spattrs);
$items[] = '
';
}
@@ -352,7 +360,11 @@ protected function get_user_content_connected() {
// My Delve URL.
if (!empty($delveurl)) {
- $delveattrs = ['class' => 'servicelink block_microsoft_delve', 'target' => '_blank'];
+ $delveattrs = [
+ 'class' => 'servicelink block_microsoft_delve',
+ 'target' => '_blank',
+ 'rel' => 'noopener noreferrer',
+ ];
$delvestr = get_string('linkmydelve', 'block_microsoft');
$items[] = html_writer::link($delveurl, $delvestr, $delveattrs);
}
@@ -360,14 +372,22 @@ protected function get_user_content_connected() {
// My email.
if (!empty($this->globalconfig->settings_showemail)) {
$emailurl = 'https://outlook.office365.com/';
- $emailattrs = ['class' => 'servicelink block_microsoft_outlook', 'target' => '_blank'];
+ $emailattrs = [
+ 'class' => 'servicelink block_microsoft_outlook',
+ 'target' => '_blank',
+ 'rel' => 'noopener noreferrer',
+ ];
$emailstr = get_string('linkemail', 'block_microsoft');
$items[] = html_writer::link($emailurl, $emailstr, $emailattrs);
}
// My Forms URL.
if (!empty($this->globalconfig->settings_showmyforms)) {
- $formsattrs = ['class' => 'servicelink block_microsoft_forms', 'target' => '_blank'];
+ $formsattrs = [
+ 'class' => 'servicelink block_microsoft_forms',
+ 'target' => '_blank',
+ 'rel' => 'noopener noreferrer',
+ ];
$formsstr = get_string('linkmyforms', 'block_microsoft');
$formsurl = get_string('settings_showmyforms_default', 'block_microsoft');
if (!empty($odburl)) {
@@ -382,6 +402,7 @@ protected function get_user_content_connected() {
if (!empty($this->globalconfig->settings_showonedrive)) {
$odbattrs = [
'target' => '_blank',
+ 'rel' => 'noopener noreferrer',
'class' => 'servicelink block_microsoft_onedrive',
];
$stronedrive = get_string('linkonedrive', 'block_microsoft');
@@ -393,14 +414,22 @@ protected function get_user_content_connected() {
// Microsoft Stream (on SharePoint).
if (!empty($this->globalconfig->settings_showmsstreamonsharepoint)) {
$streamurl = 'https://www.microsoft365.com/launch/stream';
- $streamattrs = ['target' => '_blank', 'class' => 'servicelink block_microsoft_msstream'];
+ $streamattrs = [
+ 'target' => '_blank',
+ 'rel' => 'noopener noreferrer',
+ 'class' => 'servicelink block_microsoft_msstream',
+ ];
$items[] = html_writer::link($streamurl, get_string('linkmsstream', 'block_microsoft'), $streamattrs);
}
// Microsoft Stream (Classic).
if (!empty($this->globalconfig->settings_showmsstream)) {
$streamclassicurl = 'https://web.microsoftstream.com/?noSignUpCheck=1';
- $streamclassicattrs = ['target' => '_blank', 'class' => 'servicelink block_microsoft_msstream'];
+ $streamclassicattrs = [
+ 'target' => '_blank',
+ 'rel' => 'noopener noreferrer',
+ 'class' => 'servicelink block_microsoft_msstream',
+ ];
$items[] = html_writer::link(
$streamclassicurl,
get_string('linkmsstreamclassic', 'block_microsoft'),
@@ -411,17 +440,99 @@ protected function get_user_content_connected() {
// Microsoft Teams.
if (!empty($this->globalconfig->settings_showmsteams)) {
$teamsurl = 'https://teams.microsoft.com';
- $teamsattrs = ['target' => '_blank', 'class' => 'servicelink block_microsoft_msteams'];
+ $teamsattrs = [
+ 'target' => '_blank',
+ 'rel' => 'noopener noreferrer',
+ 'class' => 'servicelink block_microsoft_msteams',
+ ];
$items[] = html_writer::link($teamsurl, get_string('linkmsteams', 'block_microsoft'), $teamsattrs);
}
// My Sways.
if (!empty($this->globalconfig->settings_showsways) && !empty($userupn)) {
$swayurl = 'https://www.sway.com/my?auth_pvr=OrgId&auth_upn=' . $userupn;
- $swayattrs = ['target' => '_blank', 'class' => 'servicelink block_microsoft_sway'];
+ $swayattrs = [
+ 'target' => '_blank',
+ 'rel' => 'noopener noreferrer',
+ 'class' => 'servicelink block_microsoft_sway',
+ ];
$items[] = html_writer::link($swayurl, get_string('linksways', 'block_microsoft'), $swayattrs);
}
+ // Additional Microsoft 365 and Viva apps, hidden by default.
+ $microsoft365apps = [
+ 'word' => 'https://www.office.com/launch/word',
+ 'excel' => 'https://www.office.com/launch/excel',
+ 'powerpoint' => 'https://www.office.com/launch/powerpoint',
+ 'vivaengage' => 'https://engage.cloud.microsoft/',
+ 'vivaglint' => 'https://glint.cloud.microsoft/',
+ 'vivagoals' => 'https://goals.microsoft.com',
+ 'vivainsights' => 'https://insights.cloud.microsoft',
+ 'vivapulse' => 'https://pulse.viva.cloud.microsoft/',
+ 'linkedin' => 'https://www.linkedin.com/',
+ ];
+ foreach ($microsoft365apps as $appkey => $appurl) {
+ if (!empty($this->globalconfig->{'settings_show' . $appkey})) {
+ $appattrs = [
+ 'target' => '_blank',
+ 'rel' => 'noopener noreferrer',
+ 'class' => 'servicelink block_microsoft_' . $appkey,
+ ];
+ $items[] = html_writer::link($appurl, get_string('link' . $appkey, 'block_microsoft'), $appattrs);
+ }
+ }
+
+ // Viva Amplify. The URL is tenant-specific and configured by the site administrator.
+ if (!empty($this->globalconfig->settings_showvivaamplify)) {
+ $vivaamplifyurl = $this->globalconfig->settings_vivaamplifyurl ?? '';
+ if (!empty($vivaamplifyurl) && preg_match(BLOCK_MICROSOFT_VIVAAMPLIFY_URL_REGEX, $vivaamplifyurl)) {
+ $vivaamplifyattrs = [
+ 'target' => '_blank',
+ 'rel' => 'noopener noreferrer',
+ 'class' => 'servicelink block_microsoft_vivaamplify',
+ ];
+ $items[] = html_writer::link(
+ $vivaamplifyurl,
+ get_string('linkvivaamplify', 'block_microsoft'),
+ $vivaamplifyattrs
+ );
+ }
+ }
+
+ // Viva Connections. The URL is tenant-specific and configured by the site administrator.
+ if (!empty($this->globalconfig->settings_showvivaconnections)) {
+ $vivaconnectionsurl = $this->globalconfig->settings_vivaconnectionsurl ?? '';
+ if (!empty($vivaconnectionsurl) && preg_match(BLOCK_MICROSOFT_VIVACONNECTIONS_URL_REGEX, $vivaconnectionsurl)) {
+ $vivaconnectionsattrs = [
+ 'target' => '_blank',
+ 'rel' => 'noopener noreferrer',
+ 'class' => 'servicelink block_microsoft_vivaconnections',
+ ];
+ $items[] = html_writer::link(
+ $vivaconnectionsurl,
+ get_string('linkvivaconnections', 'block_microsoft'),
+ $vivaconnectionsattrs
+ );
+ }
+ }
+
+ // Viva Learning. The URL is tenant-specific and configured by the site administrator.
+ if (!empty($this->globalconfig->settings_showvivalearning)) {
+ $vivalearningurl = $this->globalconfig->settings_vivalearningurl ?? '';
+ if (!empty($vivalearningurl) && preg_match(BLOCK_MICROSOFT_VIVALEARNING_URL_REGEX, $vivalearningurl)) {
+ $vivalearningattrs = [
+ 'target' => '_blank',
+ 'rel' => 'noopener noreferrer',
+ 'class' => 'servicelink block_microsoft_vivalearning',
+ ];
+ $items[] = html_writer::link(
+ $vivalearningurl,
+ get_string('linkvivalearning', 'block_microsoft'),
+ $vivalearningattrs
+ );
+ }
+ }
+
// Configure Outlook Sync.
if (!empty($this->globalconfig->settings_showoutlooksync)) {
$outlookurl = new url('/local/o365/ucp.php?action=calendar');
@@ -482,7 +593,11 @@ protected function get_user_content_connected() {
if ($hasaccesstocourserequest && !empty($this->globalconfig->settings_courserequest)) {
$courserequesturl = new url('/local/o365/courserequest.php');
- $courserequestattrs = ['target' => '_blank', 'class' => 'servicelink block_microsoft_courserequest'];
+ $courserequestattrs = [
+ 'target' => '_blank',
+ 'rel' => 'noopener noreferrer',
+ 'class' => 'servicelink block_microsoft_courserequest',
+ ];
$courserequeststr = get_string('linkcourserequest', 'block_microsoft');
$items[] = html_writer::link($courserequesturl, $courserequeststr, $courserequestattrs);
}
@@ -542,7 +657,11 @@ protected function get_content_o365download() {
html_writer::link(
$url,
$str,
- ['class' => 'servicelink block_microsoft_downloado365', 'target' => '_blank']
+ [
+ 'class' => 'servicelink block_microsoft_downloado365',
+ 'target' => '_blank',
+ 'rel' => 'noopener noreferrer',
+ ]
),
];
}
diff --git a/blocks/microsoft/classes/admin_setting_required_url.php b/blocks/microsoft/classes/admin_setting_required_url.php
new file mode 100644
index 000000000..3b018758f
--- /dev/null
+++ b/blocks/microsoft/classes/admin_setting_required_url.php
@@ -0,0 +1,81 @@
+.
+
+/**
+ * Admin setting for a URL that becomes mandatory once a companion checkbox setting is enabled.
+ *
+ * @package block_microsoft
+ * @author Lai Wei
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @copyright (C) 2026 onwards Microsoft, Inc. (http://microsoft.com/)
+ */
+
+/**
+ * Admin setting for a URL that becomes mandatory once a companion checkbox setting is enabled.
+ *
+ * This must only be required (directly or indirectly) from settings.php, since admin_setting_configtext
+ * is only guaranteed to be loaded in the admin settings context.
+ */
+class block_microsoft_admin_setting_required_url extends admin_setting_configtext {
+ /** @var admin_setting_configcheckbox The checkbox setting that makes this URL mandatory when checked. */
+ protected $requiredifsetting;
+
+ /**
+ * Constructor.
+ *
+ * @param string $name Setting name, in the 'component/settingname' format.
+ * @param string $visiblename Localised setting name.
+ * @param string $description Localised setting description.
+ * @param string $defaultsetting Default value.
+ * @param string $paramtype PARAM_XXX type, or a '/regex/' string.
+ * @param admin_setting_configcheckbox $requiredifsetting The checkbox setting that makes this URL mandatory
+ * when checked.
+ */
+ public function __construct(
+ $name,
+ $visiblename,
+ $description,
+ $defaultsetting,
+ $paramtype,
+ admin_setting_configcheckbox $requiredifsetting
+ ) {
+ parent::__construct($name, $visiblename, $description, $defaultsetting, $paramtype);
+ $this->requiredifsetting = $requiredifsetting;
+ }
+
+ /**
+ * Validate the submitted URL, also requiring a non-empty value when the companion checkbox is checked.
+ *
+ * @param string $data
+ * @return string|true True if valid, otherwise an error message.
+ */
+ public function validate($data) {
+ $parentvalidation = parent::validate($data);
+ if ($parentvalidation !== true) {
+ return $parentvalidation;
+ }
+
+ $checkboxname = $this->requiredifsetting->get_full_name();
+ $checkboxvalue = optional_param($checkboxname, $this->requiredifsetting->no, PARAM_RAW);
+ $ischecked = ((string) $checkboxvalue === (string) $this->requiredifsetting->yes);
+
+ if ($ischecked && trim((string) $data) === '') {
+ return get_string('error_urlrequiredwhenenabled', 'block_microsoft');
+ }
+
+ return true;
+ }
+}
diff --git a/blocks/microsoft/lang/en/block_microsoft.php b/blocks/microsoft/lang/en/block_microsoft.php
index 18f27e76f..9a0e0e94f 100644
--- a/blocks/microsoft/lang/en/block_microsoft.php
+++ b/blocks/microsoft/lang/en/block_microsoft.php
@@ -30,6 +30,7 @@
$string['pluginname'] = 'Microsoft block';
$string['contactadmin'] = 'Contact administrator for more information.';
$string['error_nomoodlenotebook'] = 'Could not find your Moodle notebook.';
+$string['error_urlrequiredwhenenabled'] = 'This URL must be configured, since the "Show" option above is enabled.';
$string['linkonedrive'] = 'My OneDrive';
$string['linkonenote'] = 'My OneNote Notebook';
$string['linksways'] = 'My Sways';
@@ -64,6 +65,20 @@
$string['connecttoo365'] = 'Connect to Microsoft 365';
$string['install_office'] = 'Install Office';
+// Microsoft 365 and Viva apps.
+$string['linkword'] = 'Word';
+$string['linkexcel'] = 'Excel';
+$string['linkpowerpoint'] = 'PowerPoint';
+$string['linkvivaengage'] = 'Viva Engage';
+$string['linkvivaamplify'] = 'Viva Amplify';
+$string['linkvivaconnections'] = 'Viva Connections';
+$string['linkvivaglint'] = 'Viva Glint';
+$string['linkvivagoals'] = 'Viva Goals';
+$string['linkvivainsights'] = 'Viva Insights';
+$string['linkvivalearning'] = 'Viva Learning';
+$string['linkvivapulse'] = 'Viva Pulse';
+$string['linklinkedin'] = 'Microsoft LinkedIn';
+
// Configuration settings.
$string['settings_showemail'] = 'Show "My Email"';
$string['settings_showemail_desc'] = 'Enable or disable the "My Email" link in the block.';
@@ -102,6 +117,36 @@
$string['settings_geto365link'] = 'Install Office download URL';
$string['settings_geto365link_desc'] = 'The URL to use for the "Install Office" link.';
$string['settings_geto365link_default'] = 'https://portal.office.com/OLS/MySoftware.aspx';
+$string['settings_showword'] = 'Show "Word"';
+$string['settings_showword_desc'] = 'Enable or disable the "Word" link in the block.';
+$string['settings_showexcel'] = 'Show "Excel"';
+$string['settings_showexcel_desc'] = 'Enable or disable the "Excel" link in the block.';
+$string['settings_showpowerpoint'] = 'Show "PowerPoint"';
+$string['settings_showpowerpoint_desc'] = 'Enable or disable the "PowerPoint" link in the block.';
+$string['settings_showvivaengage'] = 'Show "Viva Engage"';
+$string['settings_showvivaengage_desc'] = 'Enable or disable the "Viva Engage" link in the block.';
+$string['settings_showvivaamplify'] = 'Show "Viva Amplify"';
+$string['settings_showvivaamplify_desc'] = 'Enable or disable the "Viva Amplify" link in the block.
Note: The Viva Amplify URL below must also be configured for the link to be shown.';
+$string['settings_vivaamplifyurl'] = 'Viva Amplify URL';
+$string['settings_vivaamplifyurl_desc'] = 'The URL of your organization\'s Viva Amplify experience, as configured by your Microsoft 365 tenant administrator, e.g. https://amplify.microsoft.com/. Only URLs on an amplify.microsoft.com or amplify.cloud.microsoft domain are accepted.';
+$string['settings_showvivaconnections'] = 'Show "Viva Connections"';
+$string['settings_showvivaconnections_desc'] = 'Enable or disable the "Viva Connections" link in the block.
Note: The Viva Connections URL below must also be configured for the link to be shown.';
+$string['settings_vivaconnectionsurl'] = 'Viva Connections URL';
+$string['settings_vivaconnectionsurl_desc'] = 'The URL of your organization\'s Viva Connections experience, as configured by your Microsoft 365 tenant administrator. This is typically your SharePoint home site, e.g. https://yourtenant.sharepoint.com/sites/yourhomesite. Only URLs on a *.sharepoint.com (or sovereign cloud equivalent) domain are accepted.';
+$string['settings_showvivaglint'] = 'Show "Viva Glint"';
+$string['settings_showvivaglint_desc'] = 'Enable or disable the "Viva Glint" link in the block.';
+$string['settings_showvivagoals'] = 'Show "Viva Goals"';
+$string['settings_showvivagoals_desc'] = 'Enable or disable the "Viva Goals" link in the block.';
+$string['settings_showvivainsights'] = 'Show "Viva Insights"';
+$string['settings_showvivainsights_desc'] = 'Enable or disable the "Viva Insights" link in the block.';
+$string['settings_showvivalearning'] = 'Show "Viva Learning"';
+$string['settings_showvivalearning_desc'] = 'Enable or disable the "Viva Learning" link in the block.
Note: The Viva Learning URL below must also be configured for the link to be shown.';
+$string['settings_vivalearningurl'] = 'Viva Learning URL';
+$string['settings_vivalearningurl_desc'] = 'The URL of your organization\'s Viva Learning experience, as configured by your Microsoft 365 tenant administrator, e.g. https://web.viva.microsoft.com/learning. Only URLs on a viva.microsoft.com or cloud.microsoft domain are accepted.';
+$string['settings_showvivapulse'] = 'Show "Viva Pulse"';
+$string['settings_showvivapulse_desc'] = 'Enable or disable the "Viva Pulse" link in the block.';
+$string['settings_showlinkedin'] = 'Show "Microsoft LinkedIn"';
+$string['settings_showlinkedin_desc'] = 'Enable or disable the "Microsoft LinkedIn" link in the block.';
$string['linkmydelve'] = 'My Delve';
$string['linkmyforms'] = 'My Forms';
diff --git a/blocks/microsoft/lib.php b/blocks/microsoft/lib.php
index 38e7dc773..f479dbcd4 100644
--- a/blocks/microsoft/lib.php
+++ b/blocks/microsoft/lib.php
@@ -29,6 +29,30 @@
require_once($CFG->dirroot . '/local/o365/lib.php');
+// Regex used to validate the tenant-configured Viva Connections URL (typically the tenant's SharePoint home site).
+// An empty value is also accepted, since the admin setting form is validated even while the link is disabled.
+// Note: admin_setting_configtext only recognises a custom regex paramtype when it is delimited with literal
+// forward slashes and has no trailing modifiers (see admin_setting::validate() in lib/adminlib.php), so the
+// domain part is matched case-sensitively; URLs should be entered in lowercase.
+define(
+ 'BLOCK_MICROSOFT_VIVACONNECTIONS_URL_REGEX',
+ '/^$|^https:\/\/([a-zA-Z0-9-]+\.)*sharepoint\.(com|us|de|cn)(\/.*)?$/'
+);
+
+// Regex used to validate the tenant-configured Viva Learning URL.
+// An empty value is also accepted, since the admin setting form is validated even while the link is disabled.
+define(
+ 'BLOCK_MICROSOFT_VIVALEARNING_URL_REGEX',
+ '/^$|^https:\/\/([a-zA-Z0-9-]+\.)*(viva\.microsoft\.com|cloud\.microsoft)(\/.*)?$/'
+);
+
+// Regex used to validate the tenant-configured Viva Amplify URL.
+// An empty value is also accepted, since the admin setting form is validated even while the link is disabled.
+define(
+ 'BLOCK_MICROSOFT_VIVAAMPLIFY_URL_REGEX',
+ '/^$|^https:\/\/([a-zA-Z0-9-]+\.)*(amplify\.microsoft\.com|amplify\.cloud\.microsoft)(\/.*)?$/'
+);
+
/**
* Return the course sync option of the course with the given ID.
*
diff --git a/blocks/microsoft/pix/excel.svg b/blocks/microsoft/pix/excel.svg
new file mode 100644
index 000000000..bc72c8687
--- /dev/null
+++ b/blocks/microsoft/pix/excel.svg
@@ -0,0 +1,56 @@
+
diff --git a/blocks/microsoft/pix/linkedin.svg b/blocks/microsoft/pix/linkedin.svg
new file mode 100644
index 000000000..46087a0fa
--- /dev/null
+++ b/blocks/microsoft/pix/linkedin.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/blocks/microsoft/pix/powerpoint.svg b/blocks/microsoft/pix/powerpoint.svg
new file mode 100644
index 000000000..cbcdd7ea6
--- /dev/null
+++ b/blocks/microsoft/pix/powerpoint.svg
@@ -0,0 +1,57 @@
+
diff --git a/blocks/microsoft/pix/vivaamplify.svg b/blocks/microsoft/pix/vivaamplify.svg
new file mode 100644
index 000000000..ffa111453
--- /dev/null
+++ b/blocks/microsoft/pix/vivaamplify.svg
@@ -0,0 +1,5 @@
+
diff --git a/blocks/microsoft/pix/vivaconnections.svg b/blocks/microsoft/pix/vivaconnections.svg
new file mode 100644
index 000000000..779d8d90f
--- /dev/null
+++ b/blocks/microsoft/pix/vivaconnections.svg
@@ -0,0 +1,14 @@
+
\ No newline at end of file
diff --git a/blocks/microsoft/pix/vivaengage.svg b/blocks/microsoft/pix/vivaengage.svg
new file mode 100644
index 000000000..8307626eb
--- /dev/null
+++ b/blocks/microsoft/pix/vivaengage.svg
@@ -0,0 +1,7 @@
+
diff --git a/blocks/microsoft/pix/vivaglint.svg b/blocks/microsoft/pix/vivaglint.svg
new file mode 100644
index 000000000..9aa114e5e
--- /dev/null
+++ b/blocks/microsoft/pix/vivaglint.svg
@@ -0,0 +1,25 @@
+
diff --git a/blocks/microsoft/pix/vivagoals.svg b/blocks/microsoft/pix/vivagoals.svg
new file mode 100644
index 000000000..4a6a097e2
--- /dev/null
+++ b/blocks/microsoft/pix/vivagoals.svg
@@ -0,0 +1,62 @@
+
diff --git a/blocks/microsoft/pix/vivainsights.svg b/blocks/microsoft/pix/vivainsights.svg
new file mode 100644
index 000000000..1d7189def
--- /dev/null
+++ b/blocks/microsoft/pix/vivainsights.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/blocks/microsoft/pix/vivalearning.svg b/blocks/microsoft/pix/vivalearning.svg
new file mode 100644
index 000000000..866d15464
--- /dev/null
+++ b/blocks/microsoft/pix/vivalearning.svg
@@ -0,0 +1,29 @@
+
diff --git a/blocks/microsoft/pix/vivapulse.svg b/blocks/microsoft/pix/vivapulse.svg
new file mode 100644
index 000000000..64a5d428a
--- /dev/null
+++ b/blocks/microsoft/pix/vivapulse.svg
@@ -0,0 +1,22 @@
+
diff --git a/blocks/microsoft/pix/word.svg b/blocks/microsoft/pix/word.svg
new file mode 100644
index 000000000..31c367787
--- /dev/null
+++ b/blocks/microsoft/pix/word.svg
@@ -0,0 +1,73 @@
+
diff --git a/blocks/microsoft/settings.php b/blocks/microsoft/settings.php
index db42d7efb..904403c4a 100644
--- a/blocks/microsoft/settings.php
+++ b/blocks/microsoft/settings.php
@@ -25,6 +25,9 @@
defined('MOODLE_INTERNAL') || die;
+require_once($CFG->dirroot . '/blocks/microsoft/lib.php');
+require_once($CFG->dirroot . '/blocks/microsoft/classes/admin_setting_required_url.php');
+
// Settings to show My Delve link in block.
$label = get_string('settings_showmydelve', 'block_microsoft');
$desc = get_string('settings_showmydelve_desc', 'block_microsoft');
@@ -110,3 +113,83 @@
$label = new lang_string('settings_courserequest', 'block_microsoft');
$desc = new lang_string('settings_courserequest_desc', 'block_microsoft');
$settings->add(new \admin_setting_configcheckbox('block_microsoft/settings_courserequest', $label, $desc, 1));
+
+// Settings to show additional Microsoft 365 and Viva app links in the block. Hidden by default.
+$microsoft365apps = [
+ 'word', 'excel', 'powerpoint', 'vivaengage',
+ 'vivaglint', 'vivagoals', 'vivainsights', 'vivapulse', 'linkedin',
+];
+foreach ($microsoft365apps as $microsoft365app) {
+ $label = new lang_string('settings_show' . $microsoft365app, 'block_microsoft');
+ $desc = new lang_string('settings_show' . $microsoft365app . '_desc', 'block_microsoft');
+ $settings->add(new admin_setting_configcheckbox('block_microsoft/settings_show' . $microsoft365app, $label, $desc, 0));
+}
+
+// Settings to show Viva Amplify link in the block.
+// The link URL is tenant-specific and must be configured by the site administrator below.
+$label = new lang_string('settings_showvivaamplify', 'block_microsoft');
+$desc = new lang_string('settings_showvivaamplify_desc', 'block_microsoft');
+$vivaamplifycheckbox = new admin_setting_configcheckbox('block_microsoft/settings_showvivaamplify', $label, $desc, 0);
+$settings->add($vivaamplifycheckbox);
+
+$label = new lang_string('settings_vivaamplifyurl', 'block_microsoft');
+$desc = new lang_string('settings_vivaamplifyurl_desc', 'block_microsoft');
+$settings->add(new block_microsoft_admin_setting_required_url(
+ 'block_microsoft/settings_vivaamplifyurl',
+ $label,
+ $desc,
+ '',
+ BLOCK_MICROSOFT_VIVAAMPLIFY_URL_REGEX,
+ $vivaamplifycheckbox
+));
+$settings->hide_if(
+ 'block_microsoft/settings_vivaamplifyurl',
+ 'block_microsoft/settings_showvivaamplify',
+ 'notchecked'
+);
+
+// Settings to show Viva Connections link in the block.
+// The link URL is tenant-specific and must be configured by the site administrator below.
+$label = new lang_string('settings_showvivaconnections', 'block_microsoft');
+$desc = new lang_string('settings_showvivaconnections_desc', 'block_microsoft');
+$vivaconnectionscheckbox = new admin_setting_configcheckbox('block_microsoft/settings_showvivaconnections', $label, $desc, 0);
+$settings->add($vivaconnectionscheckbox);
+
+$label = new lang_string('settings_vivaconnectionsurl', 'block_microsoft');
+$desc = new lang_string('settings_vivaconnectionsurl_desc', 'block_microsoft');
+$settings->add(new block_microsoft_admin_setting_required_url(
+ 'block_microsoft/settings_vivaconnectionsurl',
+ $label,
+ $desc,
+ '',
+ BLOCK_MICROSOFT_VIVACONNECTIONS_URL_REGEX,
+ $vivaconnectionscheckbox
+));
+$settings->hide_if(
+ 'block_microsoft/settings_vivaconnectionsurl',
+ 'block_microsoft/settings_showvivaconnections',
+ 'notchecked'
+);
+
+// Settings to show Viva Learning link in the block.
+// The link URL is tenant-specific and must be configured by the site administrator below.
+$label = new lang_string('settings_showvivalearning', 'block_microsoft');
+$desc = new lang_string('settings_showvivalearning_desc', 'block_microsoft');
+$vivalearningcheckbox = new admin_setting_configcheckbox('block_microsoft/settings_showvivalearning', $label, $desc, 0);
+$settings->add($vivalearningcheckbox);
+
+$label = new lang_string('settings_vivalearningurl', 'block_microsoft');
+$desc = new lang_string('settings_vivalearningurl_desc', 'block_microsoft');
+$settings->add(new block_microsoft_admin_setting_required_url(
+ 'block_microsoft/settings_vivalearningurl',
+ $label,
+ $desc,
+ '',
+ BLOCK_MICROSOFT_VIVALEARNING_URL_REGEX,
+ $vivalearningcheckbox
+));
+$settings->hide_if(
+ 'block_microsoft/settings_vivalearningurl',
+ 'block_microsoft/settings_showvivalearning',
+ 'notchecked'
+);
diff --git a/blocks/microsoft/styles.css b/blocks/microsoft/styles.css
index f9c2d90ab..4d0214a7d 100644
--- a/blocks/microsoft/styles.css
+++ b/blocks/microsoft/styles.css
@@ -105,6 +105,54 @@
background-image: url([[pix:block_microsoft|courserequest]]);
}
+.block_microsoft .block_microsoft_word {
+ background-image: url([[pix:block_microsoft|word]]);
+}
+
+.block_microsoft .block_microsoft_excel {
+ background-image: url([[pix:block_microsoft|excel]]);
+}
+
+.block_microsoft .block_microsoft_powerpoint {
+ background-image: url([[pix:block_microsoft|powerpoint]]);
+}
+
+.block_microsoft .block_microsoft_vivaengage {
+ background-image: url([[pix:block_microsoft|vivaengage]]);
+}
+
+.block_microsoft .block_microsoft_vivaamplify {
+ background-image: url([[pix:block_microsoft|vivaamplify]]);
+}
+
+.block_microsoft .block_microsoft_vivaconnections {
+ background-image: url([[pix:block_microsoft|vivaconnections]]);
+}
+
+.block_microsoft .block_microsoft_vivaglint {
+ background-image: url([[pix:block_microsoft|vivaglint]]);
+}
+
+.block_microsoft .block_microsoft_vivagoals {
+ background-image: url([[pix:block_microsoft|vivagoals]]);
+}
+
+.block_microsoft .block_microsoft_vivainsights {
+ background-image: url([[pix:block_microsoft|vivainsights]]);
+}
+
+.block_microsoft .block_microsoft_vivalearning {
+ background-image: url([[pix:block_microsoft|vivalearning]]);
+}
+
+.block_microsoft .block_microsoft_vivapulse {
+ background-image: url([[pix:block_microsoft|vivapulse]]);
+}
+
+.block_microsoft .block_microsoft_linkedin {
+ background-image: url([[pix:block_microsoft|linkedin]]);
+}
+
.block_microsoft hr {
margin: 1rem 0;
}
diff --git a/blocks/microsoft/version.php b/blocks/microsoft/version.php
index 1fbc5c882..076a1ad9f 100644
--- a/blocks/microsoft/version.php
+++ b/blocks/microsoft/version.php
@@ -25,7 +25,7 @@
defined('MOODLE_INTERNAL') || die();
-$plugin->version = 2026042000;
+$plugin->version = 2026042000.01;
$plugin->requires = 2026042000;
$plugin->release = '5.2.0';
$plugin->component = 'block_microsoft';