Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Panel Area & be ready for Kirby 4 #47

Merged
merged 13 commits into from
May 4, 2024
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.cache
.DS_Store
node_modules
package-lock.json
34 changes: 31 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ return array(
);
```
4. Add this code to your footer snippet: `<?php echo snippet('matomo') ?>`
5. Copy [this blueprint](#51-basic-blueprint-example) under a dedicated tab / page in the panel.
5. Visit the Matomo panel area or copy [this blueprint](#51-basic-blueprint-example) under a dedicated tab / page in the panel.

You're all set.

Expand All @@ -51,7 +51,7 @@ You're all set.
- It's free (like, really free. You don't pay with your data)
- It's self-hosted (which means more control for you over your data)
- It respects your visitors privacy (IP Anonymization, automated logs deletion, data ownership)
- It now integrates smoothly with Kirby 3 ✌️
- It now integrates smoothly with Kirby 4 ✌️

<br/>

Expand All @@ -77,6 +77,10 @@ return array(
'sylvainjule.matomo.trackUsers' => false,
'sylvainjule.matomo.disableCookies' => false,
'sylvainjule.matomo.blacklist' => ['127.0.0.1', '::1'],
'sylvainjule.matomo.basicAuth' => null,
'sylvainjule.matomo.label' => 'Matomo',
'sylvainjule.matomo.menu' => true

);
```

