Add auto-provisioning for matomo - #52
SimonasAdams wants to merge 1 commit into
Conversation
| } | ||
|
|
||
| /** | ||
| * Override in child to implement. |
There was a problem hiding this comment.
Can you please flesh this out more with how this should work generically, eg if someone wanted to come and add support for GA later on
There was a problem hiding this comment.
That should be more descriptive now.
|
|
||
| use moodleform; | ||
| use tool_webanalytics\plugin_manager; | ||
| use tool_webanalytics\record; |
| - 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. |
There was a problem hiding this comment.
Can you please flesh this out a bit more, this might only need comments but might be some missing code too. I want to understand what is happened if we roll this auto provisioning out toa pre production side, eg p-client.catalyst-au.net and they get a matomo instance, and then a few months later they go live and the dns changes to moodle.client.com
In this scenario I can see a method called update_site but it isn't actually called from anywhere?
I would expect this to continue using the same matomo id, ie the one instance will seamlessly show stats from before and after the dns change. This should be the same as if the client later changes their domain for marketing reasons, the stats should continue to be seamless.
There was a problem hiding this comment.
It was previously just creating a new instance on the matomo server when the DNS changed but is now updating the url over the API if the DNS changes, essentially keeping the site id the same. Have fleshed this out in the docs.
Note that when manually adding an instance config on the front end it will also try to create/update over the API if the API config is in the form.
I have also documented these methods in unit tests for the watool_matomo plugin too.
| @@ -0,0 +1,22 @@ | |||
| # Matomo (formerly Piwik) | |||
There was a problem hiding this comment.
I've also realized this is a new readme file. Even though this is specific to the tool_matomo I think this should be a section under the main readme purely to make it easier to find when casually browsing github so you don't have to go dig. We could just cross link the two readmes but this chunk of help is small enough that we can just embed it directly.
In theory if we added this same support to GA and other tools they could all be inline in the main readme
There was a problem hiding this comment.
Have moved this to the parent plugin README
5445cbf to
f4c5caf
Compare
f4c5caf to
0268e6a
Compare
bwalkerl
left a comment
There was a problem hiding this comment.
Mentioning the issues I've noticed. We'll work on getting these sorted.
| <TABLE NAME="watool_matomo_api_error_log" COMMENT="Matomo Track log errors"> | ||
| <FIELDS> | ||
| <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/> | ||
| <FIELD NAME="endpoint" TYPE="text" LENGTH="255" NOTNULL="false" SEQUENCE="false" COMMENT="The name of the endpoint function called during the sync attempt"/> | ||
| <FIELD NAME="error" TYPE="text" LENGTH="255" NOTNULL="false" SEQUENCE="false" COMMENT="The string given as the error"/> | ||
| <FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/> | ||
| </FIELDS> | ||
| <KEYS> | ||
| <KEY NAME="primary" TYPE="primary" FIELDS="id"/> | ||
| </KEYS> | ||
| </TABLE> |
There was a problem hiding this comment.
- This table is missing an upgrade step
- Table name is needlessly long and could cause issues
There was a problem hiding this comment.
agree we probably just don't need the table
| $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'; |
There was a problem hiding this comment.
Fallback currency should be more global
| if (!empty($url['scheme'])) { | ||
| return $this->config->siteurl; | ||
| } | ||
| return "https://{$url['path']}"; |
There was a problem hiding this comment.
This doesn't look like it would form a proper url
| 'id' => 'id', | ||
| 'username' => 'username', | ||
| 'id' => 'id', | ||
| 'username' => 'username', |
There was a problem hiding this comment.
Indenting changed to being incorrect
| * Otherwise, create a new instance over the API. | ||
| * | ||
| * @param $client | ||
| * @return int siteid if successful, 0 if not. |
There was a problem hiding this comment.
Would recommend clarifying what is returned for already registered sites. This appears to be siteid, so would be "if successful or already registered"
| $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'), | ||
| $CFG->forced_plugin_settings['watool_matomo']['url'] ?? '', | ||
| PARAM_URL | ||
| ) | ||
| ); | ||
| $settings->add( | ||
| new admin_setting_configpasswordunmask( | ||
| 'watool_matomo_token', | ||
| get_string('apitoken', 'watool_matomo'), | ||
| get_string('apitoken_desc', 'watool_matomo'), | ||
| $CFG->forced_plugin_settings['watool_matomo']['token'] ?? '', | ||
| ) |
| $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') |
| use curl; | ||
| use Exception; | ||
| use moodle_url; |
There was a problem hiding this comment.
curl and moodle_url aren't used
| use tool_webanalytics\tool\tool_interface; | ||
|
|
| public function form_build_settings(stdClass $data): array { | ||
| $settings = []; | ||
| $settings['siteid'] = isset($data->siteid) ? $data->siteid : ''; | ||
| $settings['siteid'] = isset($data->siteid) ? $data->siteid : ''; |
There was a problem hiding this comment.
this is a bit repetitive to me, can this be a $defaults array and then cast the stdClass to an array and merge them and skip all the isset bits?
bwalkerl
left a comment
There was a problem hiding this comment.
I found a couple of extra issues after more testing
| 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') { |
There was a problem hiding this comment.
If $settings['wwwroot'] doesn't exist (which will happen for existing records since this is a new setting) auto provision is allowed for sites that may already have the proper URL set. Right now this will lead to creating a duplicate record due to other mentioned issues.
| $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)); |
There was a problem hiding this comment.
If the build_urls_for_request function isn't provided with the existing urls (none are passed here), it will override all existing sites with just the updated site. This is problematic for registrations that are connected to multiple site urls. This is used in both registrations and auto provisioning.
| $allrecords = $rm->get_all(); | ||
| $autoprovisioned = array_filter($allrecords, function($record) { | ||
| return preg_match("/^auto-provisioned:/", $record->get_property('name')); | ||
| }); | ||
|
|
||
| if ($autoprovisioned = reset($autoprovisioned)) { | ||
| $apsettings = $autoprovisioned->get_property('settings'); | ||
| $data = $autoprovisioned->export(); | ||
| } else { | ||
| $data = new stdClass(); | ||
| $data->name = 'auto-provisioned:' . uniqid(); | ||
| } | ||
|
|
||
| $hasdnschanged = !empty($apsettings['wwwroot']) && $apsettings['wwwroot'] !== $CFG->wwwroot; | ||
|
|
||
| try { | ||
| // If the DNS has changed, let's try to update an existing site. | ||
| if ($hasdnschanged && $siteid = $client->get_siteid_from_url($apsettings['wwwroot'])) { | ||
| $client->update_site($siteid, '', [$CFG->wwwroot]); | ||
| } else { | ||
| // No site provisioned yet, create a new one. | ||
| $siteid = $client->add_site(); | ||
| } |
There was a problem hiding this comment.
This is hardcoded to 'auto-provisioned', but if there's no match it goes straight to adding a site, which will create duplicates for sites that have a manual link or have changed the name. Needs some extra checks.
| $CFG->forced_plugin_settings['watool_matomo']['url'] ?? '', | ||
| PARAM_URL | ||
| ) | ||
| ); | ||
| $settings->add( | ||
| new admin_setting_configpasswordunmask( | ||
| 'watool_matomo_token', | ||
| get_string('apitoken', 'watool_matomo'), | ||
| get_string('apitoken_desc', 'watool_matomo'), | ||
| $CFG->forced_plugin_settings['watool_matomo']['token'] ?? '', |
There was a problem hiding this comment.
The defaults don't match the names of the settings that are used elsewhere or in the readme, and the token setting name doesn't match either. It may also be better to not use these as the default so the token can be kept hidden?
| $this->config = $config; | ||
| $this->settings = $settings; |
There was a problem hiding this comment.
Properties for these haven't been declared.
This commit contains the ability to auto provision sites based on either a value in the config.php file or via the instance form on the front end.
To auto provision on install or upgrade add a setting
watool_matomointoconfig.phpas an array, e.g:Where the apitoken is the
auth_tokenof the user that is allowed to do API requests on the Matomo server, and the 'siteurl' is the URL of the Matomo server instance.During install if the above setting is present it will loop through the array and attempt to create a site on the remote Matomo instance per array item. If successful, it create new records locally and stores the siteid, the apitoken, and the siteurl per instance created.
When manually adding a new instance via the front end, an auto provision attempt will be made if the form submission contains both the siteurl and the apitoken. If successful, the siteid is retrieved and stored against the local record. If the form is submitted with a siteid, there will be not attempt to register with the remote server.
Additionally, at the point of submisision the current
CFG->wwwrootis stored against that instance locally. On page loads that check if the tag should be output, a check is made to see if the currentCFG->wwwrootmatches that stored against the local record. If it does not match, an attempt is made to update the remotely registered instance with the new url. If successful, this new url is then stored locally. This is to allow the remote to track if and when the url of the server changes.