diff --git a/Classes/Backend/Units/Lead/Dashboard/Hottest.php b/Classes/Backend/Units/Lead/Dashboard/Hottest.php index b3b8ed5c..cac8c225 100644 --- a/Classes/Backend/Units/Lead/Dashboard/Hottest.php +++ b/Classes/Backend/Units/Lead/Dashboard/Hottest.php @@ -24,7 +24,7 @@ protected function assignAdditionalVariables(): array } $visitorRepository = GeneralUtility::makeInstance(VisitorRepository::class); return [ - 'hottestVisitors' => $visitorRepository->findByHottestScorings($this->filter), + 'hottestVisitors' => $visitorRepository->findByHottestScorings($this->filter->setLimit(10)), ]; } } diff --git a/Classes/Controller/LeadController.php b/Classes/Controller/LeadController.php index b82de926..53ef5989 100644 --- a/Classes/Controller/LeadController.php +++ b/Classes/Controller/LeadController.php @@ -4,8 +4,6 @@ namespace In2code\Lux\Controller; use DateTime; -use Doctrine\DBAL\DBALException; -use Doctrine\DBAL\Driver\Exception as ExceptionDbalDriver; use Doctrine\DBAL\Exception as ExceptionDbal; use Exception; use In2code\Lux\Domain\DataProvider\CompanyAmountPerMonthDataProvider; @@ -82,7 +80,6 @@ public function initializeListAction(): void * @param string $export * @return ResponseInterface * @throws ExceptionDbal - * @throws ExceptionDbalDriver * @throws InvalidQueryException */ public function listAction(FilterDto $filter, string $export = ''): ResponseInterface @@ -91,12 +88,12 @@ public function listAction(FilterDto $filter, string $export = ''): ResponseInte return (new ForwardResponse('downloadCsv'))->withArguments(['filter' => $filter]); } $this->view->assignMultiple([ + 'filter' => $filter->setLimit(750), + 'luxCategories' => $this->categoryRepository->findAllLuxCategories(), + 'allVisitors' => $this->visitorRepository->findAllWithIdentifiedFirst($filter), 'numberOfVisitorsData' => GeneralUtility::makeInstance(PagevisistsDataProvider::class, $filter), - 'hottestVisitors' => $this->visitorRepository->findByHottestScorings($filter, 8), + 'hottestVisitors' => $this->visitorRepository->findByHottestScorings($filter->setLimit(8)), 'visitorsPerTimeData' => GeneralUtility::makeInstance(LeadsPerTimeDataProvider::class, $filter), - 'filter' => $filter, - 'allVisitors' => $this->visitorRepository->findAllWithIdentifiedFirst($filter), - 'luxCategories' => $this->categoryRepository->findAllLuxCategories(), ]); $this->addDocumentHeaderForCurrentController(); @@ -137,7 +134,6 @@ public function downloadCsvAction(FilterDto $filter): ResponseInterface * * @param Visitor $visitor * @return ResponseInterface - * @throws DBALException */ public function removeAction(Visitor $visitor): ResponseInterface { @@ -151,7 +147,6 @@ public function removeAction(Visitor $visitor): ResponseInterface * @return ResponseInterface * @throws IllegalObjectTypeException * @throws UnknownObjectException - * @throws DBALException */ public function deactivateAction(Visitor $visitor): ResponseInterface { @@ -175,7 +170,6 @@ public function initializeCompaniesAction(): void * @param string $export * @return ResponseInterface * @throws ExceptionDbal - * @throws ExceptionDbalDriver */ public function companiesAction(FilterDto $filter, string $export = ''): ResponseInterface { @@ -257,7 +251,6 @@ public function companyAction(Company $company): ResponseInterface * @param FilterDto $filter * @return ResponseInterface * @throws ExceptionDbal - * @throws ExceptionDbalDriver */ public function downloadCsvCompaniesAction(FilterDto $filter): ResponseInterface { diff --git a/Classes/Domain/DataProvider/LeadsPerTimeDataProvider.php b/Classes/Domain/DataProvider/LeadsPerTimeDataProvider.php index 7d8c6b13..eef32904 100644 --- a/Classes/Domain/DataProvider/LeadsPerTimeDataProvider.php +++ b/Classes/Domain/DataProvider/LeadsPerTimeDataProvider.php @@ -43,13 +43,15 @@ public function prepareData(): void // New visitors $this->data['amounts'][] = $visitorRepository->findAmountOfNewVisitorsInTimeFrame( $interval['start'], - $interval['end'] + $interval['end'], + $this->filter ); // Existing visitors $this->data['amounts2'][] = $visitorRepository->findAmountOfExistingVisitorsInTimeFrame( $interval['start'], - $interval['end'] + $interval['end'], + $this->filter ); $this->data['titles'][] = $this->getLabelForFrequency($frequency, $interval['start']); } diff --git a/Classes/Domain/Repository/AbstractRepository.php b/Classes/Domain/Repository/AbstractRepository.php index e460ee1f..4c1aedad 100644 --- a/Classes/Domain/Repository/AbstractRepository.php +++ b/Classes/Domain/Repository/AbstractRepository.php @@ -286,7 +286,7 @@ protected function extendFromClauseWithJoinByFilter( if (in_array('v', $tables)) { $sql .= ' left join ' . Visitor::TABLE_NAME . ' v on v.uid = pv.visitor'; } - if ($filter->isSearchtermSet() || $filter->isSiteQueryNeeded()) { + if ($filter->isSearchtermSet() || $filter->isDomainSet()) { if (in_array('pv', $tables)) { $sql .= ' left join ' . Pagevisit::TABLE_NAME . ' pv on v.uid = pv.visitor'; } diff --git a/Classes/Domain/Repository/PagevisitRepository.php b/Classes/Domain/Repository/PagevisitRepository.php index ca4e13b3..34ef277f 100644 --- a/Classes/Domain/Repository/PagevisitRepository.php +++ b/Classes/Domain/Repository/PagevisitRepository.php @@ -137,7 +137,6 @@ public function getNumberOfVisitsInTimeFrame(DateTime $start, DateTime $end, Fil . $this->extendFromClauseWithJoinByFilter($filter, ['p', 'cs', 'v']) . ' where pv.crdate>=' . $start->getTimestamp() . ' and pv.crdate<=' . $end->getTimestamp() . $this->extendWhereClauseWithFilterSearchterms($filter, 'p') - . $this->extendWhereClauseWithFilterDomain($filter, 'pv') . $this->extendWhereClauseWithFilterSite($filter, 'pv') . $this->extendWhereClauseWithFilterScoring($filter, 'v') . $this->extendWhereClauseWithFilterVisitor($filter, 'v') diff --git a/Classes/Domain/Repository/VisitorRepository.php b/Classes/Domain/Repository/VisitorRepository.php index f00dbd34..9135778c 100644 --- a/Classes/Domain/Repository/VisitorRepository.php +++ b/Classes/Domain/Repository/VisitorRepository.php @@ -4,7 +4,6 @@ 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 Exception; @@ -23,14 +22,12 @@ use In2code\Lux\Domain\Model\Transfer\FilterDto; use In2code\Lux\Domain\Model\Utm; use In2code\Lux\Domain\Model\Visitor; -use In2code\Lux\Exception\FileNotFoundException; use In2code\Lux\Exception\ParametersException; use In2code\Lux\Utility\ArrayUtility; use In2code\Lux\Utility\DatabaseUtility; use In2code\Lux\Utility\DateUtility; use In2code\Lux\Utility\StringUtility; use TYPO3\CMS\Core\Utility\MathUtility; -use TYPO3\CMS\Extbase\Configuration\Exception\InvalidConfigurationTypeException; use TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException; use TYPO3\CMS\Extbase\Persistence\Exception\InvalidQueryException; use TYPO3\CMS\Extbase\Persistence\Exception\UnknownObjectException; @@ -65,25 +62,25 @@ public function findOneAndAlsoBlacklistedByFingerprint(string $identificator, in /** * @param FilterDto $filter - * @param int $limit * @return array ->toArray() improves performance up to 100% on some cases * @throws InvalidQueryException */ - public function findAllWithIdentifiedFirst(FilterDto $filter, int $limit = 750): array + public function findAllWithIdentifiedFirst(FilterDto $filter): array { // Search for single visitor by calculated hash if ($filter->isSearchtermSet() && StringUtility::isShortMd5($filter->getSearchterm())) { - $visitor = $this->findByHash($filter->getSearchterm()); + $visitor = $this->findByHash($filter); if ($visitor !== null) { return [$visitor]; } } $query = $this->createQuery(); - $logicalAnd = $this->extendLogicalAndWithFilterConstraintsForCrdate($filter, $query, []); + $logicalAnd = $this->extendLogicalAndWithFilterConstraints($filter, $query, []); + $logicalAnd = $this->extendLogicalAndWithFilterConstraintsForSite($filter, $query, $logicalAnd, 'pagevisits'); $query->matching($query->logicalAnd(...$logicalAnd)); $query->setOrderings($this->getOrderingsArrayByFilterDto($filter)); - $query->setLimit($limit); + $query->setLimit($filter->getLimit()); return $query->execute()->toArray(); } @@ -91,8 +88,6 @@ public function findAllWithIdentifiedFirst(FilterDto $filter, int $limit = 750): * @param FilterDto $filter * @return array * @throws InvalidQueryException - * @throws FileNotFoundException - * @throws InvalidConfigurationTypeException */ public function findAllWithKnownCompanies(FilterDto $filter): array { @@ -113,7 +108,7 @@ public function findAllWithKnownCompanies(FilterDto $filter): array * @param string $propertyName * @param string $propertyValue * @param bool $exactMatch - * @param array $order + * @param array $orderings * @param int $limit * @return QueryResultInterface * @throws InvalidQueryException @@ -190,11 +185,10 @@ public function findByProperty(string $propertyName, string $propertyValue): ?Vi * Find a small couple of the hottest visitors * * @param FilterDto $filter - * @param int $limit * @return array * @throws ExceptionDbal */ - public function findByHottestScorings(FilterDto $filter, int $limit = 10) + public function findByHottestScorings(FilterDto $filter) { $connection = DatabaseUtility::getConnectionForTable(Visitor::TABLE_NAME); $sql = 'select distinct v.uid, v.scoring, v.tstamp from ' . Visitor::TABLE_NAME . ' v' @@ -207,7 +201,7 @@ public function findByHottestScorings(FilterDto $filter, int $limit = 10) . $this->extendWhereClauseWithFilterScoring($filter, 'v') . $this->extendWhereClauseWithFilterCategoryScoring($filter, 'cs') . ' order by v.scoring DESC, v.tstamp DESC' - . ' limit ' . $limit; + . ' limit ' . $filter->getLimit(); $rows = $connection->executeQuery($sql)->fetchAllAssociative(); $results = []; foreach ($rows as $row) { @@ -276,7 +270,7 @@ public function findByUniqueSiteVisits(FilterDto $filter): QueryResultInterface { $query = $this->createQuery(); $logicalAnd = [$query->equals('visits', 1)]; - $logicalAnd = $this->extendLogicalAndWithFilterConstraintsForCrdate($filter, $query, $logicalAnd); + $logicalAnd = $this->extendLogicalAndWithFilterConstraints($filter, $query, $logicalAnd); $logicalAnd = $this->extendLogicalAndWithFilterConstraintsForSite($filter, $query, $logicalAnd, 'pagevisits'); $query->matching($query->logicalAnd(...$logicalAnd)); return $query->execute(); @@ -291,7 +285,7 @@ public function findByRecurringSiteVisits(FilterDto $filter): QueryResultInterfa { $query = $this->createQuery(); $logicalAnd = [$query->greaterThan('visits', 1)]; - $logicalAnd = $this->extendLogicalAndWithFilterConstraintsForCrdate($filter, $query, $logicalAnd); + $logicalAnd = $this->extendLogicalAndWithFilterConstraints($filter, $query, $logicalAnd); $logicalAnd = $this->extendLogicalAndWithFilterConstraintsForSite($filter, $query, $logicalAnd, 'pagevisits'); $query->matching($query->logicalAnd(...$logicalAnd)); return $query->execute(); @@ -306,7 +300,7 @@ public function findIdentified(FilterDto $filter): QueryResultInterface { $query = $this->createQuery(); $logicalAnd = [$query->equals('identified', true)]; - $logicalAnd = $this->extendLogicalAndWithFilterConstraintsForCrdate($filter, $query, $logicalAnd); + $logicalAnd = $this->extendLogicalAndWithFilterConstraints($filter, $query, $logicalAnd); $logicalAnd = $this->extendLogicalAndWithFilterConstraintsForSite($filter, $query, $logicalAnd, 'pagevisits'); $query->matching($query->logicalAnd(...$logicalAnd)); return $query->execute(); @@ -321,7 +315,7 @@ public function findUnknown(FilterDto $filter): QueryResultInterface { $query = $this->createQuery(); $logicalAnd = [$query->equals('identified', false)]; - $logicalAnd = $this->extendLogicalAndWithFilterConstraintsForCrdate($filter, $query, $logicalAnd); + $logicalAnd = $this->extendLogicalAndWithFilterConstraints($filter, $query, $logicalAnd); $logicalAnd = $this->extendLogicalAndWithFilterConstraintsForSite($filter, $query, $logicalAnd, 'pagevisits'); $query->matching($query->logicalAnd(...$logicalAnd)); return $query->execute(); @@ -400,8 +394,7 @@ public function findByEmailAndEmptyFrontenduser(string $email): array /** * @return bool - * @throws DBALException - * @throws ExceptionDbalDriver + * @throws ExceptionDbal */ public function isVisitorExistingWithDefaultLanguage(): bool { @@ -413,8 +406,7 @@ public function isVisitorExistingWithDefaultLanguage(): bool /** * @return int - * @throws DBALException - * @throws ExceptionDbalDriver + * @throws ExceptionDbal */ public function findAllAmount(): int { @@ -424,8 +416,7 @@ public function findAllAmount(): int /** * @return int - * @throws DBALException - * @throws ExceptionDbalDriver + * @throws ExceptionDbal */ public function findAllIdentifiedAmount(): int { @@ -436,8 +427,7 @@ public function findAllIdentifiedAmount(): int /** * @return int - * @throws DBALException - * @throws ExceptionDbalDriver + * @throws ExceptionDbal */ public function findAllUnknownAmount(): int { @@ -446,13 +436,18 @@ public function findAllUnknownAmount(): int ->fetchOne(); } - public function findByHash(string $hash): ?Visitor + public function findByHash(FilterDto $filter): ?Visitor { - if (StringUtility::isShortMd5($hash) === false) { + if (StringUtility::isShortMd5($filter->getSearchterm()) === false) { return null; } - $sql = 'select uid from ' . Visitor::TABLE_NAME . ' where SUBSTR(MD5(uid), 1, 6) = "' . $hash . '" limit 1'; + $sql = 'select v.uid from ' . Visitor::TABLE_NAME . ' v' + . ' left join ' . Pagevisit::TABLE_NAME . ' pv on pv.visitor=v.uid' + . ' where SUBSTR(MD5(v.uid), 1, 6) = "' . $filter->getSearchterm() . '"' + . ' and v.deleted=0' + . $this->extendWhereClauseWithFilterSite($filter, 'pv') + . ' limit 1'; $connection = DatabaseUtility::getConnectionForTable(Visitor::TABLE_NAME); $identifier = $connection->executeQuery($sql)->fetchOne() ?: 0; @@ -490,30 +485,33 @@ public function findLatestVisitorsWithIpAddress(int $limit, DateTime $time, bool return $connection->executeQuery($sql)->fetchAllKeyValue(); } - public function findAmountOfVisitorsInTimeFrame(DateTime $start, DateTime $end): int + public function findAmountOfVisitorsInTimeFrame(DateTime $start, DateTime $end, FilterDto $filter): int { - $sql = 'select distinct v.uid from ' . Visitor::TABLE_NAME . ' v' + $sql = 'select count(distinct v.uid) from ' . Visitor::TABLE_NAME . ' v' . ' left join ' . Pagevisit::TABLE_NAME . ' pv on v.uid = pv.visitor' . ' where v.deleted=0 and v.blacklisted=0' . ' and pv.crdate >= ' . $start->getTimestamp() . ' and pv.crdate <= ' . $end->getTimestamp() - . ' group by v.uid'; + . $this->extendWhereClauseWithFilterSite($filter, 'pv') + . ' limit 1'; $connection = DatabaseUtility::getConnectionForTable(Visitor::TABLE_NAME); - $rows = $connection->executeQuery($sql)->fetchAllNumeric(); - return count($rows); + return (int)$connection->executeQuery($sql)->fetchOne(); } - public function findAmountOfExistingVisitorsInTimeFrame(DateTime $start, DateTime $end): int + public function findAmountOfExistingVisitorsInTimeFrame(DateTime $start, DateTime $end, FilterDto $filter): int { - $newVisitors = $this->findAmountOfNewVisitorsInTimeFrame($start, $end); - $allVisitors = $this->findAmountOfVisitorsInTimeFrame($start, $end); + $newVisitors = $this->findAmountOfNewVisitorsInTimeFrame($start, $end, $filter); + $allVisitors = $this->findAmountOfVisitorsInTimeFrame($start, $end, $filter); return $allVisitors - $newVisitors; } - public function findAmountOfNewVisitorsInTimeFrame(DateTime $start, DateTime $end): int + public function findAmountOfNewVisitorsInTimeFrame(DateTime $start, DateTime $end, FilterDto $filter): int { - $sql = 'select count(uid) from ' . Visitor::TABLE_NAME - . ' where deleted=0 and blacklisted=0' - . ' and crdate >= ' . $start->getTimestamp() . ' and crdate <= ' . $end->getTimestamp(); + $sql = 'select count(distinct v.uid) from ' . Visitor::TABLE_NAME . ' v' + . ' left join ' . Pagevisit::TABLE_NAME . ' pv on v.uid = pv.visitor' + . ' where v.deleted=0 and v.blacklisted=0' + . ' and v.crdate >= ' . $start->getTimestamp() . ' and v.crdate <= ' . $end->getTimestamp() + . $this->extendWhereClauseWithFilterSite($filter, 'pv') + . ' limit 1'; $connection = DatabaseUtility::getConnectionForTable(Visitor::TABLE_NAME); return (int)$connection->executeQuery($sql)->fetchOne(); } @@ -561,7 +559,7 @@ public function updateVisitorWithFrontendUserRelation(int $visitorIdentifier, in /** * @return void - * @throws DBALException + * @throws ExceptionDbal */ public function updateRecordsWithLanguageAll(): void { @@ -586,7 +584,7 @@ public function updateRecordsWithLanguageAll(): void /** * @param Visitor $visitor * @return void - * @throws DBALException + * @throws ExceptionDbal */ public function removeVisitor(Visitor $visitor): void { @@ -656,7 +654,7 @@ public function truncateAll(): void * @throws InvalidQueryException * @throws Exception */ - protected function extendLogicalAndWithFilterConstraintsForCrdate( + protected function extendLogicalAndWithFilterConstraints( FilterDto $filter, QueryInterface $query, array $logicalAnd diff --git a/Classes/Widgets/DataProvider/LuxHottestLeadsDataProvider.php b/Classes/Widgets/DataProvider/LuxHottestLeadsDataProvider.php index 7e44e181..29330c7d 100644 --- a/Classes/Widgets/DataProvider/LuxHottestLeadsDataProvider.php +++ b/Classes/Widgets/DataProvider/LuxHottestLeadsDataProvider.php @@ -17,7 +17,7 @@ public function getItems(): array $list = []; $visitorRepository = GeneralUtility::makeInstance(VisitorRepository::class); $filter = ObjectUtility::getFilterDto(FilterDto::PERIOD_THISMONTH); - $visitors = $visitorRepository->findByHottestScorings($filter); + $visitors = $visitorRepository->findByHottestScorings($filter->setLimit(10)); /** @var Visitor $visitor */ foreach ($visitors as $visitor) { $list[] = $visitor->getFullNameWithEmail() . ' - Scoring ' . $visitor->getScoring(); diff --git a/Resources/Private/Partials/Box/Lead/Information.html b/Resources/Private/Partials/Box/Lead/Information.html index 3868176f..3641fb39 100644 --- a/Resources/Private/Partials/Box/Lead/Information.html +++ b/Resources/Private/Partials/Box/Lead/Information.html @@ -10,7 +10,7 @@