diff --git a/package.json b/package.json
index 23e5543fa9..256f3e5009 100644
--- a/package.json
+++ b/package.json
@@ -108,7 +108,6 @@
"src/Backend/Core/Js/jquery/jquery.backend.js",
"src/Backend/Core/Js/jquery/jquery.ui.dialog.patch.js",
"src/Backend/Core/Js/utils.js",
- "src/Backend/Modules/Analytics/Js/Analytics.js",
"src/Backend/Modules/Blog/Js/Blog.js",
"src/Backend/Modules/Extensions/Js/Modules.js",
"src/Backend/Modules/Extensions/Js/ThemeTemplate.js",
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index d6e71bb043..9c1323a918 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -61,7 +61,6 @@
src/Frontend/Modules/Profiles/Tests/Actions
src/Frontend/Modules/Search/Tests/Actions
src/Frontend/Modules/Tags/Tests/Actions
- src/Backend/Modules/Analytics/Tests/Actions
src/Backend/Modules/Authentication/Tests/Actions
src/Backend/Modules/Blog/Tests/Actions
src/Backend/Modules/ContentBlocks/Tests/Actions
diff --git a/src/Backend/Core/Installer/Data/locale.xml b/src/Backend/Core/Installer/Data/locale.xml
index dc1f961a32..919eb6c827 100644
--- a/src/Backend/Core/Installer/Data/locale.xml
+++ b/src/Backend/Core/Installer/Data/locale.xml
@@ -4836,24 +4836,6 @@
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Backend/Core/Js/backend.js b/src/Backend/Core/Js/backend.js
index 820f16b986..bda7c2529e 100644
--- a/src/Backend/Core/Js/backend.js
+++ b/src/Backend/Core/Js/backend.js
@@ -2045,10 +2045,6 @@ jsBackend.resizeFunctions = {
calculate = (function (_this) {
return function () {
jsBackend.navigation.resize()
- if (typeof jsBackend.analytics !== 'undefined') {
- jsBackend.analytics.chartDoubleMetricPerDay.init()
- jsBackend.analytics.chartPieChart.init()
- }
ticking = false
}
})(this)
diff --git a/src/Backend/Modules/Analytics/Actions/Index.php b/src/Backend/Modules/Analytics/Actions/Index.php
deleted file mode 100644
index 1ed8c1d81f..0000000000
--- a/src/Backend/Modules/Analytics/Actions/Index.php
+++ /dev/null
@@ -1,85 +0,0 @@
-dateRange = new DateRange();
-
- $this->handleDateRangeForm();
- $this->parse();
- $this->display();
- }
-
- /**
- * The form will update the date range filter if needed
- */
- private function handleDateRangeForm(): void
- {
- $dateRangeForm = new DateRangeType('date_range', $this->dateRange);
-
- if ($dateRangeForm->handle()) {
- $this->dateRange = $dateRangeForm->getDateRange();
- }
-
- $dateRangeForm->parse($this->template);
- }
-
- protected function parse(): void
- {
- parent::parse();
-
- // if we don't have a token anymore, redirect to the settings page
- if ($this->get('fork.settings')->get($this->getModule(), 'certificate') === null
- || $this->get('fork.settings')->get($this->getModule(), 'account') === null
- || $this->get('fork.settings')->get($this->getModule(), 'web_property_id') === null
- || $this->get('fork.settings')->get($this->getModule(), 'profile') === null
- ) {
- $this->redirect(Model::createUrlForAction('Settings'));
- }
-
- $this->header->addJS('highcharts.js', 'Core', false);
- $analytics = $this->get('analytics.connector');
- $analyticsTemplateToFunctionMap = [
- 'page_views' => 'getPageViews',
- 'visitors' => 'getVisitors',
- 'pages_per_visit' => 'getPagesPerVisit',
- 'time_on_site' => 'getTimeOnSite',
- 'new_sessions_percentage' => 'getNewSessionsPercentage',
- 'bounce_rate' => 'getBounceRate',
- 'visitors_graph_data' => 'getVisitorsGraphData',
- 'source_graph_data' => 'getSourceGraphData',
- ];
-
- foreach ($analyticsTemplateToFunctionMap as $templateVariableName => $functionName) {
- $this->template->assign(
- $templateVariableName,
- $analytics->$functionName($this->dateRange->getStartDate(), $this->dateRange->getEndDate())
- );
- }
-
- $dataGrid = new DataGridArray(
- $analytics->getMostVisitedPagesData($this->dateRange->getStartDate(), $this->dateRange->getEndDate())
- );
- $this->template->assign('dataGridMostViewedPages', $dataGrid->getContent());
- }
-}
diff --git a/src/Backend/Modules/Analytics/Actions/Reset.php b/src/Backend/Modules/Analytics/Actions/Reset.php
deleted file mode 100644
index 823356e4be..0000000000
--- a/src/Backend/Modules/Analytics/Actions/Reset.php
+++ /dev/null
@@ -1,25 +0,0 @@
-checkToken();
-
- $this->get('fork.settings')->delete($this->getModule(), 'certificate');
- $this->get('fork.settings')->delete($this->getModule(), 'email');
- $this->get('fork.settings')->delete($this->getModule(), 'account');
- $this->get('fork.settings')->delete($this->getModule(), 'web_property_id');
- $this->get('fork.settings')->delete($this->getModule(), 'profile');
-
- $this->redirect(Model::createUrlForAction('Settings'));
- }
-}
diff --git a/src/Backend/Modules/Analytics/Actions/Settings.php b/src/Backend/Modules/Analytics/Actions/Settings.php
deleted file mode 100644
index 1d7b154dd8..0000000000
--- a/src/Backend/Modules/Analytics/Actions/Settings.php
+++ /dev/null
@@ -1,45 +0,0 @@
-get('fork.settings'),
- $this->get('analytics.google_analytics_service')
- );
-
- if ($settingsForm->handle()) {
- $this->redirect(Model::createUrlForAction('Settings'));
- }
- $settingsForm->parse($this->template);
-
- if ($this->get('fork.settings')->get($this->getModule(), 'web_property_id')) {
- $this->template->assign(
- 'web_property_id',
- $this->get('fork.settings')->get($this->getModule(), 'web_property_id')
- );
- }
- if ($this->get('fork.settings')->get($this->getModule(), 'profile')) {
- $this->template->assign(
- 'profile',
- $this->get('fork.settings')->get($this->getModule(), 'profile')
- );
- }
-
- $this->display();
- }
-}
diff --git a/src/Backend/Modules/Analytics/Config.php b/src/Backend/Modules/Analytics/Config.php
deleted file mode 100644
index 446f1686c9..0000000000
--- a/src/Backend/Modules/Analytics/Config.php
+++ /dev/null
@@ -1,12 +0,0 @@
-startDate = strtotime('-1 week', mktime(0, 0, 0));
- $this->endDate = mktime(0, 0, 0);
- }
-
- public function update(int $startDate, int $endDate): void
- {
- $this->startDate = $startDate;
- $this->endDate = $endDate;
- }
-
- public function getStartDate(): int
- {
- return $this->startDate;
- }
-
- public function getEndDate(): int
- {
- return $this->endDate;
- }
-}
diff --git a/src/Backend/Modules/Analytics/DependencyInjection/AnalyticsExtension.php b/src/Backend/Modules/Analytics/DependencyInjection/AnalyticsExtension.php
deleted file mode 100644
index 8c8f7b2926..0000000000
--- a/src/Backend/Modules/Analytics/DependencyInjection/AnalyticsExtension.php
+++ /dev/null
@@ -1,22 +0,0 @@
-load('services.yml');
- }
-}
diff --git a/src/Backend/Modules/Analytics/Form/DateRangeType.php b/src/Backend/Modules/Analytics/Form/DateRangeType.php
deleted file mode 100644
index 152fac1582..0000000000
--- a/src/Backend/Modules/Analytics/Form/DateRangeType.php
+++ /dev/null
@@ -1,110 +0,0 @@
-form = new Form($name);
-
- $this->build();
- }
-
- public function parse(TwigTemplate $template): void
- {
- $this->form->parse($template);
- $template->assign('startTimestamp', $this->dateRange->getStartDate());
- $template->assign('endTimestamp', $this->dateRange->getEndDate());
- }
-
- public function handle(): bool
- {
- $this->form->cleanupFields();
-
- if (!$this->form->isSubmitted() || !$this->isValid()) {
- return false;
- }
-
- $fields = $this->form->getFields();
-
- $newStartDate = Model::getUTCTimestamp($fields['start_date']);
- $newEndDate = Model::getUTCTimestamp($fields['end_date']);
-
- $this->dateRange->update($newStartDate, $newEndDate);
-
- return true;
- }
-
- private function build(): void
- {
- $this->form->addDate(
- 'start_date',
- $this->dateRange->getStartDate(),
- 'range',
- mktime(0, 0, 0, 1, 1, 2005),
- time()
- );
- $this->form->addDate(
- 'end_date',
- $this->dateRange->getEndDate(),
- 'range',
- mktime(0, 0, 0, 1, 1, 2005),
- time()
- );
- }
-
- private function isValid(): bool
- {
- $fields = $this->form->getFields();
-
- if (!$fields['start_date']->isFilled(Language::err('FieldIsRequired')) ||
- !$fields['end_date']->isFilled(Language::err('FieldIsRequired'))
- ) {
- return $this->form->isCorrect();
- }
-
- if (!$fields['start_date']->isValid(Language::err('DateIsInvalid')) ||
- !$fields['end_date']->isValid(Language::err('DateIsInvalid'))
- ) {
- return $this->form->isCorrect();
- }
-
- $newStartDate = Model::getUTCTimestamp($fields['start_date']);
- $newEndDate = Model::getUTCTimestamp($fields['end_date']);
-
- // startdate cannot be before 2005 (earliest valid google startdate)
- if ($newStartDate < mktime(0, 0, 0, 1, 1, 2005)) {
- $fields['start_date']->setError(Language::err('DateRangeIsInvalid'));
- }
-
- // enddate cannot be in the future
- if ($newEndDate > time()) {
- $fields['start_date']->setError(Language::err('DateRangeIsInvalid'));
- }
-
- // enddate cannot be before the startdate
- if ($newStartDate > $newEndDate) {
- $fields['start_date']->setError(Language::err('DateRangeIsInvalid'));
- }
-
- return $this->form->isCorrect();
- }
-
- public function getDateRange(): DateRange
- {
- return $this->dateRange;
- }
-}
diff --git a/src/Backend/Modules/Analytics/Form/SettingsStepAccountTypeInterface.php b/src/Backend/Modules/Analytics/Form/SettingsStepAccountTypeInterface.php
deleted file mode 100644
index 480171d0bd..0000000000
--- a/src/Backend/Modules/Analytics/Form/SettingsStepAccountTypeInterface.php
+++ /dev/null
@@ -1,85 +0,0 @@
-form = new Form($name);
-
- $this->build();
- }
-
- public function parse(TwigTemplate $template): void
- {
- if (!$this->hasAccounts) {
- $template->assign('email', $this->settings->get('Analytics', 'email'));
- $template->assign('noAccounts', true);
- }
-
- $this->form->parse($template);
- }
-
- public function handle(): bool
- {
- $this->form->cleanupFields();
-
- if (!$this->form->isSubmitted() || !$this->isValid()) {
- return false;
- }
-
- $this->settings->set(
- 'Analytics',
- 'account',
- $this->form->getField('account')->getValue()
- );
-
- return true;
- }
-
- private function build(): void
- {
- try {
- $accounts = $this->googleServiceAnalytics->management_accounts->listManagementAccounts();
- } catch (Google_Service_Exception) {
- $this->hasAccounts = false;
-
- return;
- }
-
- $accountsForDropDown = [];
- foreach ($accounts->getItems() as $account) {
- $accountsForDropDown[$account->getId()] = $account->getName();
- }
- $this->form->addDropdown('account', $accountsForDropDown);
-
- $this->hasAccounts = true;
- }
-
- private function isValid(): bool
- {
- $this->form->getField('account')->isFilled(Language::err('FieldIsRequired'));
-
- return $this->form->isCorrect();
- }
-}
diff --git a/src/Backend/Modules/Analytics/Form/SettingsStepAuthConfigFileTypeInterface.php b/src/Backend/Modules/Analytics/Form/SettingsStepAuthConfigFileTypeInterface.php
deleted file mode 100644
index b042d76fb1..0000000000
--- a/src/Backend/Modules/Analytics/Form/SettingsStepAuthConfigFileTypeInterface.php
+++ /dev/null
@@ -1,73 +0,0 @@
-form = new Form($name);
-
- $this->build();
- }
-
- public function parse(TwigTemplate $template): void
- {
- $this->form->parse($template);
- }
-
- public function handle(): bool
- {
- $this->form->cleanupFields();
-
- if (!$this->form->isSubmitted() || !$this->isValid()) {
- return false;
- }
-
- $certificate = base64_encode(file_get_contents($this->form->getField('certificate')->getTempFileName()));
-
- $this->settings->set(
- 'Analytics',
- 'certificate',
- $certificate
- );
- $this->settings->set(
- 'Analytics',
- 'email',
- $this->form->getField('email')->getValue()
- );
-
- return true;
- }
-
- private function build(): void
- {
- $this->form->addFile('certificate');
- $this->form->addText('email');
- }
-
- private function isValid(): bool
- {
- $fileField = $this->form->getField('certificate');
- $emailField = $this->form->getField('email');
-
- if ($fileField->isFilled(Language::err('FieldIsRequired'))) {
- $fileField->isAllowedExtension(['p12'], Language::err('P12Only'));
- }
- $emailField->isFilled(Language::err('FieldIsRequired'));
- $emailField->isEmail(Language::err('EmailIsInvalid'));
-
- return $this->form->isCorrect();
- }
-}
diff --git a/src/Backend/Modules/Analytics/Form/SettingsStepProfileTypeInterface.php b/src/Backend/Modules/Analytics/Form/SettingsStepProfileTypeInterface.php
deleted file mode 100644
index 4d67fa6ef7..0000000000
--- a/src/Backend/Modules/Analytics/Form/SettingsStepProfileTypeInterface.php
+++ /dev/null
@@ -1,71 +0,0 @@
-form = new Form($name);
-
- $this->build();
- }
-
- public function parse(TwigTemplate $template): void
- {
- $this->form->parse($template);
- }
-
- public function handle(): bool
- {
- $this->form->cleanupFields();
-
- if (!$this->form->isSubmitted() || !$this->isValid()) {
- return false;
- }
-
- $this->settings->set(
- 'Analytics',
- 'profile',
- $this->form->getField('profile')->getValue()
- );
-
- return true;
- }
-
- private function build(): void
- {
- $profiles = $this->googleServiceAnalytics->management_profiles->listManagementProfiles(
- $this->settings->get('Analytics', 'account'),
- $this->settings->get('Analytics', 'web_property_id')
- );
-
- $profilesForDropDown = [];
- foreach ($profiles->getItems() as $property) {
- $profilesForDropDown[$property->getId()] = $property->getName();
- }
- $this->form->addDropdown('profile', $profilesForDropDown);
- }
-
- private function isValid(): bool
- {
- $this->form->getField('profile')->isFilled(Language::err('FieldIsRequired'));
-
- return $this->form->isCorrect();
- }
-}
diff --git a/src/Backend/Modules/Analytics/Form/SettingsStepTypeInterface.php b/src/Backend/Modules/Analytics/Form/SettingsStepTypeInterface.php
deleted file mode 100644
index 4c2b31aab4..0000000000
--- a/src/Backend/Modules/Analytics/Form/SettingsStepTypeInterface.php
+++ /dev/null
@@ -1,15 +0,0 @@
-form = new Form($name);
-
- $this->build();
- }
-
- public function parse(TwigTemplate $template): void
- {
- $this->form->parse($template);
- }
-
- public function handle(): bool
- {
- $this->form->cleanupFields();
-
- if (!$this->form->isSubmitted() || !$this->isValid()) {
- return false;
- }
-
- $this->settings->set(
- 'Analytics',
- 'web_property_id',
- $this->form->getField('web_property_id')->getValue()
- );
-
- return true;
- }
-
- private function build(): void
- {
- $properties = $this->googleServiceAnalytics->management_webproperties->listManagementWebproperties(
- $this->settings->get('Analytics', 'account')
- );
-
- $propertiesForDropDown = [];
- foreach ($properties->getItems() as $property) {
- $propertiesForDropDown[$property->getId()] = $property->getName();
- }
- $this->form->addDropdown('web_property_id', $propertiesForDropDown);
- }
-
- private function isValid(): bool
- {
- $this->form->getField('web_property_id')->isFilled(Language::err('FieldIsRequired'));
-
- return $this->form->isCorrect();
- }
-}
diff --git a/src/Backend/Modules/Analytics/Form/SettingsType.php b/src/Backend/Modules/Analytics/Form/SettingsType.php
deleted file mode 100644
index ea6014e25a..0000000000
--- a/src/Backend/Modules/Analytics/Form/SettingsType.php
+++ /dev/null
@@ -1,67 +0,0 @@
-get('Analytics', 'certificate') === null) {
- $this->form = new SettingsStepAuthConfigFileTypeInterface($name, $settings);
-
- return;
- }
-
- // we are authenticated! Let's see which account the user wants to use
- if ($settings->get('Analytics', 'account') === null) {
- $this->form = new SettingsStepAccountTypeInterface($name, $settings, $googleServiceAnalytics);
-
- return;
- }
-
- // we have an account, but don't know which property to track
- if ($settings->get('Analytics', 'web_property_id') === null) {
- $this->form = new SettingsStepWebPropertyTypeInterface($name, $settings, $googleServiceAnalytics);
-
- return;
- }
-
- // we have an account, but don't know which property to track
- if ($settings->get('Analytics', 'profile') === null) {
- $this->form = new SettingsStepProfileTypeInterface($name, $settings, $googleServiceAnalytics);
-
- return;
- }
-
- $this->form = new Form($name);
- }
-
- public function parse(TwigTemplate $template): void
- {
- $this->form->parse($template);
- }
-
- public function handle(): bool
- {
- if ($this->form instanceof Form) {
- return false;
- }
-
- return $this->form->handle();
- }
-}
diff --git a/src/Backend/Modules/Analytics/GoogleClient/ClientFactory.php b/src/Backend/Modules/Analytics/GoogleClient/ClientFactory.php
deleted file mode 100644
index 239ba10cb5..0000000000
--- a/src/Backend/Modules/Analytics/GoogleClient/ClientFactory.php
+++ /dev/null
@@ -1,47 +0,0 @@
-setClassConfig(Google_Cache_File::class, ['directory' => $this->cacheDir]);
- $client = new Google_Client($config);
-
- // set assertion credentials
- $client->setAssertionCredentials(
- new Google_Auth_AssertionCredentials(
- $this->settings->get('Analytics', 'email'),
- ['https://www.googleapis.com/auth/analytics.readonly'],
- base64_decode((string) $this->settings->get('Analytics', 'certificate'))
- )
- );
-
- $client->setAccessType('offline_access');
-
- return $client;
- }
-
- public function createAnalyticsService(): Google_Service_Analytics
- {
- return new Google_Service_Analytics($this->createClient());
- }
-}
diff --git a/src/Backend/Modules/Analytics/GoogleClient/Connector.php b/src/Backend/Modules/Analytics/GoogleClient/Connector.php
deleted file mode 100644
index e57cf49565..0000000000
--- a/src/Backend/Modules/Analytics/GoogleClient/Connector.php
+++ /dev/null
@@ -1,336 +0,0 @@
-getData($startDate, $endDate);
-
- return $results['metrics']['ga:pageviews'];
- }
-
- /**
- * Returns the amount of visitors in a period
- *
- * @param int $startDate
- * @param int $endDate
- *
- * @return int
- */
- public function getVisitors(int $startDate, int $endDate): int
- {
- $results = $this->getData($startDate, $endDate);
-
- return $results['metrics']['ga:users'];
- }
-
- /**
- * Returns the amount of pages per visit in a period
- *
- * @param int $startDate
- * @param int $endDate
- *
- * @return float
- */
- public function getPagesPerVisit(int $startDate, int $endDate): float
- {
- $results = $this->getData($startDate, $endDate);
-
- return $results['metrics']['ga:pageviewsPerSession'];
- }
-
- /**
- * Returns the average time on the site in a certain period
- *
- * @param int $startDate
- * @param int $endDate
- *
- * @return float
- */
- public function getTimeOnSite(int $startDate, int $endDate): float
- {
- $results = $this->getData($startDate, $endDate);
-
- return $results['metrics']['ga:avgSessionDuration'];
- }
-
- /**
- * Returns the percentage of new sessions in a certain period
- *
- * @param int $startDate
- * @param int $endDate
- *
- * @return float
- */
- public function getNewSessionsPercentage(int $startDate, int $endDate): float
- {
- $results = $this->getData($startDate, $endDate);
-
- return $results['metrics']['ga:percentNewSessions'];
- }
-
- /**
- * Returns the bounce rate in a certain period
- *
- * @param int $startDate
- * @param int $endDate
- *
- * @return float
- */
- public function getBounceRate(int $startDate, int $endDate): float
- {
- $results = $this->getData($startDate, $endDate);
-
- return $results['metrics']['ga:bounceRate'];
- }
-
- /**
- * Returns the visitors graph data
- *
- * @param int $startDate
- * @param int $endDate
- *
- * @return array
- */
- public function getVisitorsGraphData(int $startDate, int $endDate): array
- {
- $results = $this->getData($startDate, $endDate);
-
- return $results['visitGraphData'];
- }
-
- /**
- * Returns the source graph data
- *
- * @param int $startDate
- * @param int $endDate
- *
- * @return array
- */
- public function getSourceGraphData(int $startDate, int $endDate): array
- {
- $results = $this->getData($startDate, $endDate);
-
- return $results['sourceGraphData'];
- }
-
- /**
- * Returns the source graph data
- *
- * @param int $startDate
- * @param int $endDate
- *
- * @return array
- */
- public function getMostVisitedPagesData(int $startDate, int $endDate): array
- {
- $results = $this->getData($startDate, $endDate);
-
- return $results['pageViews'];
- }
-
- /**
- * Fetches all the needed data and caches it in our statistics array
- *
- * @param int $startDate
- * @param int $endDate
- *
- * @return array
- */
- private function getData(int $startDate, int $endDate): array
- {
- $dateRange = $startDate . '-' . $endDate;
-
- $item = $this->cache->getItem('analytics-' . $dateRange);
- if ($item->isHit()) {
- return $item->get();
- }
-
- $data = [
- 'metrics' => $this->getMetrics($startDate, $endDate),
- 'visitGraphData' => $this->collectVisitGraphData($startDate, $endDate),
- 'pageViews' => $this->collectMostVisitedPagesData($startDate, $endDate),
- 'sourceGraphData' => $this->collectSourceGraphData($startDate, $endDate),
- ];
-
- $item->set($data);
- $this->cache->save($item);
-
- return $data;
- }
-
- /**
- * Fetches some metrics for a certain date range
- *
- * @param int $startDate
- * @param int $endDate
- *
- * @return array
- */
- private function getMetrics(int $startDate, int $endDate): array
- {
- return $this->getAnalyticsData(
- $startDate,
- $endDate,
- 'ga:pageviews,ga:users,ga:pageviewsPerSession,ga:avgSessionDuration,ga:percentNewSessions,ga:bounceRate'
- )->getTotalsForAllResults();
- }
-
- /**
- * Fetches the data needed to build the visitors graph for a date range
- *
- * @param int $startDate
- * @param int $endDate
- *
- * @return array
- */
- private function collectVisitGraphData(int $startDate, int $endDate): array
- {
- $visitGraphData = $this->getAnalyticsData(
- $startDate,
- $endDate,
- 'ga:pageviews,ga:users',
- [
- 'dimensions' => 'ga:date',
- 'sort' => 'ga:date',
- ]
- );
-
- // make sure our column headers are the metric names, not just numbers
- $namedRows = [];
- foreach ((array) $visitGraphData->getRows() as $dataRow) {
- $namedRow = [];
- foreach ($dataRow as $key => $value) {
- $headerName = $visitGraphData->getColumnHeaders()[$key]['name'];
-
- // convert the date to a timestamp
- if ($headerName === 'ga:date') {
- $value = \DateTime::createFromFormat('Ymd H:i:s', $value . ' 00:00:00')->format('U');
- }
- $namedRow[str_replace(':', '_', $headerName)] = $value;
- }
- $namedRows[] = $namedRow;
- }
-
- return $namedRows;
- }
-
- /**
- * Fetches the data needed to build the source graph for a date range
- *
- * @param int $startDate
- * @param int $endDate
- *
- * @return array
- */
- private function collectSourceGraphData(int $startDate, int $endDate): array
- {
- $sourceGraphData = $this->getAnalyticsData(
- $startDate,
- $endDate,
- 'ga:pageviews',
- [
- 'dimensions' => 'ga:medium',
- 'sort' => '-ga:pageviews',
- ]
- );
-
- // make sure our column headers are the metric names, not just numbers
- $namedRows = [];
- foreach ((array) $sourceGraphData->getRows() as $dataRow) {
- $namedRow = [];
- foreach ($dataRow as $key => $value) {
- $headerName = $sourceGraphData->getColumnHeaders()[$key]['name'];
- $namedRow[str_replace(':', '_', $headerName)] = $value;
- }
- $namedRows[] = $namedRow;
- }
-
- return $namedRows;
- }
-
- /**
- * Fetches the data needed to build the list with most visited pages
- *
- * @param int $startDate
- * @param int $endDate
- *
- * @return array
- */
- private function collectMostVisitedPagesData(int $startDate, int $endDate): array
- {
- $sourceGraphData = $this->getAnalyticsData(
- $startDate,
- $endDate,
- 'ga:pageviews',
- [
- 'dimensions' => 'ga:pagePath',
- 'sort' => '-ga:pageviews',
- 'max-results' => 20,
- ]
- );
-
- // make sure our column headers are the metric names, not just numbers
- $namedRows = [];
- foreach ((array) $sourceGraphData->getRows() as $dataRow) {
- $namedRow = [];
- foreach ($dataRow as $key => $value) {
- $headerName = $sourceGraphData->getColumnHeaders()[$key]['name'];
- $namedRow[str_replace(':', '_', $headerName)] = $value;
- }
- $namedRows[] = $namedRow;
- }
-
- return $namedRows;
- }
-
- /**
- * Returns Analytics data for our coupled profile
- *
- * @param int $startDate
- * @param int $endDate
- * @param string $metrics A comma-separated list of Analytics metrics.
- * @param array $optParams Optional parameters.
- *
- * @return Google_Service_Analytics_GaData
- */
- private function getAnalyticsData(
- int $startDate,
- int $endDate,
- string $metrics,
- array $optParams = []
- ): Google_Service_Analytics_GaData {
- return $this->analytics->data_ga->get(
- 'ga:' . $this->settings->get('Analytics', 'profile'),
- date('Y-m-d', $startDate),
- date('Y-m-d', $endDate),
- $metrics,
- $optParams
- );
- }
-}
diff --git a/src/Backend/Modules/Analytics/Installer/Data/locale.xml b/src/Backend/Modules/Analytics/Installer/Data/locale.xml
deleted file mode 100644
index aa59c62fc8..0000000000
--- a/src/Backend/Modules/Analytics/Installer/Data/locale.xml
+++ /dev/null
@@ -1,313 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
- Hoe verkrijg je je secret file?
-
- De Analytics API inschakelen
-
-
- - Ga naar de Google Developers Console.
- - Zorg dat je aangemeld bent met een Google account die toegang heeft op de gewenste analytics account.
- - Kies een project in de header of maak een nieuw aan.
- - Klik op Bibliotheek in de zijbalk.
- - Ga naar de Analytics API door er op te klikken in de Andere populaire API's categorie of door het te typen in de zoekbalk.
- - Als je de API nog niet geactiveerd hebt kan je dit doen door onder de header op INSCHAKELEN te klikken.
-
-
- Toegangsgegevens aanmaken voor Fork CMS.
-
-
- - Kies in de zijbalk aan de linkerkant Inloggegevens.
- - Klik op Inloggegevens maken en kies Serviceaccountsleutel in de dropdown.
- - Maak een nieuw serviceaccount aan met de rol Project - Editor en P12 als type sleutel.
- - Download na het opslaan het gegenereerde certificaat (p12 file).
- - Ga terug naar de Inloggegevens pagina en klik op Serviceaccounts beheren.
- - Kopieer de Serviceaccount-ID van de net aangemaakte account. Het zou er ongeveer als volgt moeten uitzien
name@spheric-passkey-123456.iam.gserviceaccount.com
- - Log in in Google Analytics, ga naar het beheerder onderdeel en voeg het gegenereerde e-mail adres toe bij de gewenste property en geef deze "lezen en analyseren" rechten.
- - Haal een kop koffie, en kom daarna terug. Het kan even duren voor de koppeling tot stand is gekomen.
-
- ]]>
- How to get your secret file?
-
- Enable the Analytics API
-
-
- - Go to the Google Developers Console.
- - Make sure you're logged in with a Google account that has access to the wanted Analytics account.
- - Select a project in the header, or create a new one.
- - Click on Library in the sidebar on the left.
- - Go to the Analytics API page by clicking on it in the Other popular API's category or typing it in the search bar.
- - You can enable the API if you haven't done that yet by clicking on ENABLE API underneath the header.
-
-
- Creating credentials for Fork CMS.
-
-
- - In the sidebar on the left, select Credentials.
- - Click on Create credentials and select Service account key in the dropdown.
- - Create a new service account with the role Project - Editor and P12 as Key type.
- - Download the generated certificate (.p12 file).
- - Go back to the Credentials page and click on Manage service accounts
- - Copy the Service account ID of the newly created account. It should look something like
name@spheric-passkey-123456.iam.gserviceaccount.com
- - Login to analytics, go to admin page and add the generated e-mail adress to the prefered property with "read and analyze" rights.
- - Grab a cup of coffee, and come back to Fork in some minutes. It can take some time before the coupling is fully done.
-
- ]]>
-
-
- -
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Backend/Modules/Analytics/Installer/Installer.php b/src/Backend/Modules/Analytics/Installer/Installer.php
deleted file mode 100644
index 65d94d77f8..0000000000
--- a/src/Backend/Modules/Analytics/Installer/Installer.php
+++ /dev/null
@@ -1,47 +0,0 @@
-addModule('Analytics');
- $this->importLocale(__DIR__ . '/Data/locale.xml');
- $this->configureBackendNavigation();
- $this->configureBackendRights();
- $this->configureBackendWidgets();
- }
-
- private function configureBackendNavigation(): void
- {
- // Set navigation for "Modules"
- $navigationMarketingId = $this->setNavigation(null, 'Marketing', 'analytics/index', null, 4);
- $this->setNavigation($navigationMarketingId, 'Analytics', 'analytics/index');
-
- // Set navigation for "Settings"
- $navigationSettingsId = $this->setNavigation(null, 'Settings');
- $navigationModulesId = $this->setNavigation($navigationSettingsId, 'Modules');
- $this->setNavigation($navigationModulesId, $this->getModule(), 'analytics/settings');
- }
-
- private function configureBackendRights(): void
- {
- $this->setModuleRights(1, $this->getModule());
-
- $this->setActionRights(1, $this->getModule(), 'Index');
- $this->setActionRights(1, $this->getModule(), 'Settings');
- $this->setActionRights(1, $this->getModule(), 'Reset');
- }
-
- private function configureBackendWidgets(): void
- {
- $this->insertDashboardWidget('Analytics', 'RecentVisits');
- $this->insertDashboardWidget('Analytics', 'TraficSources');
- }
-}
diff --git a/src/Backend/Modules/Analytics/Js/Analytics.js b/src/Backend/Modules/Analytics/Js/Analytics.js
deleted file mode 100644
index f72590d7ba..0000000000
--- a/src/Backend/Modules/Analytics/Js/Analytics.js
+++ /dev/null
@@ -1,190 +0,0 @@
-/**
- * Interaction for the analytics module
- */
-/* global Highcharts */
-jsBackend.analytics = {
- $chartPieChart: null,
- $chartDoubleMetricPerDay: null
-}
-
-jsBackend.analytics.charts = {
- init: function () {
- jsBackend.analytics.$chartPieChart = $('#chartPieChart')
- jsBackend.analytics.$chartDoubleMetricPerDay = $('#chartDoubleMetricPerDay')
-
- if (jsBackend.analytics.$chartPieChart.length > 0 || jsBackend.analytics.$chartDoubleMetricPerDay.length > 0) {
- Highcharts.setOptions({
- colors: ['#2f77d1', '#021b45', '#ED561B', '#EDEF00', '#24CBE5', '#64E572', '#FF9655'],
- title: {text: ''},
- legend: {
- layout: 'vertical',
- borderWidth: 0,
- shadow: false,
- symbolPadding: 12,
- symbolWidth: 10,
- itemStyle: {cursor: 'pointer', color: '#000', lineHeight: '18px'},
- itemHoverStyle: {color: '#666'}
- }
- })
- }
-
- jsBackend.analytics.chartPieChart.init()
- jsBackend.analytics.chartDoubleMetricPerDay.init()
- }
-}
-
-jsBackend.analytics.chartPieChart = {
- chart: '',
-
- init: function () {
- if (jsBackend.analytics.$chartPieChart.length > 0) { jsBackend.analytics.chartPieChart.create() }
- },
-
- // add new chart
- create: function () {
- // variables
- var $pieChartValues = $('#dataChartPieChart ul.data li')
- var pieChartData = []
-
- $pieChartValues.each(function () {
- // variables
- var $this = $(this)
-
- pieChartData.push({
- name: $this.children('span.label').html(),
- y: parseInt($this.children('span.value').html()),
- percentage: parseInt($this.children('span.percentage').html())
- })
- })
-
- var containerWidth = jsBackend.analytics.$chartPieChart.width()
-
- jsBackend.analytics.chartPieChart.chart = new Highcharts.Chart({
- chart: {
- renderTo: 'chartPieChart',
- height: 200,
- width: containerWidth,
- margin: [0, 160, 0, 0],
- backgroundColor: 'transparent'
- },
- credits: {enabled: false},
- plotArea: {shadow: null, borderWidth: null, backgroundColor: null},
- tooltip: {
- formatter: function () {
- var percentage = String(this.point.percentage)
- return '' + this.point.name + ': ' + this.y + ' (' + percentage.substring(0, $.inArray('.', percentage) + 3) + '%)'
- },
- borderWidth: 2,
- shadow: false
- },
- plotOptions: {
- pie: {
- allowPointSelect: true,
- dataLabels: {
- enabled: false
- },
- showInLegend: true
- }
- },
- legend: {align: 'right'},
- series: [{type: 'pie', data: pieChartData}]
- })
- },
-
- // destroy chart
- destroy: function () {
- jsBackend.analytics.chartPieChart.chart.destroy()
- }
-}
-
-jsBackend.analytics.chartDoubleMetricPerDay = {
- chart: '',
-
- init: function () {
- if (jsBackend.analytics.$chartDoubleMetricPerDay.length > 0) { jsBackend.analytics.chartDoubleMetricPerDay.create() }
- },
-
- // add new chart
- create: function () {
- var xAxisItems = $('#dataChartDoubleMetricPerDay ul.series li.serie:first-child ul.data li')
- var xAxisValues = []
- var xAxisCategories = []
- var counter = 0
- var interval = Math.ceil(xAxisItems.length / 10)
-
- xAxisItems.each(function () {
- xAxisValues.push($(this).children('span.fulldate').html())
- var text = $(this).children('span.date').html()
- if (xAxisItems.length > 10 && counter % interval > 0) text = ' '
- xAxisCategories.push(text)
- counter++
- })
-
- var maxValue = 0
- var metric1Name = $('#dataChartDoubleMetricPerDay ul.series li#metric1serie span.name').html()
- var metric1Values = $('#dataChartDoubleMetricPerDay ul.series li#metric1serie span.value')
- var metric1Data = []
-
- metric1Values.each(function () {
- metric1Data.push(parseInt($(this).html()))
- if (parseInt($(this).html()) > maxValue) {
- maxValue = parseInt($(this).html())
- }
- })
-
- var metric2Name = $('#dataChartDoubleMetricPerDay ul.series li#metric2serie span.name').html()
- var metric2Values = $('#dataChartDoubleMetricPerDay ul.series li#metric2serie span.value')
- var metric2Data = []
-
- metric2Values.each(function () {
- metric2Data.push(parseInt($(this).html()))
- if (parseInt($(this).html()) > maxValue) {
- maxValue = parseInt($(this).html())
- }
- })
-
- var tickInterval = Math.ceil(maxValue / 5)
-
- var containerWidth = $('#chartDoubleMetricPerDay').width()
-
- jsBackend.analytics.chartDoubleMetricPerDay.chart = new Highcharts.Chart({
- chart: {
- renderTo: 'chartDoubleMetricPerDay',
- height: 200,
- width: containerWidth,
- margin: [60, 0, 30, 40],
- defaultSeriesType: 'line',
- backgroundColor: 'transparent'
- },
- xAxis: {lineColor: '#CCC', lineWidth: 1, categories: xAxisCategories, color: '#000'},
- yAxis: {min: 0, max: maxValue, tickInterval: tickInterval, title: {text: ''}},
- credits: {enabled: false},
- tooltip: {formatter: function () { return '' + this.series.name + '
' + xAxisValues[this.point.x] + ': ' + this.y }},
- plotOptions: {
- line: {
- marker: {
- enabled: false,
- states: {hover: {enabled: true, symbol: 'circle', radius: 5, lineWidth: 1}}
- }
- },
- area: {
- marker: {
- enabled: false,
- states: {hover: {enabled: true, symbol: 'circle', radius: 5, lineWidth: 1}}
- }
- },
- column: {pointPadding: 0.2, borderWidth: 0},
- series: {fillOpacity: 0.3}
- },
- series: [{name: metric1Name, data: metric1Data, type: 'area'}, {name: metric2Name, data: metric2Data}],
- legend: {layout: 'horizontal', verticalAlign: 'top'}
- })
- },
-
- // destroy chart
- destroy: function () {
- jsBackend.analytics.chartDoubleMetricPerDay.chart.destroy()
- }
-}
-
-$(jsBackend.analytics.charts.init)
diff --git a/src/Backend/Modules/Analytics/Layout/Templates/Index.html.twig b/src/Backend/Modules/Analytics/Layout/Templates/Index.html.twig
deleted file mode 100644
index 11d4b6e290..0000000000
--- a/src/Backend/Modules/Analytics/Layout/Templates/Index.html.twig
+++ /dev/null
@@ -1,138 +0,0 @@
-{% extends 'Layout/Templates/base.html.twig' %}
-
-{% block actionbar %}
-
-{% endblock %}
-
-{% block content %}
-
-
-
{{ 'lbl.Statistics'|trans|ucfirst }} {{ 'lbl.From'|trans }} {{ startTimestamp|date('m/d/Y') }} {{ 'lbl.Till'|trans }} {{ endTimestamp|date('m/d/Y') }}
-
-
-
- {% form date_range %}
-
- {% endform %}
-
-
-
-
-
-
{{ page_views }} {{ 'lbl.Pageviews'|trans|ucfirst }}
-
{{ visitors }} {{ 'lbl.Visitors'|trans|ucfirst }}
-
-
-
{{ pages_per_visit|formatfloat }} {{ 'lbl.PagesPerVisit'|trans|ucfirst }}
-
{{ time_on_site|formattime }} {{ 'lbl.AverageTimeOnSite'|trans|ucfirst }}
-
-
-
- {{ new_sessions_percentage|formatfloat }}% {{ 'lbl.NewVisitsPercentage'|trans|ucfirst }}
-
-
{{ bounce_rate|formatfloat }}% {{ 'lbl.BounceRate'|trans|ucfirst }}
-
-
-
-
-
-
-
-
-
-
-
{{ 'lbl.RecentVisits'|trans|ucfirst }}
-
-
- {% if visitors_graph_data %}
-
-
{{ maxYAxis }}
-
{{ tickInterval }}
-
{{ 'lbl.Visits'|trans|ucfirst }}
-
- -
- {{ 'lbl.Pageviews'|trans|ucfirst }}
-
- {% for visitor in visitors_graph_data %}
- -
- {{ visitor.ga_date|spoondate('D d M',INTERFACE_LANGUAGE|uppercase) }}
- {{ visitor.ga_date|spoondate('d M',INTERFACE_LANGUAGE|uppercase) }}
- {{ visitor.ga_pageviews }}
-
- {% endfor %}
-
-
- -
- {{ 'lbl.Visitors'|trans|ucfirst }}
-
- {% for visitor in visitors_graph_data %}
- -
- {{ visitor.ga_date|spoondate('D d M',INTERFACE_LANGUAGE|uppercase) }}
- {{ visitor.ga_date|spoondate('d M',INTERFACE_LANGUAGE|uppercase) }}
- {{ visitor.ga_users }}
-
- {% endfor %}
-
-
-
-
-
- {% endif %}
-
-
-
-
-
-
-
{{ 'lbl.PageviewsByTrafficSources'|trans|ucfirst }}
-
-
- {% if source_graph_data %}
-
-
- {% for source in source_graph_data %}
- -
- {{ source.ga_medium }}{{ source.ga_pageviews }}
-
- {% endfor %}
-
-
-
- {% endif %}
-
-
-
-
-
-
-
-
-
-
-
-
{{ 'lbl.MostViewedPages'|trans|ucfirst }}
-
-
-
- {{ dataGridMostViewedPages|raw }}
-
-
-
-
-
-
-{% endblock %}
diff --git a/src/Backend/Modules/Analytics/Layout/Templates/Settings.html.twig b/src/Backend/Modules/Analytics/Layout/Templates/Settings.html.twig
deleted file mode 100644
index ba5c5932e4..0000000000
--- a/src/Backend/Modules/Analytics/Layout/Templates/Settings.html.twig
+++ /dev/null
@@ -1,132 +0,0 @@
-{% extends 'Layout/Templates/base.html.twig' %}
-{% import "Layout/Templates/macros.html.twig" as macro %}
-
-{% block actionbar %}
-
-{% endblock %}
-
-{% block content %}
- {% if noAccounts %}
-
-
-
- {{ 'msg.NoAccounts'|trans|format(email)|raw }}
-
-
-
- {% endif %}
- {% form settings %}
- {% if fileCertificate %}
-
-
-
-
-
- {{ 'lbl.Certificate'|trans|ucfirst }}
-
-
-
-
-
-
- {% endif %}
- {% if ddmAccount %}
-
-
-
-
-
- {{ 'lbl.ChooseThisAccount'|trans|ucfirst }}
-
-
-
-
- {% form_field account %}
-
-
-
-
-
- {% endif %}
- {% if ddmWebPropertyId %}
-
-
-
-
-
- {{ 'lbl.ChooseWebsiteProfile'|trans|ucfirst }}
-
-
-
-
- {% form_field web_property_id %}
-
-
-
-
-
- {% endif %}
- {% if web_property_id %}
-
-
-
-
-
- {{ 'lbl.LinkedProfile'|trans|ucfirst }}
-
-
-
-
- {{ web_property_id }}{% if profile %}: ga:profile{% endif %}
-
-
-
-
-
- {% endif %}
- {% if ddmProfile %}
-
-
-
-
-
- {{ 'lbl.ChooseWebsiteProfile'|trans|ucfirst }}
-
-
-
-
- {% form_field profile %}
-
-
-
-
-
- {% endif %}
-
-
- {% endform %}
-{% endblock %}
diff --git a/src/Backend/Modules/Analytics/Layout/Widgets/RecentVisits.html.twig b/src/Backend/Modules/Analytics/Layout/Widgets/RecentVisits.html.twig
deleted file mode 100644
index 2bc963e5bb..0000000000
--- a/src/Backend/Modules/Analytics/Layout/Widgets/RecentVisits.html.twig
+++ /dev/null
@@ -1,48 +0,0 @@
-{% if visitors_graph_data %}
-
-{% endif %}
diff --git a/src/Backend/Modules/Analytics/Layout/Widgets/TraficSources.html.twig b/src/Backend/Modules/Analytics/Layout/Widgets/TraficSources.html.twig
deleted file mode 100644
index dfec71399c..0000000000
--- a/src/Backend/Modules/Analytics/Layout/Widgets/TraficSources.html.twig
+++ /dev/null
@@ -1,26 +0,0 @@
-{% if source_graph_data %}
-
-{% endif %}
diff --git a/src/Backend/Modules/Analytics/Resources/config/services.yml b/src/Backend/Modules/Analytics/Resources/config/services.yml
deleted file mode 100644
index 98512e2dcd..0000000000
--- a/src/Backend/Modules/Analytics/Resources/config/services.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-services:
- analytics.client_factory:
- class: Backend\Modules\Analytics\GoogleClient\ClientFactory
- arguments:
- - "@fork.settings"
- - "%kernel.cache_dir%"
-
- analytics.google_analytics_service:
- class: Google_Service_Analytics
- public: true
- factory: ["@analytics.client_factory",createAnalyticsService]
-
- analytics.google_client:
- class: Google_Client
- factory: ["@analytics.client_factory",createClient]
-
- analytics.connector:
- class: Backend\Modules\Analytics\GoogleClient\Connector
- public: true
- arguments:
- - "@analytics.google_analytics_service"
- - "@cache.pool"
- - "@fork.settings"
diff --git a/src/Backend/Modules/Analytics/Tests/Actions/IndexTest.php b/src/Backend/Modules/Analytics/Tests/Actions/IndexTest.php
deleted file mode 100644
index fc9609821d..0000000000
--- a/src/Backend/Modules/Analytics/Tests/Actions/IndexTest.php
+++ /dev/null
@@ -1,25 +0,0 @@
-login($client);
-
- self::assertGetsRedirected(
- $client,
- '/private/en/analytics/index',
- '/private/en/analytics/settings'
- );
- }
-}
diff --git a/src/Backend/Modules/Analytics/Tests/Actions/ResetTest.php b/src/Backend/Modules/Analytics/Tests/Actions/ResetTest.php
deleted file mode 100644
index 848e7d708c..0000000000
--- a/src/Backend/Modules/Analytics/Tests/Actions/ResetTest.php
+++ /dev/null
@@ -1,25 +0,0 @@
-login($client);
-
- self::assertGetsRedirected(
- $client,
- '/private/en/analytics/reset',
- '/private/en/analytics/settings'
- );
- }
-}
diff --git a/src/Backend/Modules/Analytics/Tests/Actions/SettingsTest.php b/src/Backend/Modules/Analytics/Tests/Actions/SettingsTest.php
deleted file mode 100644
index f278277a53..0000000000
--- a/src/Backend/Modules/Analytics/Tests/Actions/SettingsTest.php
+++ /dev/null
@@ -1,21 +0,0 @@
-login($client);
-
- self::assertPageLoadedCorrectly($client, '/private/en/analytics/settings', ['How to get your secret file?']);
- }
-}
diff --git a/src/Backend/Modules/Analytics/Tests/GoogleClient/ConnectorTest.php b/src/Backend/Modules/Analytics/Tests/GoogleClient/ConnectorTest.php
deleted file mode 100644
index dd085bcc1e..0000000000
--- a/src/Backend/Modules/Analytics/Tests/GoogleClient/ConnectorTest.php
+++ /dev/null
@@ -1,292 +0,0 @@
-getAnalyticsServiceMock(),
- new Pool(new MemoryStore()),
- $this->getModulesSettingsMock()
- );
-
- self::assertEquals(
- 1,
- $connector->getPageViews(
- strtotime('-1 day', mktime(0, 0, 0)),
- mktime(0, 0, 0)
- )
- );
- }
-
- public function testGetVisitors(): void
- {
- $connector = new Connector(
- $this->getAnalyticsServiceMock(),
- new Pool(new MemoryStore()),
- $this->getModulesSettingsMock()
- );
-
- self::assertEquals(
- 2,
- $connector->getVisitors(
- strtotime('-1 day', mktime(0, 0, 0)),
- mktime(0, 0, 0)
- )
- );
- }
-
- public function testGetPagesPerVisit(): void
- {
- $connector = new Connector(
- $this->getAnalyticsServiceMock(),
- new Pool(new MemoryStore()),
- $this->getModulesSettingsMock()
- );
-
- self::assertEquals(
- 3.14,
- $connector->getPagesPerVisit(
- strtotime('-1 day', mktime(0, 0, 0)),
- mktime(0, 0, 0)
- )
- );
- }
-
- public function testGetTimeOnSite(): void
- {
- $connector = new Connector(
- $this->getAnalyticsServiceMock(),
- new Pool(new MemoryStore()),
- $this->getModulesSettingsMock()
- );
-
- self::assertEquals(
- 1.02,
- $connector->getTimeOnSite(
- strtotime('-1 day', mktime(0, 0, 0)),
- mktime(0, 0, 0)
- )
- );
- }
-
- public function testGetNewSessionsPercentage(): void
- {
- $connector = new Connector(
- $this->getAnalyticsServiceMock(),
- new Pool(new MemoryStore()),
- $this->getModulesSettingsMock()
- );
-
- self::assertEquals(
- 78.23,
- $connector->getNewSessionsPercentage(
- strtotime('-1 day', mktime(0, 0, 0)),
- mktime(0, 0, 0)
- )
- );
- }
-
- public function testGetBounceRate(): void
- {
- $connector = new Connector(
- $this->getAnalyticsServiceMock(),
- new Pool(new MemoryStore()),
- $this->getModulesSettingsMock()
- );
-
- self::assertEquals(
- 23.25,
- $connector->getBounceRate(
- strtotime('-1 day', mktime(0, 0, 0)),
- mktime(0, 0, 0)
- )
- );
- }
-
- public function testGetVisitorsGraphData(): void
- {
- ini_set('date.timezone', 'Europe/Brussels');
-
- $connector = new Connector(
- $this->getAnalyticsServiceMock(),
- new Pool(new MemoryStore()),
- $this->getModulesSettingsMock()
- );
-
- self::assertEquals(
- [
- [
- 'ga_date' => '1431295200',
- 'ga_pageviews' => '0',
- 'ga_users' => '0',
- ],
- [
- 'ga_date' => '1431381600',
- 'ga_pageviews' => '1',
- 'ga_users' => '1',
- ],
- ],
- $connector->getVisitorsGraphData(
- strtotime('-1 day', mktime(0, 0, 0)),
- mktime(0, 0, 0)
- )
- );
- }
-
- public function testGetSourceGraphData(): void
- {
- $connector = new Connector(
- $this->getAnalyticsServiceMock(),
- new Pool(new MemoryStore()),
- $this->getModulesSettingsMock()
- );
-
- self::assertEquals(
- [
- [
- 'ga_medium' => '(none)',
- 'ga_pageviews' => '8',
- ],
- [
- 'ga_medium' => 'organic',
- 'ga_pageviews' => '6',
- ],
- ],
- $connector->getSourceGraphData(
- strtotime('-1 day', mktime(0, 0, 0)),
- mktime(0, 0, 0)
- )
- );
- }
-
- public function testGetMostVisitedPagesData(): void
- {
- $connector = new Connector(
- $this->getAnalyticsServiceMock(),
- new Pool(new MemoryStore()),
- $this->getModulesSettingsMock()
- );
-
- self::assertEquals(
- [
- [
- 'ga_pagePath' => '/en',
- 'ga_pageviews' => '15',
- ],
- [
- 'ga_pagePath' => '/en/blog',
- 'ga_pageviews' => '8',
- ],
- ],
- $connector->getMostVisitedPagesData(
- strtotime('-1 day', mktime(0, 0, 0)),
- mktime(0, 0, 0)
- )
- );
- }
-
- private function getModulesSettingsMock(): MockObject
- {
- return $this->getMockBuilder(ModulesSettings::class)
- ->disableOriginalConstructor()
- ->getMock()
- ;
- }
-
- private function getAnalyticsServiceMock(): Google_Service_Analytics
- {
- $analyticsService = new Google_Service_Analytics(new Google_Client());
-
- $dataGateway = $this->getMockBuilder('Google_Service_Analytics_DataGa_Resource')
- ->disableOriginalConstructor()
- ->getMock()
- ;
-
- $metricsReturnMock = $this->getMockBuilder('Google_Service_Analytics_GaData')->getMock();
- $metricsReturnMock
- ->method('getTotalsForAllResults')
- ->willReturn([
- 'ga:pageviews' => 1,
- 'ga:users' => 2,
- 'ga:pageviewsPerSession' => 3.14,
- 'ga:avgSessionDuration' => 1.02,
- 'ga:percentNewSessions' => 78.23,
- 'ga:bounceRate' => 23.25,
- ])
- ;
-
- $visitGraphDataMock = $this->getMockBuilder('Google_Service_Analytics_GaData')->getMock();
- $visitGraphDataMock
- ->method('getRows')
- ->willReturn([
- ['20150511', '0', '0'],
- ['20150512', '1', '1'],
- ])
- ;
- $visitGraphDataMock
- ->method('getColumnHeaders')
- ->willReturn([
- ['name' => 'ga:date'],
- ['name' => 'ga:pageviews'],
- ['name' => 'ga:users'],
- ])
- ;
-
- $sourceGraphDataMock = $this->getMockBuilder('Google_Service_Analytics_GaData')->getMock();
- $sourceGraphDataMock
- ->method('getRows')
- ->willReturn([
- ['(none)', '8'],
- ['organic', '6'],
- ])
- ;
- $sourceGraphDataMock
- ->method('getColumnHeaders')
- ->willReturn([
- ['name' => 'ga:medium'],
- ['name' => 'ga:pageviews'],
- ])
- ;
-
- $pageViewsDataMock = $this->getMockBuilder('Google_Service_Analytics_GaData')->getMock();
- $pageViewsDataMock
- ->method('getRows')
- ->willReturn([
- ['/en', '15'],
- ['/en/blog', '8'],
- ])
- ;
- $pageViewsDataMock
- ->method('getColumnHeaders')
- ->willReturn([
- ['name' => 'ga:pagePath'],
- ['name' => 'ga:pageviews'],
- ])
- ;
-
- $dataGateway->method('get')
- ->will(self::onConsecutiveCalls(
- $metricsReturnMock,
- $visitGraphDataMock,
- $pageViewsDataMock,
- $sourceGraphDataMock
- ))
- ;
-
- $analyticsService->data_ga = $dataGateway;
-
- return $analyticsService;
- }
-}
diff --git a/src/Backend/Modules/Analytics/Widgets/RecentVisits.php b/src/Backend/Modules/Analytics/Widgets/RecentVisits.php
deleted file mode 100644
index 8b4ff3b721..0000000000
--- a/src/Backend/Modules/Analytics/Widgets/RecentVisits.php
+++ /dev/null
@@ -1,36 +0,0 @@
-get('analytics.connector');
-
- $this->template->assign(
- 'visitors_graph_data',
- $analytics->getVisitorsGraphData($startDate, $endDate)
- );
-
- $this->header->addJS('highcharts.js', 'Core', false);
- $this->header->addJS('Analytics.js', 'Analytics');
- $this->display();
- } catch (Google_Auth_Exception) {
- // do nothing, analyticis is probably not set up yet.
- } catch (Google_IO_Exception) {
- // do nothing, probably no internet connection.
- }
- }
-}
diff --git a/src/Backend/Modules/Analytics/Widgets/TraficSources.php b/src/Backend/Modules/Analytics/Widgets/TraficSources.php
deleted file mode 100644
index 314619d8cc..0000000000
--- a/src/Backend/Modules/Analytics/Widgets/TraficSources.php
+++ /dev/null
@@ -1,36 +0,0 @@
-get('analytics.connector');
-
- $this->template->assign(
- 'source_graph_data',
- $analytics->getSourceGraphData($startDate, $endDate)
- );
-
- $this->header->addJS('highcharts.js', 'Core', false);
- $this->header->addJS('Analytics.js', 'Analytics');
- $this->display();
- } catch (Google_Auth_Exception) {
- // do nothing, analyticis is probably not set up yet.
- } catch (Google_IO_Exception) {
- // do nothing, probably no internet connection.
- }
- }
-}
diff --git a/src/Backend/Modules/Analytics/info.xml b/src/Backend/Modules/Analytics/info.xml
deleted file mode 100644
index c3d4f80262..0000000000
--- a/src/Backend/Modules/Analytics/info.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
- Analytics
- 2.0.0
-
- 3.9.0
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Backend/Modules/Locale/Engine/Model.php b/src/Backend/Modules/Locale/Engine/Model.php
index f69de34d08..0e33c4b328 100644
--- a/src/Backend/Modules/Locale/Engine/Model.php
+++ b/src/Backend/Modules/Locale/Engine/Model.php
@@ -476,7 +476,7 @@ public static function importXML(
// items
foreach ($items as $item) {
// attributes
- $attributes = $item->attributes();
+ $attributes = current($item->attributes());
$type = in_array($attributes['type'], $possibleTypes, true) ? $attributes['type'] : '';
$name = s($attributes['name'] ?? '')->title()->toString();
@@ -494,7 +494,7 @@ public static function importXML(
++$statistics['total'];
// attributes
- $attributes = $translation->attributes();
+ $attributes = current($translation->attributes());
$language = in_array($attributes['language'], $possibleLanguages[$application], true) ? $attributes['language'] : '';
// language does not exist
diff --git a/src/Backend/Modules/Settings/Actions/Index.php b/src/Backend/Modules/Settings/Actions/Index.php
index 3f855c33a5..1254e6b3d4 100644
--- a/src/Backend/Modules/Settings/Actions/Index.php
+++ b/src/Backend/Modules/Settings/Actions/Index.php
@@ -67,7 +67,7 @@ private function loadForm(): void
$googleTrackingAnalyticsTrackingId = $this->get('fork.settings')->get(
'Core',
'google_tracking_google_analytics_tracking_id',
- $this->get('fork.settings')->get('Analytics', 'web_property_id', '')
+ ''
);
$this->form->addCheckbox(
'google_tracking_google_analytics_tracking_id_enabled',
diff --git a/tests/data/test_db.sql b/tests/data/test_db.sql
index 5ccefee07a..4e7b4fd172 100644
--- a/tests/data/test_db.sql
+++ b/tests/data/test_db.sql
@@ -7,69 +7,6 @@
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
-# Dump of table analytics_keywords
-# ------------------------------------------------------------
-
-DROP TABLE IF EXISTS `analytics_keywords`;
-
-CREATE TABLE `analytics_keywords` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `keyword` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
- `entrances` int(11) NOT NULL,
- `date` datetime NOT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-
-
-
-# Dump of table analytics_landing_pages
-# ------------------------------------------------------------
-
-DROP TABLE IF EXISTS `analytics_landing_pages`;
-
-CREATE TABLE `analytics_landing_pages` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `page_path` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
- `entrances` int(11) NOT NULL,
- `bounces` int(11) NOT NULL,
- `bounce_rate` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
- `start_date` datetime NOT NULL,
- `end_date` datetime NOT NULL,
- `updated_on` datetime NOT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-
-
-
-# Dump of table analytics_pages
-# ------------------------------------------------------------
-
-DROP TABLE IF EXISTS `analytics_pages`;
-
-CREATE TABLE `analytics_pages` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `page` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
- `date_viewed` datetime NOT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-
-
-
-# Dump of table analytics_referrers
-# ------------------------------------------------------------
-
-DROP TABLE IF EXISTS `analytics_referrers`;
-
-CREATE TABLE `analytics_referrers` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `referrer` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
- `entrances` int(11) NOT NULL,
- `date` datetime NOT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-
-
-
# Dump of table backend_navigation
# ------------------------------------------------------------
@@ -113,13 +50,6 @@ VALUES
(21,9,'Search','search/settings',NULL,3),
(22,2,'ContentBlocks','content_blocks/index','a:2:{i:0;s:18:\"content_blocks/add\";i:1;s:19:\"content_blocks/edit\";}',2),
(23,2,'Tags','tags/index','a:1:{i:0;s:9:\"tags/edit\";}',3),
- (24,0,'Marketing','analytics/index',NULL,4),
- (25,24,'Analytics','analytics/index','a:1:{i:0;s:17:\"analytics/loading\";}',1),
- (26,25,'Content','analytics/content',NULL,1),
- (27,25,'AllPages','analytics/all_pages',NULL,2),
- (28,25,'ExitPages','analytics/exit_pages',NULL,3),
- (29,25,'LandingPages','analytics/landing_pages','a:3:{i:0;s:26:\"analytics/add_landing_page\";i:1;s:27:\"analytics/edit_landing_page\";i:2;s:21:\"analytics/detail_page\";}',4),
- (30,9,'Analytics','analytics/settings',NULL,4),
(31,2,'Blog','',NULL,4),
(32,31,'Articles','blog/index','a:3:{i:0;s:8:\"blog/add\";i:1;s:9:\"blog/edit\";i:2;s:21:\"blog/import_wordpress\";}',1),
(33,31,'Comments','blog/comments','a:1:{i:0;s:17:\"blog/edit_comment\";}',2),
@@ -488,22 +418,6 @@ VALUES
(55,1,'Tags','Edit',7),
(56,1,'Tags','Index',7),
(57,1,'Tags','MassAction',7),
- (58,1,'Analytics','AddLandingPage',7),
- (59,1,'Analytics','AllPages',7),
- (60,1,'Analytics','CheckStatus',7),
- (61,1,'Analytics','Content',7),
- (62,1,'Analytics','DeleteLandingPage',7),
- (63,1,'Analytics','DetailPage',7),
- (64,1,'Analytics','ExitPages',7),
- (65,1,'Analytics','GetTrafficSources',7),
- (66,1,'Analytics','Index',7),
- (67,1,'Analytics','LandingPages',7),
- (68,1,'Analytics','Loading',7),
- (69,1,'Analytics','MassLandingPageAction',7),
- (70,1,'Analytics','RefreshTrafficSources',7),
- (71,1,'Analytics','Settings',7),
- (72,1,'Analytics','TrafficSources',7),
- (73,1,'Analytics','Visitors',7),
(74,1,'Blog','AddCategory',7),
(75,1,'Blog','Add',7),
(76,1,'Blog','Categories',7),
@@ -573,7 +487,6 @@ VALUES
(178,2,'Pages','Edit',7),
(179,2,'Pages','Settings',7),
(180,3,'Users','Edit',7),
- (181,1,'Analytics','Reset',7),
(182,1,'Extensions','ExportThemeTemplates',7),
(183,1,'Location','Settings',7),
(184,1,'Mailmotor','Ping',7),
@@ -638,7 +551,6 @@ VALUES
(8,1,'Search'),
(9,1,'ContentBlocks'),
(10,1,'Tags'),
- (11,1,'Analytics'),
(12,1,'Blog'),
(13,1,'Faq'),
(14,1,'FormBuilder'),
@@ -1030,7 +942,6 @@ VALUES
(327, 1, 'en', 'Backend', 'Core', 'lbl', 'Amount', 'amount', '2017-08-31 14:28:18'),
(328, 1, 'en', 'Backend', 'Core', 'lbl', 'Analyse', 'analyse', '2017-08-31 14:28:18'),
(329, 1, 'en', 'Backend', 'Core', 'lbl', 'Analysis', 'analysis', '2017-08-31 14:28:18'),
- (330, 1, 'en', 'Backend', 'Core', 'lbl', 'Analytics', 'analytics', '2017-08-31 14:28:18'),
(331, 1, 'en', 'Backend', 'Core', 'lbl', 'APIKey', 'API key', '2017-08-31 14:28:18'),
(332, 1, 'en', 'Backend', 'Core', 'lbl', 'APIKeys', 'API keys', '2017-08-31 14:28:18'),
(333, 1, 'en', 'Backend', 'Core', 'lbl', 'APIURL', 'API URL', '2017-08-31 14:28:18'),
@@ -1784,24 +1695,6 @@ VALUES
(1083, 1, 'en', 'Backend', 'Tags', 'err', 'NonExisting', 'This tag doesn\'t exist.', '2017-08-31 14:28:22'),
(1084, 1, 'en', 'Backend', 'Tags', 'err', 'NoSelection', 'No tags were selected.', '2017-08-31 14:28:22'),
(1085, 1, 'en', 'Backend', 'Tags', 'err', 'TagAlreadyExists', 'This tag already exists.', '2017-08-31 14:28:22'),
- (1086, 1, 'en', 'Backend', 'Analytics', 'lbl', 'AverageTimeOnSite', 'average time on site', '2017-08-31 14:28:22'),
- (1087, 1, 'en', 'Backend', 'Analytics', 'lbl', 'BounceRate', 'bounce rate', '2017-08-31 14:28:22'),
- (1088, 1, 'en', 'Backend', 'Analytics', 'lbl', 'ChangePeriod', 'change period', '2017-08-31 14:28:22'),
- (1089, 1, 'en', 'Backend', 'Analytics', 'lbl', 'ChooseThisAccount', 'choose this account', '2017-08-31 14:28:22'),
- (1090, 1, 'en', 'Backend', 'Analytics', 'lbl', 'ChooseWebsiteProfile', 'Choose an Analytics website profile...', '2017-08-31 14:28:22'),
- (1091, 1, 'en', 'Backend', 'Analytics', 'lbl', 'GaPagePath', 'page', '2017-08-31 14:28:22'),
- (1092, 1, 'en', 'Backend', 'Analytics', 'lbl', 'GaPageviews', 'pageviews', '2017-08-31 14:28:22'),
- (1093, 1, 'en', 'Backend', 'Analytics', 'lbl', 'LinkedProfile', 'linked profile', '2017-08-31 14:28:22'),
- (1094, 1, 'en', 'Backend', 'Analytics', 'lbl', 'NewVisitsPercentage', 'new visits percentage', '2017-08-31 14:28:22'),
- (1095, 1, 'en', 'Backend', 'Analytics', 'lbl', 'PagesPerVisit', 'pages per visit', '2017-08-31 14:28:22'),
- (1096, 1, 'en', 'Backend', 'Analytics', 'lbl', 'Pageviews', 'pageviews', '2017-08-31 14:28:22'),
- (1097, 1, 'en', 'Backend', 'Analytics', 'lbl', 'Certificate', 'certificate (.p12 file)', '2017-08-31 14:28:22'),
- (1098, 1, 'en', 'Backend', 'Analytics', 'lbl', 'MostViewedPages', 'most viewed pages', '2017-08-31 14:28:22'),
- (1099, 1, 'en', 'Backend', 'Analytics', 'lbl', 'Visitors', 'visitors', '2017-08-31 14:28:22'),
- (1100, 1, 'en', 'Backend', 'Analytics', 'err', 'P12Only', 'Only p12 files are allowed.', '2017-08-31 14:28:22'),
- (1101, 1, 'en', 'Backend', 'Analytics', 'msg', 'CertificateHelp', '\n How to get your secret file?
\n
\n Enable the Analytics API
\n \n
\n - Go to the Google Developers Console.
\n - Make sure you\'re logged in with a Google account that has access to the wanted Analytics account.
\n - Select a project in the header, or create a new one.
\n - Click on Library in the sidebar on the left.
\n - Go to the Analytics API page by clicking on it in the Other popular API\'s category or typing it in the search bar.
\n - You can enable the API if you haven\'t done that yet by clicking on ENABLE API underneath the header.
\n
\n \n Creating credentials for Fork CMS.
\n \n
\n - In the sidebar on the left, select Credentials.
\n - Click on Create credentials and select Service account key in the dropdown.
\n - Create a new service account with the role Project - Editor and P12 as Key type.
\n - Download the generated certificate (.p12 file).
\n - Go back to the Credentials page and click on Manage service accounts
\n - Copy the Service account ID of the newly created account. It should look something like
name@spheric-passkey-123456.iam.gserviceaccount.com \n - Login to analytics, go to admin page and add the generated e-mail adress to the prefered property with \"read and analyze\" rights.
\n - Grab a cup of coffee, and come back to Fork in some minutes. It can take some time before the coupling is fully done.
\n
\n ', '2017-08-31 14:28:22'),
- (1102, 1, 'en', 'Backend', 'Analytics', 'msg', 'NoAccounts', 'There are no analytics accounts coupled to the given email address. Make sure you added the email address %1$s to the wanted account. It can take a while before the coupling is completed.', '2017-08-31 14:28:22'),
- (1103, 1, 'en', 'Backend', 'Analytics', 'msg', 'RemoveAccountLink', 'Remove the link with your Google account', '2017-08-31 14:28:22'),
(1104, 1, 'en', 'Backend', 'Core', 'lbl', 'PageviewsByTrafficSources', 'pageviews per traffic source', '2017-08-31 14:28:22'),
(1105, 1, 'en', 'Backend', 'Blog', 'lbl', 'Add', 'add article', '2017-08-31 14:28:23'),
(1106, 1, 'en', 'Backend', 'Blog', 'lbl', 'WordpressFilter', 'filter', '2017-08-31 14:28:23'),
@@ -2373,7 +2266,6 @@ VALUES
('Search','2015-02-23 19:48:53'),
('ContentBlocks','2015-02-23 19:48:53'),
('Tags','2015-02-23 19:48:53'),
- ('Analytics','2015-02-23 19:48:53'),
('Blog','2015-02-23 19:48:53'),
('Faq','2015-02-23 19:48:53'),
('FormBuilder','2015-02-23 19:48:53'),