Expand Down Expand Up @@ -146,6 +150,30 @@ If you want to use Matomo without any tracking cookies on the user side, set thi
'sylvainjule.matomo.disableCookies' => false
```

#### 3.9. `basicAuth`

If your Matomo instance is additionally secured by Basic Authentication, you can configure these credentials in the format `USERNAME:PASSWORD`.

```php
'sylvainjule.matomo.basicAuth' => null
```

#### 3.10. `label`

If you want to change the label for the Matomo Panel area, you can configure it in the options.

```php
'sylvainjule.matomo.label' => 'Matomo'
```

#### 3.11. `menu`

If you want to hide the Matomo Panel area, set this option to `false`.

```php
'sylvainjule.matomo.menu' => true
```

<br/>

## 4. Template usage
Expand All @@ -160,7 +188,7 @@ You only need to include the snippet in your code somewhere:

## 5. Panel dashboard

The panel dashboard (screenshot on top of this readme) displays metrics for the whole website.
The panel dashboard (screenshot on top of this readme) displays metrics for the whole website. It is usually available as panel area (at the `{ site.url }/panel/matomo` route), but you can also configure it in a custom tab / blueprint.

#### 5.1. Basic blueprint example

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sylvainjule/matomo",
"description": "Matomo helpers and panel sections for Kirby",
"description": "Matomo helpers, panel area and sections for Kirby",
"type": "kirby-plugin",
"license": "MIT",
"authors": [
Expand Down
2 changes: 1 addition & 1 deletion index.css

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions index.js

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions index.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require_once __DIR__ . '/lib/matomo.php';

Kirby::plugin('sylvainjule/matomo', array(
'areas' => require_once __DIR__ . '/lib/area.php',
'options' => array(
'token' => false,
'url' => false,
Expand All @@ -11,6 +12,8 @@
'debug' => false,
'blacklist' => ['127.0.0.1', '::1'],
'trackUsers' => false,
'label' => 'Matomo',
'menu' => true
),
'snippets' => array(
'matomo' => __DIR__ . '/lib/snippets/matomo.php'
Expand Down
47 changes: 47 additions & 0 deletions lib/area.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

return [
'matomo' => function ($kirby) {
$label = $kirby->option('sylvainjule.matomo.label');
return [
'label' => $label,
'icon' => 'line-chart',
'link' => 'matomo',
'menu' => $kirby->option('sylvainjule.matomo.menu'),
'views' => [
[
'pattern' => 'matomo',
'action' => function () use ($label) {
$lang = kirby()->user()->language();
$periods = ['year', 'month', 'week', 'day'];
$url = option('sylvainjule.matomo.url');
$widgets = ["referrerType", "websites", "socials", "devicesType", "keywords", "popularPages"];
return [
'component' => 'matomo',
'title' => $label . ': ' . t('matomo.title.overview'),
'breadcrumb' => [
[
'label' => t('matomo.title.overview'),
'link' => 'matomo'
]
],
'props' => [
'main' => [
'periods' => $periods,
'lang' => $lang,
'widgets' => $widgets
],
'sidebar' => [
'link' => true,
'realtime' => true,
'summary' => true,
'url' => $url,
]
]
];
}
]
]
];
}
];
20 changes: 12 additions & 8 deletions lib/matomo.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public static function allowed() {
protected $url = null;
protected $id = null;
protected $token = null;
protected $requestParams = [];
protected $methodsMap = array (
'referrerType' => 'Referrers.getReferrerType',
'websites' => 'Referrers.getWebsites',
Expand All @@ -48,6 +49,9 @@ public function __construct() {
$this->url = option('sylvainjule.matomo.url');
$this->id = option('sylvainjule.matomo.id');
$this->token = is_callable($this->token) ? $this->token() : option('sylvainjule.matomo.token');
if (option('sylvainjule.matomo.basicAuth') !== null) {
$this->requestParams['basicAuth'] = option('sylvainjule.matomo.basicAuth');
}
}

public function apiWidget($widget, $method, $period, $date, $limit, $lang) {
Expand All @@ -58,12 +62,12 @@ public function apiWidget($widget, $method, $period, $date, $limit, $lang) {
$url .= $limit ? "&filter_limit=" . $limit : '';
$url .= "&token_auth=". $this->token;

$content = Remote::get($url)->json();
$content = Remote::get($url, $this->requestParams)->json();
return $content;
}

public function apiBulkWidgets($widgets, $period, $date, $limit, $lang) {
$widgets = json_decode(stripslashes($widgets));
$widgets = json_decode($widgets);

$url = $this->url;

Expand All @@ -77,7 +81,7 @@ public function apiBulkWidgets($widgets, $period, $date, $limit, $lang) {
$i++;
}

$content = Remote::get($url)->content();
$content = Remote::get($url, $this->requestParams)->json();
return $content;
}

Expand All @@ -87,7 +91,7 @@ public function apiChart($method, $period, $date) {
$url .= "&idSite=". $this->id ."&period=". $period ."&date=" . $date;
$url .= "&format=JSON&token_auth=". $this->token;

$content = Remote::get($url)->json();
$content = Remote::get($url, $this->requestParams)->json();
return $content;
}

Expand All @@ -97,7 +101,7 @@ public function apiOverview($method, $period, $date) {
$url .= "&idSite=". $this->id ."&period=". $period ."&date=" . $date;
$url .= "&format=JSON&token_auth=". $this->token;

$content = Remote::get($url)->json();
$content = Remote::get($url, $this->requestParams)->json();
return $content;
}

Expand All @@ -109,7 +113,7 @@ public function apiRealtime() {
$url .= "&idSite=". $this->id ."&lastMinutes=3";
$url .= "&format=JSON&token_auth=". $this->token;

$content = Remote::get($url)->json();
$content = Remote::get($url, $this->requestParams)->json();
return $content;
}

Expand All @@ -131,7 +135,7 @@ public function apiBulkSummary() {
$url .= "&urls[3]=";
$url .= urlencode("method=VisitsSummary.getVisits&idSite=". $this->id ."&period=year&date=today");

$content = Remote::get($url)->json();
$content = Remote::get($url, $this->requestParams)->json();
return $content;
}

Expand All @@ -142,7 +146,7 @@ public function apiPageMetrics($period, $uri, $lang) {
$url .= "&format=JSON&token_auth=". $this->token;
$url .= $lang['multilang'] ? '&expanded=1' : '';

$content = Remote::get($url)->json();
$content = Remote::get($url, $this->requestParams)->json();
$content = $this->filterPageMetrics($content, $uri, $lang);
return $content;
}
Expand Down
51 changes: 40 additions & 11 deletions src/components/main.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
<template>
<div class="matomo-main">
<div class="matomo-period-selector">
<div v-for="(period, index) in periods" :class="['matomo-period-option', period, {active: period == currentPeriod}]" @click="setCurrentPeriod(period)">{{ $t('matomo.chart.'+ period) }}</div>
<div
v-for="(period) in periods"
:class="['matomo-period-option', period, {active: period == currentPeriod}]"
@click="setCurrentPeriod(period)"
v-bind:key="period">
{{ $t('matomo.chart.'+ period) }}
</div>
</div>

<div v-if="chart" :class="['matomo-chart', {'is-empty': chartEmpty}]">
<div v-if="chartLoading" class="overlay"><div class="loader"></div></div>
<div v-if="chartEmpty" class="empty"><span>{{ $t('matomo.empty') }}</span></div>
Expand All @@ -23,21 +29,44 @@ import Widgets from './widgets/widgets.vue'

export default {
components: {Chart, Overview, Widgets},
data() {
props: {
periods: {
type: Array,
default: []
},
chart: {
type: Boolean,
default: true
},
overview: {
type: Boolean,
default: true
},
currentPeriod: {
type: String,
default: 'week'
},
lang: {
type: String,
default: ''
},
widgets: {
type: Array,
default: []
}
},
data() {
return {
currentPeriod: '',
periods: Array,
periods: [],
defaults: {
period: 'month',
limit: 5,
},
totalVisits: '',
lang: '',
chart: false,
overview: false,
widgets: Array,
chart: true,
chartLoading: true,
chartEmpty: false,
chartEmpty: false,
widgets: []
}
},
created() {
Expand Down Expand Up @@ -79,4 +108,4 @@ export default {

<style lang="scss">
@import '../assets/css/styles.scss'
</style>
</style>
23 changes: 19 additions & 4 deletions src/components/sidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,27 @@ import SummaryWidget from './widgets/summary.vue'

export default {
components: {RealtimeWidget, SummaryWidget},
props: {
link: {
type: Boolean,
default: true
},
realtime: {
type: Boolean,
default: true
},
summary: {
type: Boolean,
default: true
},
url: String,
},
data() {
return {
url: String,
link: false,
realtime: false,
summary: false,
url: '',
link: true,
realtime: true,
summary: true,
}
},
computed: {
Expand Down
31 changes: 31 additions & 0 deletions src/components/view.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<template>
<k-inside>
<k-view class="k-matomo">
<k-header> {{ $t('matomo.title.overview') }} </k-header>
<k-grid variant="columns">
<k-column width="3/4">
<matomo-main
:periods="main['periods']"
:lang="main['lang']"
:widgets="main['widgets']" />
</k-column>
<k-column width="1/4">
<matomo-sidebar
:link="sidebar['link']"
:summary="sidebar['summary']"
:realtime="sidebar['realtime']"
:url="sidebar['url']" />
</k-column>
</k-grid>
</k-view>
</k-inside>
</template>

<script>
export default {
props: {
main: Array,
sidebar: Array
},
};
</script>
2 changes: 1 addition & 1 deletion src/components/widgets/widget.vue
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export default {
},
computed: {
isEmpty() {
return this.status == 'empty'
return this.results.length === 0
},
originalColor() {
return this.widget == 'socials'
Expand Down
Loading