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 Oct 12, 2023
1 parent b24faf3 commit 0268e6a
Show file tree
Hide file tree
Showing 21 changed files with 947 additions and 22 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@ including categories and action types
- Optional tracking for User ID
- User ID could be id or username

#### Matomo auto-provisioning
- Set the watool_matomo 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']['siteurl'] = 'https://matomo.org';` The url of the matomo server.
- `$CFG->forced_plugin_settings['watool_matomo']['apitoken'] = 'xxxx';` The token to allow use of the API at the server.
- An attempt to auto provision will be made the first time a page is loaded when the API config above is set.
- A successfully auto-provisioned site will have an entry in the management page `admin/tool/webanalytics/manage.php` prefixed with 'auto-provisioned'.
- If the Moodle site url changes after an auto provisioned site has been stored, the next page load will attempt to update the instance on the configured Matomo instance with the new url.
- If autoprovisioning failed, the instance will be set with the name 'auto-provisioned:FAILED' to stop continuing attempts per page load. Delete the instance to attempt an autoprovision again.
- You can register with Matomo on manually creating/updating an instance at `admin/tool/webanalytics/manage.php` also. When submitting the form, if the `siteurl` and `apitoken` fields are set and the instance is being created, an attempt to register with the API will be made and the site id will be stored against the instance. If editing an instance, on save the plugin will check the API to see if the Moodle DNS has changed since the instance was last saved and if so it will attempt to register the current URL against that site id in Matomo.

### Google Universal Analytics
- Plugin modifies the page speed sample to have 50% of your visitors samples for page speed instead of 1% making it much more useful
- Set your Google tracking ID
Expand Down
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($tool->get_client(get_config("watool_{$tool->name}")));
}
}
}
}
45 changes: 45 additions & 0 deletions classes/client_base.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?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/>.
/**
* Webanalytics class to wrap HTTP requests.
*
* @package watool_matomo
* @copyright 2023 onwards Catalyst IT EU {@link https://catalyst-eu.net}
* @author Simon Adams [email protected]
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

namespace tool_webanalytics;

use curl;
use stdClass;

/**
* Simple wrapper Http client.
* Each plugin that needs it should implement their own class in the plugin namespace /watool_{PLUGINNAME}/client.
* Each plugin must also ensure that the relevant client config is stored via set_config under component watool_{PLUGINNAME}.
*/
class client_base extends curl {
/**
* @param stdClass $config global settings to allow the API to function
* @param array $settings optional settings for the curl client to use.
*/
public function __construct(stdClass $config, array $settings = []) {
$this->config = $config;
$this->settings = $settings;
parent::__construct($settings);
}
}
9 changes: 9 additions & 0 deletions classes/form/edit.php
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,19 @@ 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);
$pluginmanager = plugin_manager::instance();
$currentplugin = $pluginmanager->get_enabled_plugin_by_type($this->type);
$client = $currentplugin->get_client($data);
if ($siteid = $this->tool->register_site($client)) {
$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
33 changes: 33 additions & 0 deletions classes/plugin_manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@

namespace tool_webanalytics;

use tool_webanalytics\plugininfo\watool;

defined('MOODLE_INTERNAL') || die;

/**
Expand Down Expand Up @@ -117,6 +119,18 @@ public function get_enabled_plugins(): array {
return static::$plugins;
}

/**
* @param string $type
* @return watool|null
*/
public function get_enabled_plugin_by_type(string $type): ?watool {
if (is_null(static::$plugins)) {
static::$plugins = $this->build_plugins();
}

return static::$plugins[$type];
}

/**
* Build a list of enabled plugins.
*
Expand All @@ -141,4 +155,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();
}
);
}
}
59 changes: 59 additions & 0 deletions classes/plugininfo/watool.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
namespace tool_webanalytics\plugininfo;

use core\plugininfo\base;
use stdClass;
use tool_webanalytics\record_interface;
use tool_webanalytics\tool\tool_interface;

Expand All @@ -52,4 +53,62 @@ 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;
}

/**
* @param stdClass $config
* @return mixed|void
*/
public function get_client(stdClass $config) {
$class = "\watool_{$this->name}\client";
if (class_exists($class)) {
return new $class($config);
}
}
}
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
2 changes: 1 addition & 1 deletion classes/table/tools_table.php
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ public function col_actions(record_interface $record) {

$buttons[] = self::format_icon_link(
new moodle_url('/admin/tool/webanalytics/edit.php', [
'edit' => $record->get_property('id'),
'id' => $record->get_property('id'),
'type' => $record->get_property('type')
]),
't/edit',
Expand Down
38 changes: 38 additions & 0 deletions classes/tool/tool_base.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@

namespace tool_webanalytics\tool;

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

defined('MOODLE_INTERNAL') || die();
Expand Down Expand Up @@ -144,4 +147,39 @@ public function trackurl($urlencode = false, $leadingslash = false): string {
return $trackurl;
}

/**
* Called from the config instance form submission.
*
* @param $client
* @return int $siteid returned from the API.
*/
public function register_site($client): 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.
*
* @param $client
* @return void
*/
public static function auto_provision($client): void {}
}
Loading

0 comments on commit 0268e6a

Please sign in to comment.