From 215cc025d1961870402ee5fc9190568a584a9c52 Mon Sep 17 00:00:00 2001 From: Alexander Kellner Date: Fri, 23 Feb 2024 23:25:24 +0100 Subject: [PATCH] [FEATURE] Update of Analysis/UTM view --- Classes/Controller/AnalysisController.php | 7 +- .../DataProvider/UtmCampaignDataProvider.php | 2 - .../Domain/DataProvider/UtmDataProvider.php | 4 +- .../DataProvider/UtmMediaDataProvider.php | 2 - .../DataProvider/UtmSourceDataProvider.php | 2 - Classes/Domain/Model/Transfer/FilterDto.php | 22 ++- Classes/Domain/Repository/UtmRepository.php | 155 +++++++++++------- .../Private/Partials/Filter/Analysis/Utm.html | 82 ++++++--- 8 files changed, 184 insertions(+), 92 deletions(-) diff --git a/Classes/Controller/AnalysisController.php b/Classes/Controller/AnalysisController.php index f5f9293e..157bb09a 100644 --- a/Classes/Controller/AnalysisController.php +++ b/Classes/Controller/AnalysisController.php @@ -199,9 +199,10 @@ public function utmAction(FilterDto $filter, string $export = ''): ResponseInter $variables = [ 'filter' => $filter, - 'utmCampaigns' => $this->utmRepository->findAllCampaigns(), - 'utmSources' => $this->utmRepository->findAllSources(), - 'utmMedia' => $this->utmRepository->findAllMedia(), + 'utmCampaigns' => $this->utmRepository->findAllCampaigns($filter), + 'utmSources' => $this->utmRepository->findAllSources($filter), + 'utmMedia' => $this->utmRepository->findAllMedia($filter), + 'utmContent' => $this->utmRepository->findAllContent($filter), 'utmList' => $this->utmRepository->findByFilter($filter), 'utmData' => GeneralUtility::makeInstance(UtmDataProvider::class, $filter), 'utmCampaignData' => GeneralUtility::makeInstance(UtmCampaignDataProvider::class, $filter), diff --git a/Classes/Domain/DataProvider/UtmCampaignDataProvider.php b/Classes/Domain/DataProvider/UtmCampaignDataProvider.php index 523334b2..879422d9 100644 --- a/Classes/Domain/DataProvider/UtmCampaignDataProvider.php +++ b/Classes/Domain/DataProvider/UtmCampaignDataProvider.php @@ -3,7 +3,6 @@ declare(strict_types=1); namespace In2code\Lux\Domain\DataProvider; -use Doctrine\DBAL\Driver\Exception as ExceptionDbalDriver; use Doctrine\DBAL\Exception as ExceptionDbal; use In2code\Lux\Domain\Repository\UtmRepository; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -24,7 +23,6 @@ class UtmCampaignDataProvider extends AbstractDataProvider * ] * * @return void - * @throws ExceptionDbalDriver * @throws ExceptionDbal */ public function prepareData(): void diff --git a/Classes/Domain/DataProvider/UtmDataProvider.php b/Classes/Domain/DataProvider/UtmDataProvider.php index 5b75fb7a..b052676c 100644 --- a/Classes/Domain/DataProvider/UtmDataProvider.php +++ b/Classes/Domain/DataProvider/UtmDataProvider.php @@ -29,11 +29,11 @@ class UtmDataProvider extends AbstractDynamicFilterDataProvider */ public function prepareData(): void { - $newsvisitRepository = GeneralUtility::makeInstance(UtmRepository::class); + $utmRepository = GeneralUtility::makeInstance(UtmRepository::class); $intervals = $this->filter->getIntervals(); $frequency = (string)$intervals['frequency']; foreach ($intervals['intervals'] as $interval) { - $this->data['amounts'][] = $newsvisitRepository->getNumberOfVisitorsInTimeFrame( + $this->data['amounts'][] = $utmRepository->getNumberOfVisitorsInTimeFrame( $interval['start'], $interval['end'], $this->filter diff --git a/Classes/Domain/DataProvider/UtmMediaDataProvider.php b/Classes/Domain/DataProvider/UtmMediaDataProvider.php index 1d7e822e..e469c45a 100644 --- a/Classes/Domain/DataProvider/UtmMediaDataProvider.php +++ b/Classes/Domain/DataProvider/UtmMediaDataProvider.php @@ -3,7 +3,6 @@ declare(strict_types=1); namespace In2code\Lux\Domain\DataProvider; -use Doctrine\DBAL\Driver\Exception as ExceptionDbalDriver; use Doctrine\DBAL\Exception as ExceptionDbal; use In2code\Lux\Domain\Repository\UtmRepository; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -26,7 +25,6 @@ class UtmMediaDataProvider extends AbstractDataProvider * ] * * @return void - * @throws ExceptionDbalDriver * @throws ExceptionDbal */ public function prepareData(): void diff --git a/Classes/Domain/DataProvider/UtmSourceDataProvider.php b/Classes/Domain/DataProvider/UtmSourceDataProvider.php index 8c1f8d1d..80969944 100644 --- a/Classes/Domain/DataProvider/UtmSourceDataProvider.php +++ b/Classes/Domain/DataProvider/UtmSourceDataProvider.php @@ -3,7 +3,6 @@ declare(strict_types=1); namespace In2code\Lux\Domain\DataProvider; -use Doctrine\DBAL\Driver\Exception as ExceptionDbalDriver; use Doctrine\DBAL\Exception as ExceptionDbal; use In2code\Lux\Domain\Repository\UtmRepository; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -26,7 +25,6 @@ class UtmSourceDataProvider extends AbstractDataProvider * ] * * @return void - * @throws ExceptionDbalDriver * @throws ExceptionDbal */ public function prepareData(): void diff --git a/Classes/Domain/Model/Transfer/FilterDto.php b/Classes/Domain/Model/Transfer/FilterDto.php index 1087a6b0..7d5fff14 100644 --- a/Classes/Domain/Model/Transfer/FilterDto.php +++ b/Classes/Domain/Model/Transfer/FilterDto.php @@ -77,6 +77,7 @@ class FilterDto protected string $utmCampaign = ''; protected string $utmSource = ''; protected string $utmMedium = ''; + protected string $utmContent = ''; protected int $branchCode = 0; protected string $revenueClass = ''; protected string $sizeClass = ''; @@ -323,7 +324,7 @@ public function setDomain(string $domain): self public function getSite(): string { - return $this->site; + return StringUtility::cleanString($this->site); } public function isSiteSet(): bool @@ -389,6 +390,22 @@ public function setUtmMedium(string $utmMedium): FilterDto return $this; } + public function getUtmContent(): string + { + return $this->utmContent; + } + + public function isUtmContentSet(): bool + { + return $this->getUtmContent() !== ''; + } + + public function setUtmContent(string $utmContent): self + { + $this->utmContent = $utmContent; + return $this; + } + public function getBranchCode(): int { return $this->branchCode; @@ -488,6 +505,7 @@ public function isSet(): bool || $this->isUtmCampaignSet() || $this->isUtmMediumSet() || $this->isUtmSourceSet() + || $this->isUtmContentSet() || $this->isBranchCodeSet() || $this->isRevenueClassSet() || $this->isSizeClassSet(); @@ -803,7 +821,7 @@ public function getAllowedSites(): array public function getSitesForFilter(): array { if ($this->isSiteSet()) { - return [StringUtility::cleanString($this->getSite())]; + return [$this->getSite()]; } return array_merge(array_keys($this->getAllowedSites()), ['']); } diff --git a/Classes/Domain/Repository/UtmRepository.php b/Classes/Domain/Repository/UtmRepository.php index 4f3fdd1f..17442f01 100644 --- a/Classes/Domain/Repository/UtmRepository.php +++ b/Classes/Domain/Repository/UtmRepository.php @@ -4,9 +4,9 @@ namespace In2code\Lux\Domain\Repository; use DateTime; -use Doctrine\DBAL\DBALException; -use Doctrine\DBAL\Driver\Exception as ExceptionDbalDriver; use Doctrine\DBAL\Exception as ExceptionDbal; +use In2code\Lux\Domain\Model\Newsvisit; +use In2code\Lux\Domain\Model\Pagevisit; use In2code\Lux\Domain\Model\Transfer\FilterDto; use In2code\Lux\Domain\Model\Utm; use In2code\Lux\Utility\ArrayUtility; @@ -28,60 +28,72 @@ public function findByFilter(FilterDto $filter): QueryResultInterface $logicalAnd = $this->extendLogicalAndWithFilterConstraintsForCrdate($filter, $query, []); $logicalAnd = $this->extendWithExtendedFilterQuery($query, $logicalAnd, $filter); $query->matching($query->logicalAnd(...$logicalAnd)); + $query->setLimit(750); return $query->execute(); } /** + * @param FilterDto $filter * @return array - * @throws DBALException - * @throws ExceptionDbalDriver + * @throws ExceptionDbal */ - public function findAllCampaigns(): array + public function findAllCampaigns(FilterDto $filter): array { - $queryBuilder = DatabaseUtility::getQueryBuilderForTable(Utm::TABLE_NAME); - $results = $queryBuilder - ->select('utm_campaign') - ->from(Utm::TABLE_NAME) - ->where('utm_campaign != ""') - ->groupBy('utm_campaign') - ->executeQuery() - ->fetchFirstColumn(); - return ArrayUtility::copyValuesToKeys($results); + return $this->findAllProperties('utm_campaign', $filter); } /** + * @param FilterDto $filter * @return array - * @throws DBALException - * @throws ExceptionDbalDriver + * @throws ExceptionDbal */ - public function findAllSources(): array + public function findAllSources(FilterDto $filter): array { - $queryBuilder = DatabaseUtility::getQueryBuilderForTable(Utm::TABLE_NAME); - $results = $queryBuilder - ->select('utm_source') - ->from(Utm::TABLE_NAME) - ->where('utm_source != ""') - ->groupBy('utm_source') - ->executeQuery() - ->fetchFirstColumn(); - return ArrayUtility::copyValuesToKeys($results); + return $this->findAllProperties('utm_source', $filter); + } + + /** + * @param FilterDto $filter + * @return array + * @throws ExceptionDbal + */ + public function findAllMedia(FilterDto $filter): array + { + return $this->findAllProperties('utm_medium', $filter); } /** + * @param FilterDto $filter + * @return array + * @throws ExceptionDbal + */ + public function findAllContent(FilterDto $filter): array + { + return $this->findAllProperties('utm_content', $filter); + } + + /** + * @param string $property + * @param FilterDto $filter * @return array - * @throws DBALException - * @throws ExceptionDbalDriver + * @throws ExceptionDbal */ - public function findAllMedia(): array + protected function findAllProperties(string $property, FilterDto $filter): array { - $queryBuilder = DatabaseUtility::getQueryBuilderForTable(Utm::TABLE_NAME); - $results = $queryBuilder - ->select('utm_medium') - ->from(Utm::TABLE_NAME) - ->where('utm_medium != ""') - ->groupBy('utm_medium') - ->executeQuery() - ->fetchFirstColumn(); + $connection = DatabaseUtility::getConnectionForTable(Utm::TABLE_NAME); + $sql = 'select utm.' . $property; + $sql .= ' from ' . Utm::TABLE_NAME . ' utm'; + $sql .= ' left join ' . Pagevisit::TABLE_NAME . ' pv on pv.uid = utm.pagevisit'; + $sql .= ' left join ' . Newsvisit::TABLE_NAME . ' nv on nv.uid = utm.newsvisit'; + $sql .= ' left join ' . Pagevisit::TABLE_NAME . ' pnv on pnv.uid = nv.pagevisit'; + $sql .= ' where utm.' . $property . ' != \'\''; + $sql .= ' and (pv.site in ("' . implode('","', $filter->getSitesForFilter()) . '") or'; + $sql .= ' pnv.site in ("' . implode('","', $filter->getSitesForFilter()) . '"))'; + $sql .= $this->extendWhereClauseWithFilterTime($filter, true, 'utm'); + $sql .= ' group by utm.' . $property; + $sql .= ' order by utm.' . $property . ' asc'; + $sql .= ' limit 1000'; + $results = $connection->executeQuery($sql)->fetchFirstColumn(); return ArrayUtility::copyValuesToKeys($results); } @@ -109,12 +121,15 @@ public function getNumberOfVisitorsInTimeFrame(DateTime $start, DateTime $end, F * @param FilterDto $filter * @return array * @throws ExceptionDbal - * @throws ExceptionDbalDriver */ public function findCombinedByField(string $field, FilterDto $filter): array { $connection = DatabaseUtility::getConnectionForTable(Utm::TABLE_NAME); - $sql = 'select count(utm.' . $field . ') count, utm.' . $field . ' from ' . Utm::TABLE_NAME . ' utm' + $sql = 'select count(utm.' . $field . ') count, utm.' . $field + . ' from ' . Utm::TABLE_NAME . ' utm' + . ' left join ' . Pagevisit::TABLE_NAME . ' pv on pv.uid = utm.pagevisit' + . ' left join ' . Newsvisit::TABLE_NAME . ' nv on nv.uid = utm.newsvisit' + . ' left join ' . Pagevisit::TABLE_NAME . ' pnv on pnv.uid = nv.pagevisit' . ' where ' . $field . ' != \'\'' . $this->extendWhereClauseWithFilterTime($filter, true, 'utm') . $this->extendWhereClauseWithFilterSearchterms($filter, 'utm', 'utm_source') @@ -123,22 +138,20 @@ public function findCombinedByField(string $field, FilterDto $filter): array . $this->extendWhereClauseWithFilterSearchterms($filter, 'utm', 'utm_id', 'or') . $this->extendWhereClauseWithFilterSearchterms($filter, 'utm', 'utm_term', 'or') . $this->extendWhereClauseWithFilterSearchterms($filter, 'utm', 'utm_content', 'or') + . $this->extendWhereClauseWithFilterSearchterms($filter, 'utm', 'referrer', 'or') . $this->extendWhereClauseWithFilterCampaign($filter, 'utm') . $this->extendWhereClauseWithFilterSource($filter, 'utm') . $this->extendWhereClauseWithFilterMedium($filter, 'utm') + . $this->extendWhereClauseWithFilterContent($filter, 'utm') + . $this->extendWhereClauseWithFilterSite($filter) . ' group by utm.' . $field . ' order by count desc limit 8'; return $connection->executeQuery($sql)->fetchAllAssociative(); } - /** - * @param FilterDto $filter - * @param string $table - * @return string - */ protected function extendWhereClauseWithFilterCampaign(FilterDto $filter, string $table = ''): string { $sql = ''; - if ($filter->getUtmCampaign() !== '') { + if ($filter->isUtmCampaignSet()) { $field = 'utm_campaign'; if ($table !== '') { $field = $table . '.' . $field; @@ -148,15 +161,10 @@ protected function extendWhereClauseWithFilterCampaign(FilterDto $filter, string return $sql; } - /** - * @param FilterDto $filter - * @param string $table - * @return string - */ protected function extendWhereClauseWithFilterSource(FilterDto $filter, string $table = ''): string { $sql = ''; - if ($filter->getUtmSource() !== '') { + if ($filter->isUtmSourceSet()) { $field = 'utm_source'; if ($table !== '') { $field = $table . '.' . $field; @@ -166,15 +174,10 @@ protected function extendWhereClauseWithFilterSource(FilterDto $filter, string $ return $sql; } - /** - * @param FilterDto $filter - * @param string $table - * @return string - */ protected function extendWhereClauseWithFilterMedium(FilterDto $filter, string $table = ''): string { $sql = ''; - if ($filter->getUtmMedium() !== '') { + if ($filter->isUtmMediumSet()) { $field = 'utm_medium'; if ($table !== '') { $field = $table . '.' . $field; @@ -184,6 +187,37 @@ protected function extendWhereClauseWithFilterMedium(FilterDto $filter, string $ return $sql; } + protected function extendWhereClauseWithFilterContent(FilterDto $filter, string $table = ''): string + { + $sql = ''; + if ($filter->isUtmContentSet()) { + $field = 'utm_content'; + if ($table !== '') { + $field = $table . '.' . $field; + } + $sql .= ' and ' . $field . '="' . $filter->getUtmContent() . '"'; + } + return $sql; + } + + /** + * Returns part of a where clause like + * ' and site="site 1"' + * + * @param FilterDto $filter + * @param string $table table with crdate (normally the main table) + * @return string + */ + protected function extendWhereClauseWithFilterSite(FilterDto $filter, string $table = ''): string + { + $sql = ' and ('; + $sql .= 'pv.site in ("' . implode('","', $filter->getSitesForFilter()) . '")'; + $sql .= ' or '; + $sql .= 'pnv.site in ("' . implode('","', $filter->getSitesForFilter()) . '")'; + $sql .= ')'; + return $sql; + } + /** * @param QueryInterface $query * @param array $logicalAnd @@ -218,6 +252,13 @@ protected function extendWithExtendedFilterQuery( if ($filter->isUtmSourceSet()) { $logicalAnd[] = $query->like('utmSource', '%' . $filter->getUtmSource() . '%'); } + if ($filter->isUtmContentSet()) { + $logicalAnd[] = $query->like('utmContent', '%' . $filter->getUtmContent() . '%'); + } + $logicalAnd[] = $query->logicalOr( + $query->in('pagevisit.site', $filter->getSitesForFilter()), + $query->in('newsvisit.pagevisit.site', $filter->getSitesForFilter()) + ); } return $logicalAnd; } diff --git a/Resources/Private/Partials/Filter/Analysis/Utm.html b/Resources/Private/Partials/Filter/Analysis/Utm.html index ba7e6475..f1341fa3 100644 --- a/Resources/Private/Partials/Filter/Analysis/Utm.html +++ b/Resources/Private/Partials/Filter/Analysis/Utm.html @@ -5,7 +5,7 @@

UTM Filter

-
+
Suche
@@ -21,31 +21,34 @@
- -
-
-
Campaign
+
+
Zeit
- -
@@ -62,13 +65,25 @@
+
+ Campaign, Source - and - Medium
+
+ + +
+
Source
+
+ + +
+
+ Medium, + Content +
Medium
+ +
+ + +