diff --git a/classes/auto_provisioner.php b/classes/auto_provisioner.php new file mode 100644 index 0000000..574752f --- /dev/null +++ b/classes/auto_provisioner.php @@ -0,0 +1,48 @@ +. + +/** + * Auto-provisioning service. + * + * @package tool_webanalytics + * @author Simon Adams (simon.adams@catalyst-eu.net) + * @copyright 2023 Catalyst IT + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace tool_webanalytics; + +use tool_webanalytics\plugininfo\watool; + +class auto_provisioner { + + /** + * Get all plugin types that support provisioning and are ready to provision. Then attempt an auto-provision. + * + * @return void + */ + public static function auto_provision(): void { + $autoprovisionable = plugin_manager::instance()->get_auto_provision_type_plugins(); + + /** @var watool $tool */ + foreach ($autoprovisionable as $tool) { + $class = $tool->get_tool_classname(); + if ($class::can_auto_provision()) { + $class::auto_provision(); + } + } + } +} diff --git a/classes/form/edit.php b/classes/form/edit.php index 3b2f4bc..291490f 100644 --- a/classes/form/edit.php +++ b/classes/form/edit.php @@ -27,6 +27,7 @@ use moodleform; use tool_webanalytics\plugin_manager; +use tool_webanalytics\record; defined('MOODLE_INTERNAL') || die(); @@ -138,10 +139,16 @@ public function validation($data, $files) { * @return object submitted data; NULL if not valid or not submitted or cancelled */ public function get_data() { + global $CFG; + $data = parent::get_data(); if (!empty($data)) { $data->settings = $this->tool->form_build_settings($data); + if ($siteid = $this->tool->register_site(new record($data))) { + $data->settings['siteid'] = $siteid; + $data->settings['wwwroot'] = $CFG->wwwroot; + } } return $data; diff --git a/classes/injector.php b/classes/injector.php index df45860..8172db4 100644 --- a/classes/injector.php +++ b/classes/injector.php @@ -26,6 +26,8 @@ namespace tool_webanalytics; +use tool_webanalytics\tool\tool_interface; + defined('MOODLE_INTERNAL') || die; /** @@ -68,6 +70,8 @@ public static function render_tracking_code(): string { } } + auto_provisioner::auto_provision(); + return $result; } diff --git a/classes/plugin_manager.php b/classes/plugin_manager.php index 53827ee..dbca53b 100644 --- a/classes/plugin_manager.php +++ b/classes/plugin_manager.php @@ -141,4 +141,23 @@ protected function build_plugins(): array { return $plugins; } + /** + * Get all sub-plugins that support auto provisioning. + * + * @return \core\plugininfo\base[] + */ + public function get_auto_provision_type_plugins(): array { + return array_filter($this->build_plugins(), static function($plugin) { + $classes = \core_component::get_component_classes_in_namespace('watool_' . $plugin->name, 'tool'); + if (!$class = array_key_first($classes)) { + return false; + } + $method = 'supports_auto_provision'; + if (!method_exists($class, $method)) { + return false; + } + return $class::$method(); + } + ); + } } diff --git a/classes/plugininfo/watool.php b/classes/plugininfo/watool.php index 490820c..fbe0e57 100644 --- a/classes/plugininfo/watool.php +++ b/classes/plugininfo/watool.php @@ -52,4 +52,51 @@ public function get_tool_instance(record_interface $record): tool_interface { return new $class($record); } + /** + * Gt the classname of the tool to aid in calling methods dynamically. + * + * @return string + */ + public function get_tool_classname() { + return '\\watool_' . $this->name . '\\tool\\tool'; + } + + /** + * Load tool specific settings. + * + * @param \part_of_admin_tree $adminroot + * @param $parentnodename + * @param $hassiteconfig + * @return void + */ + public function load_settings(\part_of_admin_tree $adminroot, $parentnodename, $hassiteconfig) { + global $CFG, $USER, $DB, $OUTPUT, $PAGE; // In case settings.php wants to refer to them. + $ADMIN = $adminroot; // May be used in settings.php. + $plugininfo = $this; // Also can be used inside settings.php. + + if (!$this->is_installed_and_upgraded()) { + return; + } + + if (!$hassiteconfig || !file_exists($this->full_path('settings.php'))) { + return; + } + + $section = $this->get_settings_section_name(); + $settings = new \admin_settingpage($section, $this->displayname, 'moodle/site:config', $this->is_enabled() === false); + include($this->full_path('settings.php')); // This may also set $settings to null. + + if ($settings) { + $ADMIN->add($parentnodename, $settings); + } + } + + /** + * Get the tool specific section name for our settings page. + * + * @return string + */ + public function get_settings_section_name() { + return 'watool_' . $this->name; + } } diff --git a/classes/record.php b/classes/record.php index 4368cf6..40bb025 100644 --- a/classes/record.php +++ b/classes/record.php @@ -128,6 +128,20 @@ public function get_property($name) { return $this->$name; } + /** + * Set the property value. + * + * @param $name + * @param $value + * @return void + */ + public function set_property($name, $value): void { + if (!property_exists($this, $name)) { + throw new coding_exception('Property does not exist.', $name); + } + + $this->$name = $value; + } /** * Export record for inserting/updating it in DB. diff --git a/classes/record_interface.php b/classes/record_interface.php index 0c15480..bca2253 100644 --- a/classes/record_interface.php +++ b/classes/record_interface.php @@ -50,6 +50,13 @@ public function is_enabled(): bool; */ public function get_property($name); + /** + * Set the property value. + * + * @param string $name Property name. + */ + public function set_property($name, $value); + /** * Export the record. * diff --git a/classes/tool/tool_base.php b/classes/tool/tool_base.php index acbcf5d..0fa1ba5 100644 --- a/classes/tool/tool_base.php +++ b/classes/tool/tool_base.php @@ -25,6 +25,8 @@ namespace tool_webanalytics\tool; +use stdClass; +use tool_webanalytics\record; use tool_webanalytics\record_interface; defined('MOODLE_INTERNAL') || die(); @@ -144,4 +146,38 @@ public function trackurl($urlencode = false, $leadingslash = false): string { return $trackurl; } + /** + * Called from the config instance form submission. + * + * @param record $record data from the form submission. + * @return int $siteid returned from the API. + */ + public function register_site(record $record): int { + return 0; + } + + /** + * Does the tool support auto provision over an API? + * + * @return bool + */ + public static function supports_auto_provision(): bool { + return false; + } + + /** + * Is the tool ready to attempt an auto provision? + * + * @return bool + */ + public static function can_auto_provision(): bool { + return false; + } + + /** + * Auto provision the site with the API. + * + * @return void + */ + public static function auto_provision(): void {} } diff --git a/classes/tool/tool_interface.php b/classes/tool/tool_interface.php index b22662b..36b244a 100644 --- a/classes/tool/tool_interface.php +++ b/classes/tool/tool_interface.php @@ -25,6 +25,7 @@ namespace tool_webanalytics\tool; +use tool_webanalytics\record; use tool_webanalytics\record_interface; defined('MOODLE_INTERNAL') || die(); @@ -103,4 +104,35 @@ public function form_build_settings(\stdClass $data): array; * @return void */ public function form_set_data(\stdClass &$data); + + /** + * Register the instance with an external API. + * Called from the config instance form submission. + * Return 0 as the siteid if the tool does not support it. + * + * @param record $record data from the form submission. + * @return int $siteid returned from the API. + */ + public function register_site(record $record): int; + + /** + * Does the tool support auto provision over an API? + * + * @return bool + */ + public static function supports_auto_provision(): bool; + + /** + * Is the tool ready to attempt an auto provision? + * + * @return bool + */ + public static function can_auto_provision(): bool; + + /** + * Auto provision the site with the API. + * + * @return void + */ + public static function auto_provision(): void; } diff --git a/settings.php b/settings.php index 8915f08..122a2e3 100644 --- a/settings.php +++ b/settings.php @@ -26,11 +26,23 @@ defined('MOODLE_INTERNAL') || die; if (is_siteadmin()) { + $category = new admin_category( + 'tool_webanalytics', + new lang_string('pluginname', 'tool_webanalytics'), + false + ); + $ADMIN->add('tools', $category); + $externalpage = new admin_externalpage( - 'tool_webanalytics_manage', - get_string('pluginname', 'tool_webanalytics'), - new moodle_url('/admin/tool/webanalytics/manage.php') + 'tool_webanalytics_manage', + get_string('pluginname', 'tool_webanalytics'), + new moodle_url('/admin/tool/webanalytics/manage.php') ); + $ADMIN->add('tool_webanalytics', $externalpage); + + foreach (core_plugin_manager::instance()->get_plugins_of_type('watool') as $plugin) { + /** @var \tool_webanalytics\plugin_manager $plugin */ + $plugin->load_settings($ADMIN, 'tool_webanalytics', $hassiteconfig); + } - $ADMIN->add('tools', $externalpage); } diff --git a/tool/matomo/README.md b/tool/matomo/README.md new file mode 100644 index 0000000..3831083 --- /dev/null +++ b/tool/matomo/README.md @@ -0,0 +1,22 @@ +# Matomo (formerly Piwik) +- Set the Site ID +- Choose whether you want image fallback tracking +- Enter the URL to your Matomo install excluding http/https and trailing slashes +- Choose whether you want to track admins (not recommended) +- Choose whether you want to send Clean URLs (recommended): Matomo will aggregate Page Titles and show a nice waterfall cascade of all sites, +- Set alternative piwik.js URL for any purpose +including categories and action types +- Optional tracking for User ID +- User ID could be id or username +- Set the API url +- Set the API token + +If both the API url and API token are set in the form and the siteid is empty when the form is submitted, an attempt to register the site with the API will be made. + + +# Auto-provisioning +- Set the global config settings 'apitoken' and 'apiurl' to enable auto provisioning. These can also be set in config.php e.g: + - `$CFG->forced_plugin_settings['watool_matomo']['apiurl'] = 'https://matomo.org';` + - `$CFG->forced_plugin_settings['watool_matomo']['apitoken'] = 'xxxx';` +- Auto provisioning attempts are made if the current site url has changed since any of the instances were stored. +- If autoprovisioning failed, the instance will be set with the name 'auto-provisioned:FAILED'. Delete the instance to attempt an autoprovision again. diff --git a/tool/matomo/classes/client.php b/tool/matomo/classes/client.php new file mode 100644 index 0000000..b2c47de --- /dev/null +++ b/tool/matomo/classes/client.php @@ -0,0 +1,212 @@ +. +/** + * Webanalytics class to wrap HTTP requests. + * + * @package watool_matomo + * @copyright 2023 onwards Catalyst IT EU {@link https://catalyst-eu.net} + * @author Simon Adams simon.adams@catalyst-eu.net + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace watool_matomo; + +use core_date; +use curl; +use Exception; +use moodle_url; +use stdClass; +use Throwable; + +/** + * Wrap Http client. + */ +class client extends curl { + + /** @var moodle_url */ + private $url; + + /** @var string */ + private $token; + + /** + * Constructor. + * + * @param string $url + * @param string $token + * @param array $settings + */ + public function __construct(string $url, string $token, array $settings = []) { + $this->url = new moodle_url($url); + $this->token = $token; + + parent::__construct($settings); + } + + /** + * Build boilerplate request options. + * + * @return array + */ + private function build_request(): array { + return [ + 'module' => 'API', + 'method' => '', + 'format' => 'JSON', + 'token_auth' => $this->token + ]; + } + + /** + * Get the site id by url of any site registered on Matomo. + * + * @param string $url + * @return int 0 Means it doesn't exist. + */ + public function get_siteid_from_url(string $url = ''): int { + global $CFG; + + $request = $this->build_request(); + $request['method'] = 'SitesManager.getSitesIdFromSiteUrl'; + $request['url'] = !empty($url) ? $url : $CFG->wwwroot; + $rawresponsebody = $this->post($this->url, $request); + $response = $this->validate_response_body($rawresponsebody, $request); + $response = is_array($response) ? reset($response) : new stdClass(); + + return !empty($response->idsite) ? $response->idsite : 0; + } + + /** + * Get all registered urls for this siteid. + * + * @param int $siteid + * @return array + */ + public function get_urls_from_siteid(int $siteid): array { + $request = $this->build_request(); + $request['method'] = 'SitesManager.getSiteUrlsFromId'; + $request['idSite'] = $siteid; + $rawresponsebody = $this->post($this->url, $request); + $response = $this->validate_response_body($rawresponsebody, $request); + return is_array($response) ? $response : []; + } + + /** + * Create a site at Matomo instance. + * + * @param string $sitename + * @param string[] $urls + * @param string $timezone + * @param string $currency + * @return int Site id on success, or 0 on failure. + * @throws Exception + */ + public function add_site(string $sitename = '', array $urls = [], string $timezone = '', string $currency = ''): int { + global $SITE; + + $request = $this->build_request(); + $request['method'] = 'SitesManager.addSite'; + $request['siteName'] = !empty($sitename) ? $sitename : $SITE->fullname; + $request['timezone'] = !empty($timezone) ? $timezone : core_date::get_server_timezone(); + $request['currency'] = !empty($currency) ? $currency : 'GBP'; + $request = array_merge($request, $this->build_urls_for_request($urls)); + $rawresponse = $this->post($this->url, $request); + $responsebody = $this->validate_response_body($rawresponse, $request); + + return !empty($responsebody->value) ? $responsebody->value : 0; + } + + /** + * Update site at Matomo instance. + * + * @param int $siteid + * @param string $sitename + * @param array $urls + * @param string $timezone + * @param string $currency + * @return int + * @throws Exception + */ + public function update_site( + int $siteid, + string $sitename = '', + array $urls = [], + string $timezone = '', + string $currency = '' + ): int { + global $SITE; + + $request = $this->build_request(); + $request['method'] = 'SitesManager.updateSite'; + $request['idSite'] = $siteid; + $request['siteName'] = !empty($sitename) ? $sitename : $SITE->fullname; + $request['timezone'] = !empty($timezone) ? $timezone : core_date::get_server_timezone(); + $request['currency'] = !empty($currency) ? $currency : 'GBP'; + $request = array_merge($request, $this->build_urls_for_request($urls)); + $rawresponse = $this->post($this->url, $request); + $responsebody = $this->validate_response_body($rawresponse, $request); + + return !empty($responsebody->value) ? $responsebody->value : 0; + } + + /** + * Log any errors and return the json decoded result. + * + * @param string $responsebody + * @param array $request + * @return mixed + */ + protected function validate_response_body(string $responsebody, array $request) { + global $DB; + + try { + $responsebody = json_decode($responsebody, false, 512, JSON_THROW_ON_ERROR); + } catch (Throwable $t) { + $responsebody = $t->getMessage(); + } + + if (!empty($responsebody->result) && $responsebody->result === 'error') { + $todb = new stdClass(); + $todb->endpoint = $request['method']; + $todb->error = $responsebody->message; + $todb->timecreated = time(); + $DB->insert_record('watool_matomo_api_error_log', $todb); + debugging($responsebody->message); + } + + return $responsebody; + } + + /** + * Parse an array into the correct associative type for the request. + * + * @param array $urls + * @return array + */ + private function build_urls_for_request(array $urls): array { + global $CFG; + + $urls = !empty($urls) ? $urls : [$CFG->wwwroot]; + $associative = []; + $count = 0; + foreach ($urls as $url) { + $associative['urls[' . $count . ']'] = $url; + $count++; + } + + return $associative; + } +} diff --git a/tool/matomo/classes/tool/tool.php b/tool/matomo/classes/tool/tool.php index e14c8ee..82c6d9c 100644 --- a/tool/matomo/classes/tool/tool.php +++ b/tool/matomo/classes/tool/tool.php @@ -25,7 +25,11 @@ namespace watool_matomo\tool; +use stdClass; +use tool_webanalytics\record; +use tool_webanalytics\records_manager; use tool_webanalytics\tool\tool_base; +use watool_matomo\client; defined('MOODLE_INTERNAL') || die(); @@ -47,12 +51,12 @@ public function get_tracking_code(): string { $settings = $this->record->get_property('settings'); - $template = new \stdClass(); - $template->siteid = $settings['siteid']; + $template = new stdClass(); + $template->siteid = $settings['siteid'] ?? ''; $template->siteurl = $settings['siteurl']; $custompiwikjs = (isset($settings['piwikjsurl']) && !empty($settings['piwikjsurl'])); $template->piwikjsurl = $custompiwikjs ? $settings['piwikjsurl'] : $settings['siteurl']; - $template->imagetrack = $settings['imagetrack']; + $template->imagetrack = $settings['imagetrack'] ?? ''; $template->userid = false; @@ -82,6 +86,10 @@ public function form_add_settings_elements(\MoodleQuickForm &$mform) { $mform->setType('siteurl', PARAM_TEXT); $mform->addRule('siteurl', get_string('required'), 'required', null, 'client'); + $mform->addElement('password', 'apitoken', get_string('apitoken', 'watool_matomo')); + $mform->setType('apitoken', PARAM_TEXT); + $mform->addHelpButton('apitoken', 'apitoken', 'watool_matomo'); + $mform->addElement('text', 'piwikjsurl', get_string('piwikjsurl', 'watool_matomo')); $mform->addHelpButton('piwikjsurl', 'piwikjsurl', 'watool_matomo'); $mform->setType('piwikjsurl', PARAM_URL); @@ -90,7 +98,6 @@ public function form_add_settings_elements(\MoodleQuickForm &$mform) { $mform->addElement('text', 'siteid', get_string('siteid', 'watool_matomo')); $mform->addHelpButton('siteid', 'siteid', 'watool_matomo'); $mform->setType('siteid', PARAM_TEXT); - $mform->addRule('siteid', get_string('required'), 'required', null, 'client'); $mform->addElement('checkbox', 'imagetrack', get_string('imagetrack', 'watool_matomo')); $mform->addHelpButton('imagetrack', 'imagetrack', 'watool_matomo'); @@ -121,7 +128,7 @@ public function form_add_settings_elements(\MoodleQuickForm &$mform) { * @return void */ public function form_validate(&$data, &$files, &$errors) { - if (empty($data['siteid'])) { + if (empty($data['siteid']) && empty($data['apitoken'])) { $errors['siteid'] = get_string('error:siteid', 'watool_matomo'); } @@ -153,11 +160,11 @@ public function form_validate(&$data, &$files, &$errors) { /** * Build settings array from submitted form data. * - * @param \stdClass $data + * @param stdClass $data * * @return array */ - public function form_build_settings(\stdClass $data): array { + public function form_build_settings(stdClass $data): array { $settings = []; $settings['siteid'] = isset($data->siteid) ? $data->siteid : ''; $settings['siteurl'] = isset($data->siteurl) ? $data->siteurl : ''; @@ -165,6 +172,7 @@ public function form_build_settings(\stdClass $data): array { $settings['imagetrack'] = isset($data->imagetrack) ? $data->imagetrack : 0; $settings['userid'] = isset($data->userid) ? $data->userid : 0; $settings['usefield'] = isset($data->usefield) ? $data->usefield : 'id'; + $settings['apitoken'] = isset($data->apitoken) ? $data->apitoken : ''; return $settings; } @@ -172,16 +180,115 @@ public function form_build_settings(\stdClass $data): array { /** * Set form data. * - * @param \stdClass $data Form data. + * @param stdClass $data Form data. * * @return void */ - public function form_set_data(\stdClass &$data) { + public function form_set_data(stdClass &$data) { $data->siteid = isset($data->settings['siteid']) ? $data->settings['siteid'] : ''; $data->siteurl = isset($data->settings['siteurl']) ? $data->settings['siteurl'] : ''; $data->piwikjsurl = isset($data->settings['piwikjsurl']) ? $data->settings['piwikjsurl'] : ''; $data->imagetrack = isset($data->settings['imagetrack']) ? $data->settings['imagetrack'] : 0; $data->userid = isset($data->settings['userid']) ? $data->settings['userid'] : 1; $data->usefield = isset($data->settings['usefield']) ? $data->settings['usefield'] : 'id'; + $data->apitoken = isset($data->settings['apitoken']) ? $data->settings['apitoken'] : ''; + } + + /** + * Register a site with the configured Matomo instance, called from the instance form submission. + * Must have no site id set on the record yet. + * Must have apitoken and siteurl set in the record. + * Must not already be registered with the API using the current site url. + * + * @param record $record + * @return int + */ + public function register_site(record $record): int { + + $settings = $this->record->get_property('settings'); + if (!empty($settings['siteid'])) { + return 0; + } + + if (empty($settings['siteurl']) && empty($settings['apitoken'])) { + return 0; + } + + $client = new client($settings['siteurl'], $settings['apitoken']); + + if ($client->get_siteid_from_url()) { + return 0; + } + + return $client->add_site(); + } + + /** + * Is the auto provisioning config set? + * + * @return bool + */ + public static function supports_auto_provision(): bool { + $config = get_config('watool_matomo'); + + return !empty($config->autoapiurl) && !empty($config->autoapitoken); + } + + /** + * Has the current siteurl changed based on any stored instances? + * + * @return bool + */ + public static function can_auto_provision(): bool { + global $CFG; + if (!self::supports_auto_provision()) { + return false; + } + $canprovision = true; + $rm = new records_manager(); + $records = $rm->get_all(); + foreach ($records as $record) { + $settings = $record->get_property('settings'); + $name = $record->get_property('name'); + if ((!empty($settings['wwwroot']) && $settings['wwwroot'] === $CFG->wwwroot) || $name === 'auto-provisioned:FAILED') { + $canprovision = false; + } + } + return $canprovision; + } + + /** + * Auto provision a new instance based on config 'autoapiurl' and 'autoapitoken'. + * + * @return void + */ + public static function auto_provision(): void { + global $CFG; + + $config = get_config('watool_matomo'); + + if (empty($config->autoapiurl) && empty($config->autoapitoken)) { + return; + } + + $client = new client($config->autoapiurl, $config->autoapitoken); + $rm = new records_manager(); + $data = new stdClass(); + $data->name = 'auto-provisioned:' . uniqid(); + + try { + $siteid = $client->add_site(); + } catch (Throwable $t) { + $data->name = 'auto-provisioned:FAILED'; + } + + $settings['siteid'] = $siteid; + $settings['wwwroot'] = $CFG->wwwroot; + $settings['siteurl'] = $config->autoapiurl; + $settings['apitoken'] = $config->autoapitoken; + $data->type = 'matomo'; + $data->settings = $settings; + $record = new record($data); + $rm->save($record); } } diff --git a/tool/matomo/db/install.xml b/tool/matomo/db/install.xml new file mode 100644 index 0000000..9718479 --- /dev/null +++ b/tool/matomo/db/install.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + +
+
+
\ No newline at end of file diff --git a/tool/matomo/lang/en/watool_matomo.php b/tool/matomo/lang/en/watool_matomo.php index db7f9dc..8b360a3 100644 --- a/tool/matomo/lang/en/watool_matomo.php +++ b/tool/matomo/lang/en/watool_matomo.php @@ -31,7 +31,7 @@ $string['piwikjsurl'] = 'Alternative piwik.js URL'; $string['piwikjsurl_help'] = 'Enter alternative piwik.js URL (optional) without http(s), piwik.js or a trailing slash, used when you host your own version of piwik.js'; $string['siteid'] = 'Matomo Site ID'; -$string['siteid_help'] = 'Enter your Matomo Site ID'; +$string['siteid_help'] = 'You must enter your Matomo Site ID. You can leave this blank if you are intending to register this site over the API using the token above.'; $string['imagetrack'] = 'Image Tracking'; $string['imagetrack_help'] = 'Enable Image Tracking for Moodle for browsers with JavaScript disabled'; $string['error:siteid'] = 'You must provide Site ID'; @@ -39,9 +39,17 @@ $string['error:siteurlinvalid'] = 'You must provide valid site URL'; $string['error:siteurlhttps'] = 'Please provide URL without http(s)'; $string['error:siteurltrailingslash'] = 'Please provide URL without a trailing slash'; +$string['error:noapicreds'] = 'No site URL or API token configured!'; $string['privacy:metadata:watool_matomo'] = 'In order to track user activity, user data needs to be sent with that service.'; $string['privacy:metadata:watool_matomo:userid'] = 'The userid is sent from Moodle to personalise user activity.'; $string['userid'] = 'Track User ID'; $string['userid_help'] = 'If enabled userId parameter will be sent for tracking'; $string['usefield'] = 'User ID field'; $string['usefield_help'] = 'Select a user field to be used as User ID when sending for tracking'; +$string['apiheader'] = 'API Instance Settings:'; +$string['apiurl'] = 'API url'; +$string['apiurl_help'] = 'Base URL of the Matomo instance'; +$string['apitoken'] = 'API token'; +$string['apitoken_help'] = 'Authentication "token_auth" of a user who can access the instance over the API. If configured, this allows automatic site registration with the matomo instance set in "Analytics URL" above.'; +$string['apitoken_desc'] = 'Authentication "token_auth" of a user who can access the instance over the API.'; +$string['autoprovision_heading'] = 'Auto provision settings:'; diff --git a/tool/matomo/settings.php b/tool/matomo/settings.php new file mode 100644 index 0000000..a2066f5 --- /dev/null +++ b/tool/matomo/settings.php @@ -0,0 +1,53 @@ +. + +/** + * Settings + * + * @package tool_webanalytics + * @author Simon Adams (simon.adams@catalyst-eu.net) + * @copyright 2023 Catalyst IT + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die; + +if ($hassiteconfig) { + $settings->add( + new admin_setting_heading( + 'watool_matomo_autoprovision', + get_string('autoprovision_heading', 'watool_matomo'), + '' + ) + ); + $settings->add( + new admin_setting_configtext( + 'watool_matomo_siteurl', + get_string('apiurl', 'watool_matomo'), + get_string('apiurl_help', 'watool_matomo'), + '', + PARAM_ALPHANUM + ) + ); + $settings->add( + new admin_setting_configpasswordunmask( + 'watool_matomo_token', + get_string('apitoken', 'watool_matomo'), + get_string('apitoken_desc', 'watool_matomo'), + '', + ) + ); +} diff --git a/tool/matomo/version.php b/tool/matomo/version.php index a5816e4..192baa3 100644 --- a/tool/matomo/version.php +++ b/tool/matomo/version.php @@ -25,7 +25,7 @@ defined('MOODLE_INTERNAL') || die; -$plugin->version = 2020063001; // The current plugin version (Date: YYYYMMDDXX). +$plugin->version = 2020063002; // The current plugin version (Date: YYYYMMDDXX). $plugin->release = 2020063001; // Same as version. $plugin->requires = 2017051500; // Requires Moodle 3.3 or later. $plugin->component = "watool_matomo";