From 0dec1ada87b3ac5235d961fc19e2c16bd619ae31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Garc=C3=ADa?= Date: Thu, 6 Jun 2024 15:40:17 +0200 Subject: [PATCH] Analytics services integration (#7313) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Analytics services integration * Analytics services integration - add settings help * Analytics services integration - move configuration to config.properties * Analytics services integration - better name for web analytics service * Analytics improvements (#84) * Analytics services integration / Send events by protocol * Analytics services integration / Add example config for matomo. * Update web/src/main/webResources/WEB-INF/config.properties Co-authored-by: François Prunayre * Test / Fix bean initialization Failing test were: ``` 15:47:17,320 [INFO] Results: 15:47:17,320 [INFO] Error: 7,320 [ERROR] Failures: Error: 7,320 [ERROR] AlternateLogoForPdfExportTest.whenGeneratingPdfWithPropertyNotSetSiteLogoIsUsed:114 Status expected:<200> but was:<400> Error: 7,321 [ERROR] AlternateLogoForPdfExportTest.whenGeneratingPdfWithPropertySetPdfLogoIsUsed:74 Status expected:<200> but was:<400> Error: 7,321 [ERROR] AlternateLogoForPdfExportTest.whenNotGeneratingPdfWithPropertySetSiteLogoIsUsed:93 Status expected:<200> but was:<400> Error: 7,321 [ERROR] Errors: Error: 7,321 [ERROR] FormatterApiIntegrationTest.testExec:97 » XPath Exception in extension functio. ``` --------- Co-authored-by: François Prunayre Co-authored-by: Juan Luis Rodríguez Ponce --- .../analytics/WebAnalyticsConfiguration.java | 45 +++++++++++++++++++ .../java/org/fao/geonet/util/XslUtil.java | 15 +++++++ .../core-repository-test-context.xml | 5 +++ .../RelatedResourcesService.js | 10 ++++- .../components/utility/UtilityService.js | 18 ++++++++ .../resources/catalog/views/default/module.js | 11 +++++ .../WEB-INF/config-spring-geonetwork.xml | 6 +++ .../webResources/WEB-INF/config.properties | 8 ++++ .../webapp/xslt/base-layout-cssjs-loader.xsl | 16 +++++++ web/src/main/webapp/xslt/base-layout.xsl | 2 + .../main/webapp/xslt/common/render-html.xsl | 1 + 11 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 core/src/main/java/org/fao/geonet/analytics/WebAnalyticsConfiguration.java diff --git a/core/src/main/java/org/fao/geonet/analytics/WebAnalyticsConfiguration.java b/core/src/main/java/org/fao/geonet/analytics/WebAnalyticsConfiguration.java new file mode 100644 index 00000000000..d9c2799076e --- /dev/null +++ b/core/src/main/java/org/fao/geonet/analytics/WebAnalyticsConfiguration.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2001-2023 Food and Agriculture Organization of the + * United Nations (FAO-UN), United Nations World Food Programme (WFP) + * and United Nations Environment Programme (UNEP) + * + * This program 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 2 of the License, or (at + * your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + * Contact: Jeroen Ticheler - FAO - Viale delle Terme di Caracalla 2, + * Rome - Italy. email: geonetwork@osgeo.org + */ + +package org.fao.geonet.analytics; + +public class WebAnalyticsConfiguration { + private String service; + private String javascriptCode; + + public String getService() { + return service; + } + + public void setService(String service) { + this.service = service; + } + + public String getJavascriptCode() { + return javascriptCode; + } + + public void setJavascriptCode(String javascriptCode) { + this.javascriptCode = javascriptCode; + } +} diff --git a/core/src/main/java/org/fao/geonet/util/XslUtil.java b/core/src/main/java/org/fao/geonet/util/XslUtil.java index 4329d479afd..50bd7d1da87 100644 --- a/core/src/main/java/org/fao/geonet/util/XslUtil.java +++ b/core/src/main/java/org/fao/geonet/util/XslUtil.java @@ -47,6 +47,7 @@ import org.apache.http.impl.client.DefaultHttpClient; import org.fao.geonet.ApplicationContextHolder; import org.fao.geonet.SystemInfo; +import org.fao.geonet.analytics.WebAnalyticsConfiguration; import org.fao.geonet.api.records.attachments.FilesystemStore; import org.fao.geonet.api.records.attachments.FilesystemStoreResourceContainer; import org.fao.geonet.api.records.attachments.Store; @@ -1580,4 +1581,18 @@ private static List buildRecordLink(List hits, String type) { public static String escapeForJson(String value) { return StringEscapeUtils.escapeJson(value); } + + public static String getWebAnalyticsService() { + ApplicationContext applicationContext = ApplicationContextHolder.get(); + WebAnalyticsConfiguration webAnalyticsConfiguration = applicationContext.getBean(WebAnalyticsConfiguration.class); + + return webAnalyticsConfiguration.getService(); + } + + public static String getWebAnalyticsJavascriptCode() { + ApplicationContext applicationContext = ApplicationContextHolder.get(); + WebAnalyticsConfiguration webAnalyticsConfiguration = applicationContext.getBean(WebAnalyticsConfiguration.class); + + return webAnalyticsConfiguration.getJavascriptCode(); + } } diff --git a/core/src/test/resources/core-repository-test-context.xml b/core/src/test/resources/core-repository-test-context.xml index 7a42eee2535..c0ada088e3f 100644 --- a/core/src/test/resources/core-repository-test-context.xml +++ b/core/src/test/resources/core-repository-test-context.xml @@ -141,4 +141,9 @@ + + + + + diff --git a/web-ui/src/main/resources/catalog/components/metadataactions/RelatedResourcesService.js b/web-ui/src/main/resources/catalog/components/metadataactions/RelatedResourcesService.js index c2e03a96bb8..c5097337798 100644 --- a/web-ui/src/main/resources/catalog/components/metadataactions/RelatedResourcesService.js +++ b/web-ui/src/main/resources/catalog/components/metadataactions/RelatedResourcesService.js @@ -54,6 +54,7 @@ "$filter", "gnExternalViewer", "gnGlobalSettings", + "gnWebAnalyticsService", function ( gnMap, gnOwsCapabilities, @@ -68,7 +69,8 @@ gnConfig, $filter, gnExternalViewer, - gnGlobalSettings + gnGlobalSettings, + gnWebAnalyticsService ) { this.configure = function (options) { angular.extend(this.map, options); @@ -135,6 +137,7 @@ var addWFSToMap = function (link, md) { var url = $filter("gnLocalized")(link.url) || link.url; + gnWebAnalyticsService.trackLink(url, link.protocol); var isServiceLink = gnSearchSettings.mapProtocols.services.indexOf(link.protocol) > -1; @@ -211,6 +214,7 @@ function addMapToMap(record, md) { var url = $filter("gnLocalized")(record.url) || record.url; + gnWebAnalyticsService.trackLink(url, record.protocol); gnOwsContextService.loadContextFromUrl(url, gnSearchSettings.viewerMap); gnSearchLocation.setMap("legend"); @@ -250,8 +254,12 @@ var openLink = function (record, link) { var url = $filter("gnLocalized")(record.url) || record.url; if (url && angular.isString(url) && url.match("^(http|ftp|sftp|\\\\|//)")) { + gnWebAnalyticsService.trackLink(url, record.protocol); + return window.open(url, "_blank"); } else if (url && url.indexOf("www.") == 0) { + gnWebAnalyticsService.trackLink("http://" + url, record.protocol); + return window.open("http://" + url, "_blank"); } else if ( record.title && diff --git a/web-ui/src/main/resources/catalog/components/utility/UtilityService.js b/web-ui/src/main/resources/catalog/components/utility/UtilityService.js index bdd80c1f22b..65dcf00babd 100644 --- a/web-ui/src/main/resources/catalog/components/utility/UtilityService.js +++ b/web-ui/src/main/resources/catalog/components/utility/UtilityService.js @@ -922,6 +922,24 @@ } ]); + /** + * Service to track links in the web analytics service configured in GeoNetwork. + */ + module.service("gnWebAnalyticsService", [ + "gnGlobalSettings", + function (gnGlobalSettings) { + var analyticsService = gnGlobalSettings.webAnalyticsService; + + this.trackLink = function (url, linkType) { + // Implement track link for the analytics + if (analyticsService === "matomo") { + _paq.push(["trackLink", url, linkType]); + _paq.push(["trackEvent", "catalogue-actions", linkType, url]); + } + }; + } + ]); + module.filter("sanitizeHtmlFilter", [ "$filter", "$sanitize", diff --git a/web-ui/src/main/resources/catalog/views/default/module.js b/web-ui/src/main/resources/catalog/views/default/module.js index aec0512a243..b35cfab657f 100644 --- a/web-ui/src/main/resources/catalog/views/default/module.js +++ b/web-ui/src/main/resources/catalog/views/default/module.js @@ -145,6 +145,7 @@ "gnFacetSorter", "gnExternalViewer", "gnUrlUtils", + "gnWebAnalyticsService", "gnAlertService", function ( $scope, @@ -169,6 +170,7 @@ gnFacetSorter, gnExternalViewer, gnUrlUtils, + gnWebAnalyticsService, gnAlertService ) { var viewerMap = gnSearchSettings.viewerMap; @@ -421,6 +423,10 @@ $scope.resultviewFns = { addMdLayerToMap: function (link, md) { + var config = buildAddToMapConfig(link, md); + + gnWebAnalyticsService.trackLink(config.url, link.protocol); + // This is probably only a service // Open the add service layer tab var config = buildAddToMapConfig(link, md); @@ -442,6 +448,11 @@ if (config.length === 0) { return; } + + config.forEach(function (c) { + gnWebAnalyticsService.trackLink(c.url, c.type); + }); + $location.path("map").search({ add: encodeURIComponent(angular.toJson(config)) }); diff --git a/web/src/main/webResources/WEB-INF/config-spring-geonetwork.xml b/web/src/main/webResources/WEB-INF/config-spring-geonetwork.xml index 35ce16a7512..1d414a56bd5 100644 --- a/web/src/main/webResources/WEB-INF/config-spring-geonetwork.xml +++ b/web/src/main/webResources/WEB-INF/config-spring-geonetwork.xml @@ -316,4 +316,10 @@ The default publication options publishes the metadata to the ALL group and the INTRANET group. --> + + + + + + diff --git a/web/src/main/webResources/WEB-INF/config.properties b/web/src/main/webResources/WEB-INF/config.properties index 6e53082b1fe..6a623b39a77 100644 --- a/web/src/main/webResources/WEB-INF/config.properties +++ b/web/src/main/webResources/WEB-INF/config.properties @@ -68,4 +68,12 @@ metadata.extentApi.disableFullUrlBackgroundMapServices=true db.migration_onstartup=true +# Analytics service: (empty value: no analytics),matomo,google +analytics.web.service= +# Analytics javascript code to integrate with the analytics service (lines must be ended with \n\) +analytics.web.jscode= + +#analytics.web.service=matomo +#analytics.web.jscode=var _paq = _paq || [];_paq.push(['trackPageView']);_paq.push(['enableLinkTracking']);(function() {var u="//localhost/";_paq.push(['setTrackerUrl', u+'piwik.php']);_paq.push(['setSiteId', '1']);var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);})();var currentUrl = location.href; window.addEventListener('hashchange', function() {_paq.push(['setReferrerUrl', currentUrl]);currentUrl = window.location.href;_paq.push(['setCustomUrl', currentUrl]);_paq.push(['setDocumentTitle', currentUrl]);_paq.push(['deleteCustomVariables', 'page']);_paq.push(['trackPageView']);var content = document.getElementsByTagName('body')[0];_paq.push(['MediaAnalytics::scanForMedia', content]);_paq.push(['FormAnalytics::scanForForms', content]);_paq.push(['trackContentImpressionsWithinNode', content]);_paq.push(['enableLinkTracking']);}); + diff --git a/web/src/main/webapp/xslt/base-layout-cssjs-loader.xsl b/web/src/main/webapp/xslt/base-layout-cssjs-loader.xsl index faaa6c536b5..3f9bc30e761 100644 --- a/web/src/main/webapp/xslt/base-layout-cssjs-loader.xsl +++ b/web/src/main/webapp/xslt/base-layout-cssjs-loader.xsl @@ -246,6 +246,11 @@ @@ -313,4 +318,15 @@ //jQuery.migrateEnablePatches( "self-closed-tags" ); + + + + + + + + + diff --git a/web/src/main/webapp/xslt/base-layout.xsl b/web/src/main/webapp/xslt/base-layout.xsl index c9bed51d468..4e362bc04ba 100644 --- a/web/src/main/webapp/xslt/base-layout.xsl +++ b/web/src/main/webapp/xslt/base-layout.xsl @@ -128,6 +128,8 @@ + + diff --git a/web/src/main/webapp/xslt/common/render-html.xsl b/web/src/main/webapp/xslt/common/render-html.xsl index 4c6a3739109..e6ad329c106 100644 --- a/web/src/main/webapp/xslt/common/render-html.xsl +++ b/web/src/main/webapp/xslt/common/render-html.xsl @@ -98,6 +98,7 @@ +