Skip to content

Commit

Permalink
[FEATURE] Add site filter to view Lead/List
Browse files Browse the repository at this point in the history
  • Loading branch information
einpraegsam committed Feb 27, 2024
1 parent 4dcb531 commit f548a32
Show file tree
Hide file tree
Showing 10 changed files with 88 additions and 80 deletions.
2 changes: 1 addition & 1 deletion Classes/Backend/Units/Lead/Dashboard/Hottest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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)),
];
}
}
15 changes: 4 additions & 11 deletions Classes/Controller/LeadController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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();
Expand Down Expand Up @@ -137,7 +134,6 @@ public function downloadCsvAction(FilterDto $filter): ResponseInterface
*
* @param Visitor $visitor
* @return ResponseInterface
* @throws DBALException
*/
public function removeAction(Visitor $visitor): ResponseInterface
{
Expand All @@ -151,7 +147,6 @@ public function removeAction(Visitor $visitor): ResponseInterface
* @return ResponseInterface
* @throws IllegalObjectTypeException
* @throws UnknownObjectException
* @throws DBALException
*/
public function deactivateAction(Visitor $visitor): ResponseInterface
{
Expand All @@ -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
{
Expand Down Expand Up @@ -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
{
Expand Down
6 changes: 4 additions & 2 deletions Classes/Domain/DataProvider/LeadsPerTimeDataProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -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']);
}
Expand Down
2 changes: 1 addition & 1 deletion Classes/Domain/Repository/AbstractRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -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';
}
Expand Down
1 change: 0 additions & 1 deletion Classes/Domain/Repository/PagevisitRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand Down
86 changes: 42 additions & 44 deletions Classes/Domain/Repository/VisitorRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -65,34 +62,32 @@ 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();
}

/**
* @param FilterDto $filter
* @return array
* @throws InvalidQueryException
* @throws FileNotFoundException
* @throws InvalidConfigurationTypeException
*/
public function findAllWithKnownCompanies(FilterDto $filter): array
{
Expand All @@ -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
Expand Down Expand Up @@ -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'
Expand All @@ -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) {
Expand Down Expand Up @@ -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();
Expand All @@ -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();
Expand All @@ -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();
Expand All @@ -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();
Expand Down Expand Up @@ -400,8 +394,7 @@ public function findByEmailAndEmptyFrontenduser(string $email): array

/**
* @return bool
* @throws DBALException
* @throws ExceptionDbalDriver
* @throws ExceptionDbal
*/
public function isVisitorExistingWithDefaultLanguage(): bool
{
Expand All @@ -413,8 +406,7 @@ public function isVisitorExistingWithDefaultLanguage(): bool

/**
* @return int
* @throws DBALException
* @throws ExceptionDbalDriver
* @throws ExceptionDbal
*/
public function findAllAmount(): int
{
Expand All @@ -424,8 +416,7 @@ public function findAllAmount(): int

/**
* @return int
* @throws DBALException
* @throws ExceptionDbalDriver
* @throws ExceptionDbal
*/
public function findAllIdentifiedAmount(): int
{
Expand All @@ -436,8 +427,7 @@ public function findAllIdentifiedAmount(): int

/**
* @return int
* @throws DBALException
* @throws ExceptionDbalDriver
* @throws ExceptionDbal
*/
public function findAllUnknownAmount(): int
{
Expand All @@ -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;

Expand Down Expand Up @@ -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();
}
Expand Down Expand Up @@ -561,7 +559,7 @@ public function updateVisitorWithFrontendUserRelation(int $visitorIdentifier, in

/**
* @return void
* @throws DBALException
* @throws ExceptionDbal
*/
public function updateRecordsWithLanguageAll(): void
{
Expand All @@ -586,7 +584,7 @@ public function updateRecordsWithLanguageAll(): void
/**
* @param Visitor $visitor
* @return void
* @throws DBALException
* @throws ExceptionDbal
*/
public function removeVisitor(Visitor $visitor): void
{
Expand Down Expand Up @@ -656,7 +654,7 @@ public function truncateAll(): void
* @throws InvalidQueryException
* @throws Exception
*/
protected function extendLogicalAndWithFilterConstraintsForCrdate(
protected function extendLogicalAndWithFilterConstraints(
FilterDto $filter,
QueryInterface $query,
array $logicalAnd
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion Resources/Private/Partials/Box/Lead/Information.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ <h3 class="panel-title">
<img src="{f:uri.resource(path:'Images/AvatarDefault.svg',extensionName:'lux')}" alt="{visitor.fullName}" data-lux-asynchronous-image="{visitor.uid}" width="150" height="150" style="max-width: 100%; margin-top: 20px;" class="img-circle img-responsive" />
</div>
<div class="col-md-9">
<h3 title="UID{visitor.uid}">
<h3 title="UID{visitor.uid}{visitor.anonymousPostfix}">
{visitor.fullName}
<span class="badge" title="{f:translate(key:'LLL:EXT:lux/Resources/Private/Language/locallang_db.xlf:tx_lux_domain_model_visitor.scoring')}">{visitor.scoring}</span>
<f:if condition="{visitor.hottestCategoryscoring}">
Expand Down
Loading

0 comments on commit f548a32

Please sign in to comment.