From d8790055046bda33923b8e0d585599d32d7fb1d8 Mon Sep 17 00:00:00 2001 From: Stefan-Alexander Scholz Date: Thu, 18 Jun 2026 21:33:37 +0000 Subject: [PATCH] DASH-1272 Allow registered data sources to gate picker visibility by context MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a generic, opt-in visibility hook to the data-source registry so a registering plugin can hide one of its data sources from the block builder picker based on the editing context, without block_dash knowing anything about that plugin's rules. - data_source_factory::is_visible_in_context($identifier, $context): if the registry entry carries a 'visible' => callable($identifier, $context): bool, it is consulted; entries without one stay visible (no behaviour change for existing data sources). - edit_form::dash_features_list(): the datasource and widget picker loops now also honour is_visible_in_context(), so a gated entry is omitted for users the callback rejects. Authoring-time only — build_data_source()/render are untouched, so already configured blocks keep rendering. First consumer is dashaddon_repository's per-preset "block builder" role audience. --- .../local/data_source/data_source_factory.php | 21 +++++++++++++++++++ edit_form.php | 4 ++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/classes/local/data_source/data_source_factory.php b/classes/local/data_source/data_source_factory.php index 3f7e809..8f38169 100644 --- a/classes/local/data_source/data_source_factory.php +++ b/classes/local/data_source/data_source_factory.php @@ -143,6 +143,27 @@ public static function build_data_source($identifier, \context $context) { return new $identifier($context); } + /** + * Whether a registered data source should be offered to the current user in + * the given context. + * + * A registering plugin may attach a `'visible' => callable($identifier, + * $context): bool` entry to its registry record to gate the data source by + * context/role at authoring time (e.g. dashaddon_repository's per-preset + * block-builder audience). Entries without a callback are always visible. + * + * @param string $identifier + * @param \context $context + * @return bool + */ + public static function is_visible_in_context($identifier, \context $context) { + $info = self::get_data_source_info($identifier); + if ($info && isset($info['visible']) && is_callable($info['visible'])) { + return (bool) call_user_func($info['visible'], $identifier, $context); + } + return true; + } + /** * Get options array for select form fields. * diff --git a/edit_form.php b/edit_form.php index fc4c60b..1aff17c 100644 --- a/edit_form.php +++ b/edit_form.php @@ -432,7 +432,7 @@ public static function dash_features_list(&$mform, $context, $page) { $group[] = $mform->createElement('html', html_writer::start_div('datasource-content')); foreach ($datasources as $id => $source) { - if (block_dash_visible_addons($id)) { + if (block_dash_visible_addons($id) && data_source_factory::is_visible_in_context($id, $context)) { $group[] = $mform->createElement('html', html_writer::start_div('datasource-item')); $group[] = $mform->createElement('radio', 'config_data_source_idnumber', '', $source['name'], $id); if ($help = $source['help']) { @@ -457,7 +457,7 @@ public static function dash_features_list(&$mform, $context, $page) { ); $widgets[] = $mform->createElement('html', html_writer::start_div('datasource-content')); foreach ($widgetlist as $id => $source) { - if (block_dash_visible_addons($id)) { + if (block_dash_visible_addons($id) && data_source_factory::is_visible_in_context($id, $context)) { $widgets[] = $mform->createElement('html', html_writer::start_div('datasource-item')); $widgets[] = $mform->createElement('radio', 'config_data_source_idnumber', '', $source['name'], $id); if ($source['help']) {