Skip to content

Commit

Permalink
Add auto-provisioning for matomo
Browse files Browse the repository at this point in the history
  • Loading branch information
SimonasAdams committed Jun 27, 2023
1 parent b24faf3 commit 38ae377
Show file tree
Hide file tree
Showing 17 changed files with 662 additions and 15 deletions.
48 changes: 48 additions & 0 deletions classes/auto_provisioner.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

/**
* Auto-provisioning service.
*
* @package tool_webanalytics
* @author Simon Adams ([email protected])
* @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();
}
}
}
}
7 changes: 7 additions & 0 deletions classes/form/edit.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

use moodleform;
use tool_webanalytics\plugin_manager;
use tool_webanalytics\record;

defined('MOODLE_INTERNAL') || die();

Expand Down Expand Up @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions classes/injector.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@

namespace tool_webanalytics;

use tool_webanalytics\tool\tool_interface;

defined('MOODLE_INTERNAL') || die;

/**
Expand Down Expand Up @@ -68,6 +70,8 @@ public static function render_tracking_code(): string {
}
}

auto_provisioner::auto_provision();

return $result;
}

Expand Down
19 changes: 19 additions & 0 deletions classes/plugin_manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
);
}
}
47 changes: 47 additions & 0 deletions classes/plugininfo/watool.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
14 changes: 14 additions & 0 deletions classes/record.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
7 changes: 7 additions & 0 deletions classes/record_interface.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
36 changes: 36 additions & 0 deletions classes/tool/tool_base.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@

namespace tool_webanalytics\tool;

use stdClass;
use tool_webanalytics\record;
use tool_webanalytics\record_interface;

defined('MOODLE_INTERNAL') || die();
Expand Down Expand Up @@ -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 {}
}
32 changes: 32 additions & 0 deletions classes/tool/tool_interface.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

namespace tool_webanalytics\tool;

use tool_webanalytics\record;
use tool_webanalytics\record_interface;

defined('MOODLE_INTERNAL') || die();
Expand Down Expand Up @@ -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;
}
20 changes: 16 additions & 4 deletions settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
22 changes: 22 additions & 0 deletions tool/matomo/README.md
Original file line number Diff line number Diff line change
@@ -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.
Loading

0 comments on commit 38ae377

Please sign in to comment.