Skip to content

Commit

Permalink
[FEATURE] Respect permissions for dashboard
Browse files Browse the repository at this point in the history
  • Loading branch information
einpraegsam committed Mar 5, 2024
1 parent 32ae3ea commit 958b43c
Show file tree
Hide file tree
Showing 9 changed files with 191 additions and 107 deletions.
30 changes: 18 additions & 12 deletions Classes/Controller/NewsletterController.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,29 @@

class NewsletterController extends AbstractNewsletterController
{
public function dashboardAction(): ResponseInterface
public function initializeDashboardAction(): void
{
$this->setFilter();
}

public function dashboardAction(Filter $filter): ResponseInterface
{
$this->view->assignMultiple(
[
'statistic' => [
'overallReceivers' => $this->logRepository->getNumberOfReceivers(),
'overallOpenings' => $this->logRepository->getOverallOpenings(),
'openingsByClickers' => $this->logRepository->getOpeningsByClickers(),
'overallClicks' => $this->logRepository->getOverallClicks(),
'overallUnsubscribes' => $this->logRepository->getOverallUnsubscribes(),
'overallMailsSent' => $this->logRepository->getOverallMailsSent(),
'overallOpenRate' => $this->logRepository->getOverallOpenRate(),
'overallClickRate' => $this->logRepository->getOverallClickRate(),
'overallUnsubscribeRate' => $this->logRepository->getOverallUnsubscribeRate(),
'overallReceivers' => $this->logRepository->getNumberOfReceivers($filter),
'overallOpenings' => $this->logRepository->getOverallOpenings($filter),
'openingsByClickers' => $this->logRepository->getOpeningsByClickers($filter),
'overallClicks' => $this->logRepository->getOverallClicks($filter),
'overallUnsubscribes' => $this->logRepository->getOverallUnsubscribes($filter),
'overallMailsSent' => $this->logRepository->getOverallMailsSent($filter),
'overallOpenRate' => $this->logRepository->getOverallOpenRate($filter),
'overallClickRate' => $this->logRepository->getOverallClickRate($filter),
'overallUnsubscribeRate' => $this->logRepository->getOverallUnsubscribeRate($filter),
],
'groupedLinksByHref' => $this->logRepository->getGroupedLinksByHref(),
'newsletters' => $this->newsletterRepository->findAll()->getQuery()->setLimit(10)->execute(),
'filter' => $filter,
'groupedLinksByHref' => $this->logRepository->getGroupedLinksByHref($filter->setLimit(8)),
'newsletters' => $this->newsletterRepository->findAllAuthorized($filter->setLimit(10)),
]
);

Expand Down
17 changes: 17 additions & 0 deletions Classes/Domain/Model/Dto/Filter.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class Filter
protected ?Configuration $configuration = null;

protected int $time = self::TIME_DEFAULT;
protected int $limit = 0;

/**
* This is just a dummy property, that helps to recognize if a filter is set and helps to save this to the session
Expand Down Expand Up @@ -160,6 +161,22 @@ public function setTime(int $time): Filter
return $this;
}

public function getLimit(): int
{
return $this->limit;
}

public function isLimitSet(): bool
{
return $this->getLimit() > 0;
}

public function setLimit(int $limit): self
{
$this->limit = $limit;
return $this;
}

public function isReset(): bool
{
return $this->reset;
Expand Down
165 changes: 89 additions & 76 deletions Classes/Domain/Repository/LogRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,35 @@
declare(strict_types=1);
namespace In2code\Luxletter\Domain\Repository;

use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Driver\Exception;
use Doctrine\DBAL\Exception as ExceptionDbal;
use In2code\Luxletter\Domain\Model\Configuration;
use In2code\Luxletter\Domain\Model\Dto\Filter;
use In2code\Luxletter\Domain\Model\Log;
use In2code\Luxletter\Domain\Model\Newsletter;
use In2code\Luxletter\Domain\Model\User;
use In2code\Luxletter\Utility\ArrayUtility;
use In2code\Luxletter\Utility\DatabaseUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;

/**
* Class LogRepository
*/
class LogRepository extends AbstractRepository
{
/**
* @param Filter $filter
* @return int
* @throws Exception
* @throws ExceptionDbal
*/
public function getNumberOfReceivers(): int
public function getNumberOfReceivers(Filter $filter): int
{
$connection = DatabaseUtility::getConnectionForTable(Log::TABLE_NAME);
return (int)$connection->executeQuery(
'select count(DISTINCT user) from ' . Log::TABLE_NAME .
' where deleted=0 and status=' . Log::STATUS_DISPATCH . ';'
)->fetchOne();
$sql = 'select count(distinct user) '
. ' from ' . Log::TABLE_NAME . ' l'
. ' left join ' . Newsletter::TABLE_NAME . ' nl on nl.uid=l.newsletter'
. ' left join ' . Configuration::TABLE_NAME . ' c on nl.configuration=c.uid'
. ' where l.deleted=0 and l.status=' . Log::STATUS_DISPATCH
. ' and c.site in ("' . implode('","', $filter->getSitesForFilter()) . '")'
. ' limit 1';
return (int)$connection->executeQuery($sql)->fetchOne();
}

/**
Expand All @@ -42,18 +44,23 @@ public function getNumberOfReceivers(): int
* 'target' => 'https://de.wikipedia.org/wiki/Haushund'
* ]
*
* @param int $limit
* @param Filter $filter
* @return array
* @throws DBALException
* @throws ExceptionDbal
*/
public function getGroupedLinksByHref(int $limit = 8): array
public function getGroupedLinksByHref(Filter $filter): array
{
$connection = DatabaseUtility::getConnectionForTable(Log::TABLE_NAME);
$results = (array)$connection->executeQuery(
'select count(*) as count, properties, newsletter from ' . Log::TABLE_NAME .
' where deleted=0 and status=' . Log::STATUS_LINKOPENING .
' group by properties,newsletter order by count desc limit ' . $limit
)->fetchAll();
$sql = 'select count(*) as count, l.properties, l.newsletter, l.uid'
. ' from ' . Log::TABLE_NAME . ' l'
. ' left join ' . Newsletter::TABLE_NAME . ' nl on nl.uid=l.newsletter'
. ' left join ' . Configuration::TABLE_NAME . ' c on nl.configuration=c.uid'
. ' where l.deleted=0 and l.status=' . Log::STATUS_LINKOPENING
. ' and c.site in ("' . implode('","', $filter->getSitesForFilter()) . '")'
. ' group by l.properties, l.newsletter, l.uid'
. ' order by count desc'
. ' limit ' . $filter->getLimit();
$results = $connection->executeQuery($sql)->fetchAllAssociative();
$nlRepository = GeneralUtility::makeInstance(NewsletterRepository::class);
foreach ($results as &$result) {
$result['target'] = json_decode($result['properties'], true)['target'];
Expand All @@ -63,118 +70,127 @@ public function getGroupedLinksByHref(int $limit = 8): array
}

/**
* @param Filter $filter
* @return int
* @throws Exception
* @throws ExceptionDbal
*/
public function getOverallOpenings(): int
public function getOverallOpenings(Filter $filter): int
{
$connection = DatabaseUtility::getConnectionForTable(Log::TABLE_NAME);
return (int)$connection->executeQuery(
'select count(distinct newsletter, user) from ' . Log::TABLE_NAME .
' where deleted = 0' .
' and status IN (' . Log::STATUS_NEWSLETTEROPENING . ',' . Log::STATUS_LINKOPENING . ')' . ';'
)->fetchOne();
$sql = 'select count(distinct newsletter, user)'
. ' from ' . Log::TABLE_NAME . ' l'
. ' left join ' . Newsletter::TABLE_NAME . ' nl on nl.uid=l.newsletter'
. ' left join ' . Configuration::TABLE_NAME . ' c on nl.configuration=c.uid'
. ' where l.deleted = 0'
. ' and l.status IN (' . Log::STATUS_NEWSLETTEROPENING . ',' . Log::STATUS_LINKOPENING . ')'
. ' and c.site in ("' . implode('","', $filter->getSitesForFilter()) . '")';
return (int)$connection->executeQuery($sql)->fetchOne();
}

/**
* @param Filter $filter
* @return int
* @throws DBALException
* @throws Exception
* @throws ExceptionDbal
*/
public function getOpeningsByClickers(): int
public function getOpeningsByClickers(Filter $filter): int
{
$connection = DatabaseUtility::getConnectionForTable(Log::TABLE_NAME);
return (int)$connection->executeQuery(
'select count(distinct newsletter, user) from ' . Log::TABLE_NAME .
' where deleted = 0 and status=' . Log::STATUS_LINKOPENING . ';'
)->fetchOne();
$sql = 'select count(distinct newsletter, user)'
. ' from ' . Log::TABLE_NAME . ' l'
. ' left join ' . Newsletter::TABLE_NAME . ' nl on nl.uid=l.newsletter'
. ' left join ' . Configuration::TABLE_NAME . ' c on nl.configuration=c.uid'
. ' where l.deleted = 0 and l.status=' . Log::STATUS_LINKOPENING
. ' and c.site in ("' . implode('","', $filter->getSitesForFilter()) . '")';
return (int)$connection->executeQuery($sql)->fetchOne();
}

/**
* @param Filter $filter
* @return int
* @throws Exception
* @throws ExceptionDbal
*/
public function getOverallClicks(): int
public function getOverallClicks(Filter $filter): int
{
$connection = DatabaseUtility::getConnectionForTable(Log::TABLE_NAME);
return (int)$connection->executeQuery(
'select count(uid) from ' . Log::TABLE_NAME .
' where deleted = 0 and status=' . Log::STATUS_LINKOPENING . ';'
)->fetchOne();
return $this->getOverallAmountByLogStatus([Log::STATUS_LINKOPENING], $filter);
}

/**
* @param Filter $filter
* @return int
* @throws Exception
* @throws ExceptionDbal
*/
public function getOverallUnsubscribes(): int
public function getOverallUnsubscribes(Filter $filter): int
{
$connection = DatabaseUtility::getConnectionForTable(Log::TABLE_NAME);
return (int)$connection->executeQuery(
'select count(uid) from ' . Log::TABLE_NAME .
' where deleted = 0 and status=' . Log::STATUS_UNSUBSCRIBE . ';'
)->fetchOne();
return $this->getOverallAmountByLogStatus([Log::STATUS_UNSUBSCRIBE], $filter);
}

/**
* @param Filter $filter
* @return int
* @throws ExceptionDbal
*/
public function getOverallMailsSent(Filter $filter): int
{
return $this->getOverallAmountByLogStatus([Log::STATUS_DISPATCH], $filter);
}

/**
* @param array $status
* @param Filter $filter
* @return int
* @throws Exception
* @throws ExceptionDbal
*/
public function getOverallMailsSent(): int
protected function getOverallAmountByLogStatus(array $status, Filter $filter): int
{
$connection = DatabaseUtility::getConnectionForTable(Log::TABLE_NAME);
return (int)$connection->executeQuery(
'select count(uid) from ' . Log::TABLE_NAME .
' where deleted = 0 and status=' . Log::STATUS_DISPATCH . ';'
)->fetchOne();
$sql = 'select count(l.uid)'
. ' from ' . Log::TABLE_NAME . ' l'
. ' left join ' . Newsletter::TABLE_NAME . ' nl on nl.uid=l.newsletter'
. ' left join ' . Configuration::TABLE_NAME . ' c on nl.configuration=c.uid'
. ' where l.deleted = 0 and l.status in (' . ArrayUtility::convertArrayToIntegerList($status) . ')'
. ' and c.site in ("' . implode('","', $filter->getSitesForFilter()) . '")';
return (int)$connection->executeQuery($sql)->fetchOne();
}

/**
* @param Filter $filter
* @return float
* @throws DBALException
* @throws Exception
* @throws ExceptionDbal
*/
public function getOverallOpenRate(): float
public function getOverallOpenRate(Filter $filter): float
{
$overallSent = $this->getOverallMailsSent();
$overallOpenings = $this->getOverallOpenings();
$overallSent = $this->getOverallMailsSent($filter);
$overallOpenings = $this->getOverallOpenings($filter);
if ($overallSent > 0) {
return $overallOpenings / $overallSent;
}
return 0.0;
}

/**
* @param Filter $filter
* @return float
* @throws DBALException
* @throws Exception
* @throws ExceptionDbal
*/
public function getOverallClickRate(): float
public function getOverallClickRate(Filter $filter): float
{
$overallOpenings = $this->getOverallOpenings();
$openingsByClickers = $this->getOpeningsByClickers();
$overallOpenings = $this->getOverallOpenings($filter);
$openingsByClickers = $this->getOpeningsByClickers($filter);
if ($overallOpenings > 0) {
return $openingsByClickers / $overallOpenings;
}
return 0.0;
}

/**
* @param Filter $filter
* @return float
* @throws DBALException
* @throws Exception
* @throws ExceptionDbal
*/
public function getOverallUnsubscribeRate(): float
public function getOverallUnsubscribeRate(Filter $filter): float
{
$overallOpenings = $this->getOverallOpenings();
$overallUnsubscribes = $this->getOverallUnsubscribes();
$overallOpenings = $this->getOverallOpenings($filter);
$overallUnsubscribes = $this->getOverallUnsubscribes($filter);
if ($overallOpenings > 0) {
return $overallUnsubscribes / $overallOpenings;
}
Expand All @@ -186,8 +202,7 @@ public function getOverallUnsubscribeRate(): float
* @param User $user
* @param int $status
* @return bool
* @throws Exception
* @throws DBALException
* @throws ExceptionDbal
*/
public function isLogRecordExisting(Newsletter $newsletter, User $user, int $status): bool
{
Expand All @@ -197,7 +212,7 @@ public function isLogRecordExisting(Newsletter $newsletter, User $user, int $sta
->from(Log::TABLE_NAME)
->where('newsletter=' . $newsletter->getUid() . ' and user=' . $user->getUid() . ' and status=' . $status)
->setMaxResults(1)
->execute()
->executeQuery()
->fetchOne();
return $uid > 0;
}
Expand All @@ -207,8 +222,7 @@ public function isLogRecordExisting(Newsletter $newsletter, User $user, int $sta
* @param int[] $status
* @param bool $distinctMails
* @return array
* @throws DBALException
* @throws Exception
* @throws ExceptionDbal
*/
public function findByNewsletterAndStatus(Newsletter $newsletter, array $status, bool $distinctMails = true): array
{
Expand All @@ -217,7 +231,7 @@ public function findByNewsletterAndStatus(Newsletter $newsletter, array $status,
if ($distinctMails === true) {
$sqlSelectColumns = 'distinct newsletter, user';
}
return (array)$connection->executeQuery(
return $connection->executeQuery(
'select ' . $sqlSelectColumns . ' from ' . Log::TABLE_NAME .
' where deleted=0 and status in (' . implode(',', $status) . ') and newsletter=' . $newsletter->getUid()
)->fetchAllAssociative();
Expand All @@ -228,8 +242,7 @@ public function findByNewsletterAndStatus(Newsletter $newsletter, array $status,
* @param array $statusWhitelist only want logs with this status (overrules any values from $statusBlacklist)
* @param array $statusBlacklist ignore logs with this status
* @return array
* @throws DBALException
* @throws Exception
* @throws ExceptionDbal
*/
public function findRawByUser(User $user, array $statusWhitelist = [], array $statusBlacklist = []): array
{
Expand Down
6 changes: 6 additions & 0 deletions Classes/Domain/Repository/NewsletterRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ public function findAllAuthorized(Filter $filter): QueryResultInterface
$siteService = GeneralUtility::makeInstance(SiteService::class);
$query->matching($query->in('configuration.site', array_keys($siteService->getAllowedSites())));
}
if ($filter->isLimitSet()) {
$query->setLimit($filter->getLimit());
}
return $query->execute();
}

Expand Down Expand Up @@ -104,6 +107,9 @@ protected function findAllByFilter(Filter $filter): ?QueryResultInterface
}
$logicalAnd[] = $query->in('configuration.site', $filter->getSitesForFilter());
$query->matching($query->logicalAnd(...$logicalAnd));
if ($filter->isLimitSet()) {
$query->setLimit($filter->getLimit());
}
return $query->execute();
}

Expand Down
Loading

0 comments on commit 958b43c

Please sign in to comment.