1<?php
2// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
3//
4// All Rights Reserved. See copyright.txt for details and a complete list of authors.
5// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
6// $Id$
7
8function wikiplugin_piwik_info()
9{
10	return [
11		'name' => tra('Piwik'),
12		'documentation' => 'PluginPiwik',
13		'description' => tr('Embed a Piwik preformatted report (widget module) - Piwik Analytics is required.
14                            To use this plugin you have to grant in your Piwik view permission to anonymous for the selected "Site Id" or to add a token authentification parameter.'),
15		'prefs' => ['wikiplugin_piwik'],
16		'iconname' => 'chart',
17		'introduced' => 15,
18		'tags' => ['basic'],
19		'format' => 'html',
20		'params' => [
21			'piwikserverurl' => [
22				'required' => false,
23				'name' => tra('Piwik server url'),
24				'description' => tr('The url to your Piwik Server, where data for the report are collected and available.') . ' <code>http(s)://yourpiwik.tld/index.php?</code> ' . '<br />'
25					. tr('In Piwik, the selected site (Site Id) must have view permission set for anonymous, or a token authentication parameter can be inserted in the Piwik server URL.') . '<br />'
26					. '<code>http(s)://yourpiwik.tld/index.php&token_auth=yourtokencode</code> ' . tr('Important : token_auth is visible in the html code and must be used in private page accessible to trusted users.'),
27				'since' => '15',
28				'default' => '',
29			],
30
31			'idSite' => [
32				'required' => false,
33				'name' => tra('Site Id'),
34				'description' => tr('The ID of this website in Piwik To be improved.'),
35				'since' => '15',
36				'filter' => 'digits',
37				'default' => '',
38			],
39
40			'moduleToWidgetize' => [
41				'required' => false,
42				'name' => tra('Module and Action To Widgetize'),
43				'description' => tr('Piwik widget module to be used (as described in the widget section of your Piwik server) followed by the actionToWidgetize parameter separated by a comma.'),
44				'since' => '15',
45				'default' => 'VisitsSummary,getEvolutionGraph',
46				'options' => [
47					['text' => tra('Actions - Pages'), 'value' => 'Actions,getPageUrls'],
48					['text' => tra('Actions - Entry pages'), 'value' => 'Actions,getEntryPageUrls'],
49					['text' => tra('Actions - Exit pages'), 'value' => 'Actions,getExitPageUrls'],
50					['text' => tra('Actions - Outlinks'), 'value' => 'Actions,getOutlinks'],
51					['text' => tra('Dashboard'), 'value' => 'Dashboard,index'],
52					['text' => tra('Live - Visitor in real time'), 'value' => 'Live,widget'],
53					['text' => tra('Live - Simple Last Visit Count'), 'value' => 'Live,getSimpleLastVisitCount'],
54					['text' => tra('Live - Visitor Profile Popup'), 'value' => 'Live,getVisitorProfilePopup'],
55					['text' => tra('Referrers - All referrers'), 'value' => 'Referrers,getAll'],
56					['text' => tra('Referrers - Search engines'), 'value' => 'Referrers,getSearchEngines'],
57					['text' => tra('Resolution - Screen Resolution'), 'value' => 'Resolution,getResolution'],
58					['text' => tra('SEO - SEO Ranking (slow)'), 'value' => 'SEO,getRank'],
59					['text' => tra('User Country Map - RealTime Map'), 'value' => 'UserCountryMap,realtimeMap'],
60					['text' => tra('User Country Map - Visitor Map'), 'value' => 'UserCountryMap,visitorMap'],
61					['text' => tra('User Country Map - Country'), 'value' => 'UserCountryMap,getCountry'],
62					['text' => tra('User Country Map - Continent'), 'value' => 'UserCountryMap,getContinent'],
63					['text' => tra('User Language - Language'), 'value' => 'UserLanguage,getLanguage'],
64					['text' => tra('User Language - Language Code'), 'value' => 'UserLanguage,getLanguageCode'],
65					['text' => tra('Visits Time - By day of the week'), 'value' => 'VisitTime,getByDayOfWeek'],
66					['text' => tra('Visits Time - Visit Information Per Local Time'), 'value' => 'VisitTime,getVisitInformationPerLocalTime'],
67					['text' => tra('Visits Time - Visit Information Per Server Time'), 'value' => 'VisitTime,getVisitInformationPerServerTime'],
68					['text' => tra('Visits Summary - by day of the week'), 'value' => 'VisitTime,getByDayOfWeek'],
69					['text' => tra('Visits Summary - over time'), 'value' => 'VisitsSummary,getEvolutionGraph'],
70					['text' => tra('Visits Summary - overview with graph'), 'value' => 'VisitsSummary,index'],
71					['text' => tra('Visitors - Visitor map'), 'value' => 'UserCountryMap,visitorMap'],
72					['text' => tra('Visitors - Pages per visit'), 'value' => 'VisitorInterest,getNumberOfVisitsPerVisitDuration'],
73					['text' => tra('Visitors - Frequency overview'), 'value' => 'VisitFrequency,getSparklines'],
74					['text' => tra('Visitors - Returning visits over time'), 'value' => 'VisitFrequency,getEvolutionGraph'],
75					['text' => tra('Visitor Devices - Device type'), 'value' => 'DevicesDetection,getType'],
76					['text' => tra('Visitor Devices - browser'), 'value' => 'DevicesDetection,getBrowsers'],
77					['text' => tra('Visitor Devices - Browser Versions'), 'value' => 'DevicesDetection,getBrowserVersions'],
78					['text' => tra('Visitor Devices - OS Families'), 'value' => 'DevicesDetection,getOsFamilies'],
79					['text' => tra('Visitor Devices - OS Versions'), 'value' => 'DevicesDetection,getOsVersions'],
80					['text' => tra('Visitor Interest - Number Of Visits Per Visit Duration'), 'value' => 'VisitorInterest,getNumberOfVisitsPerVisitDuration'],
81					['text' => tra('Visitor Interest - Number Of Visits Per Page'), 'value' => 'VisitorInterest,getNumberOfVisitsPerPage'],
82					['text' => tra('Visitor Interest - Number Of Visits By Visit Count'), 'value' => 'VisitorInterest,getNumberOfVisitsByVisitCount'],
83					['text' => tra('Visitor Interest - Number Of Visits By Days Since Last'), 'value' => 'VisitorInterest,getNumberOfVisitsByDaysSinceLast'],
84					['text' => tra('Visitor Setting - Screen resolution'), 'value' => 'Resolution,getResolution'],
85				],
86			],
87
88			'period' => [
89				'required' => false,
90				'name' => tra('Statistics period'),
91				'description' => tr('Data display duration. If range is selected you must enter the start and end the date.'),
92				'since' => '15',
93				'default' => 'day',
94				'options' => [
95					['text' => tra('Day'), 'value' => 'day'],
96					['text' => tra('Week'), 'value' => 'week'],
97					['text' => tra('Month'), 'value' => 'month'],
98					['text' => tra('Year'), 'value' => 'year'],
99					['text' => tra('Range'), 'value' => 'range'],
100				],
101			],
102
103			'date' => [
104				'required' => false,
105				'name' => tra('Date or Start date'),
106				'description' => tr('Enter date or start date for the data to be displayed (yesterday by default). Possible values are: today, yesterday, and yyyy-mm-dd.'),
107				'since' => '15',
108				'default' => 'yesterday',
109			],
110
111			'enddate' => [
112				'required' => false,
113				'name' => tra('End date'),
114				'description' => tr('Enter end date (format yyyy-mm-dd) for the data to be displayed (only if range period is selected).'),
115				'since' => '15',
116				'default' => '',
117			],
118
119			'_width' => [
120				'required' => false,
121				'name' => tra('Module width'),
122				'description' => tr('Optional, width of the module in px or % (100% by default).'),
123				'since' => '15',
124				'default' => '100%',
125			],
126
127			'_height' => [
128				'required' => false,
129				'name' => tra('Module height'),
130				'description' => tr('Optional, height of the module in px.'), // Would be nice to have this as auto - checking if number of rows is applicable.
131				'since' => '15',
132				'default' => '265',
133			],
134
135			'_scrolling' => [
136				'required' => false,
137				'name' => tra('Iframe Scrolling'),
138				'description' => tr('Optional, scrolling of the iframe that contain the module (no by default).'),
139				'since' => '15',
140				'default' => 'no',
141				'options' => [
142					['text' => tra('No'), 'value' => 'no'],
143					['text' => tra('Yes'), 'value' => 'yes'],
144				],
145			],
146			'code' => [
147				'required' => true,
148				'name' => tra('Piwik javascript code'),
149				'description' => tr('Piwik JavaScript tracking code'),
150				'filter' => 'none',
151				'default' => ''
152			],
153			'group_option' => [
154				'required' => true,
155				'name' => tra('Groups Option'),
156				'description' => tr('Define option for Piwik groups, include or exclude'),
157				'filter' => 'text',
158				'default' => ''
159			],
160			'groups' => [
161				'required' => true,
162				'name' => tra('Available Groups'),
163				'description' => tr('User groups for which piwik will be available'),
164				'default' => ''
165			],
166		],
167	];
168}
169
170function wikiplugin_piwik($data, $params)
171{
172	global $prefs;
173
174	if (! empty($params['code'])) {
175		$showCode = WikiPlugin_Helper::showAnalyticsCode($params);
176		if ($showCode) {
177			return $params['code'];
178		}
179		return;
180	}
181
182	$plugininfo = wikiplugin_piwik_info();
183	$default = [];
184	foreach ($plugininfo['params'] as $key => $param) {
185		$default["$key"] = $param['default'];
186	}
187	$params = array_merge($default, $params);
188
189	if (empty($params['piwikserverurl'])) {
190		$params['piwikserverurl'] = $prefs['site_piwik_analytics_server_url'];
191	}
192
193	if (empty($params['piwikserverurl'])) {
194		return tra('Plugin Piwik error:') . ' ' . tra('Piwik server url is required.');
195	}
196
197	if (empty($params['idSite'])) {
198		$params['idSite'] = $prefs['site_piwik_site_id'];
199	}
200
201	if (empty($params['idSite'])) {
202		return tra('Plugin Piwik error:') . ' ' . tra('Site Id is required.');
203	}
204
205	if (empty($params['moduleToWidgetize'])) {
206		return tra('Plugin Piwik error:') . ' ' . tra('moduleToWidgetize is required.');
207	} else {
208		$arr = explode(',', $params['moduleToWidgetize']);
209
210		$params['moduleToWidgetize'] = $arr[0];
211		$params['actionToWidgetize'] = $arr[1];
212	}
213
214	if ($params['period'] === 'range') {
215		if ($params['enddate']) {
216			$params['date'] .= ',' . $params['enddate'];
217			unset($params['enddate']);
218		} else {
219			return tra('Plugin Piwik error:') . ' ' . tra('Period set to range but no end date provided.');
220		}
221	}
222
223	// grab out the params that aren't going to be part of the url, they will be iframe attributes and start with an underscore
224	$attributes = '';
225
226	foreach ($params as $key => $value) {
227		if (strpos($key, '_') === 0) {
228			if ($value) {
229				$attributes .= ' ' . substr($key, 1) . '="' . $value . '"';
230			}
231			unset($params[$key]);
232		}
233	}
234
235	// parse the main url param and unset it
236	$url_parts = parse_url($params['piwikserverurl']);
237	unset($params['piwikserverurl']);
238
239	// add the fixed query params
240	$params['module'] = 'Widgetize';
241	$params['action'] = 'iframe';
242	$params['disableLink'] = 1;
243	$params['widget=1'] = 1;
244
245	// parse the query part of the url into an array
246	parse_str($url_parts['query'], $query);
247
248	// merge the params and the fixed ones
249	$query = array_merge($params, $query);
250	// convert back to a string and replace in the parts array
251	$url_parts['query'] = http_build_query($query, '', '&amp;');
252
253	$url  = TikiLib::unparse_url($url_parts);
254
255	$iframe = ('<iframe src="' . $url . '" ' . $attributes . ' frameborder="0"></iframe>');
256
257	return $iframe;
258}
259