mirror of
https://github.com/DanielSiepmann/tracking.git
synced 2024-11-16 11:16:09 +01:00
WIP|Add flags feature
Allow each tracking record to contain arbitrary tags. Those tags are generated via an API and can be extended by foreign extensions or for individual projects. Existing operating_system was moved to this new feature. The update command allows to migrate existing records to this new feature. Those flags can be used when configuring widgets. A new flag was added bot:yes and bot:no. Bots are now tracked but flagged. That new feature allows to build fine grained reports and makes the extension way more flexible. Possible new implications: - Show visits from none bots - Show visits from bots - Show visits from specific bot - Add color to page views per page (bar chart) to color bot or none bot WIP: - Update Yaml file to work like before, no bots in widgets - Add documentation (widgets) - Add documentation (migration *.yaml)
This commit is contained in:
parent
1dbdaac9c6
commit
5f0490f493
62 changed files with 2574 additions and 960 deletions
|
@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||||
namespace DanielSiepmann\Tracking\Command;
|
namespace DanielSiepmann\Tracking\Command;
|
||||||
|
|
||||||
use DanielSiepmann\Tracking\Domain\Repository\Pageview;
|
use DanielSiepmann\Tracking\Domain\Repository\Pageview;
|
||||||
|
use DanielSiepmann\Tracking\Domain\Repository\Recordview;
|
||||||
use Symfony\Component\Console\Command\Command;
|
use Symfony\Component\Console\Command\Command;
|
||||||
use Symfony\Component\Console\Helper\ProgressBar;
|
use Symfony\Component\Console\Helper\ProgressBar;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
@ -35,33 +36,58 @@ class UpdateDataCommand extends Command
|
||||||
/**
|
/**
|
||||||
* @var Pageview
|
* @var Pageview
|
||||||
*/
|
*/
|
||||||
private $repository;
|
private $pageviews;
|
||||||
|
|
||||||
public function __construct(Pageview $repository)
|
/**
|
||||||
{
|
* @var Recordview
|
||||||
$this->repository = $repository;
|
*/
|
||||||
|
private $recordviews;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
Pageview $pageviews,
|
||||||
|
Recordview $recordviews
|
||||||
|
) {
|
||||||
|
$this->pageviews = $pageviews;
|
||||||
|
$this->recordviews = $recordviews;
|
||||||
|
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function configure(): void
|
protected function configure(): void
|
||||||
{
|
{
|
||||||
$this->setDescription('Updates existing data.');
|
$this->setHelp('Converts legacy data to new format if necessary. Runs incrementel to work with large data sets.');
|
||||||
$this->setHelp('In case some more data can be extracted of the existing data.');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||||
{
|
{
|
||||||
$io = new SymfonyStyle($input, $output);
|
$io = new SymfonyStyle($input, $output);
|
||||||
$io->progressStart($this->repository->countAll());
|
|
||||||
|
|
||||||
foreach ($this->repository->findAll() as $pageView) {
|
$io->writeln('Updating: Pageviews');
|
||||||
$this->repository->update($pageView);
|
$this->update($this->pageviews, $io);
|
||||||
$io->progressAdvance();
|
$io->writeln('Updating: Recordviews');
|
||||||
}
|
$this->update($this->recordviews, $io);
|
||||||
|
|
||||||
$io->progressFinish();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Pageview|Recordview $repository
|
||||||
|
*/
|
||||||
|
private function update(
|
||||||
|
$repository,
|
||||||
|
SymfonyStyle $io
|
||||||
|
): void {
|
||||||
|
$count = $repository->findLegacyCount();
|
||||||
|
if ($count === 0) {
|
||||||
|
$io->writeln('No more data to update.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$io->progressStart($count);
|
||||||
|
foreach ($repository->findLegacy() as $data) {
|
||||||
|
$repository->update($data);
|
||||||
|
$io->progressAdvance();
|
||||||
|
}
|
||||||
|
$io->progressFinish();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
181
Classes/Dashboard/Provider/Demand.php
Normal file
181
Classes/Dashboard/Provider/Demand.php
Normal file
|
@ -0,0 +1,181 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace DanielSiepmann\Tracking\Dashboard\Provider;
|
||||||
|
|
||||||
|
use DanielSiepmann\Tracking\Dashboard\Provider\Demand\Tag;
|
||||||
|
use TYPO3\CMS\Core\Database\Connection;
|
||||||
|
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
|
||||||
|
|
||||||
|
class Demand
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
private $days;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
private $maxResults;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int[]
|
||||||
|
*/
|
||||||
|
private $pagesToExclude;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int[]
|
||||||
|
*/
|
||||||
|
private $languageLimitation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Tag[]
|
||||||
|
*/
|
||||||
|
private $tagConstraints;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int[] $pagesToExclude
|
||||||
|
* @param int[] $languageLimitation
|
||||||
|
* @param Tag[] $tagConstraints
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
int $days = 31,
|
||||||
|
int $maxResults = 6,
|
||||||
|
array $pagesToExclude = [],
|
||||||
|
array $languageLimitation = [],
|
||||||
|
array $tagConstraints = []
|
||||||
|
) {
|
||||||
|
$this->days = $days;
|
||||||
|
$this->maxResults = $maxResults;
|
||||||
|
$this->pagesToExclude = array_map('intval', $pagesToExclude);
|
||||||
|
$this->languageLimitation = array_map('intval', $languageLimitation);
|
||||||
|
$this->tagConstraints = $tagConstraints;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDays(): int
|
||||||
|
{
|
||||||
|
return $this->days;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMaxResults(): int
|
||||||
|
{
|
||||||
|
return $this->maxResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int[]
|
||||||
|
*/
|
||||||
|
public function getPagesToExclude(): array
|
||||||
|
{
|
||||||
|
return $this->pagesToExclude;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int[]
|
||||||
|
*/
|
||||||
|
public function getLanguageLimitation(): array
|
||||||
|
{
|
||||||
|
return $this->languageLimitation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Tag[]
|
||||||
|
*/
|
||||||
|
public function getTagConstraints(): array
|
||||||
|
{
|
||||||
|
return $this->tagConstraints;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addJoins(
|
||||||
|
QueryBuilder $queryBuilder,
|
||||||
|
string $tableName
|
||||||
|
): void {
|
||||||
|
if ($this->getTagConstraints() !== []) {
|
||||||
|
$queryBuilder->leftJoin(
|
||||||
|
$tableName,
|
||||||
|
'tx_tracking_tag',
|
||||||
|
'tx_tracking_tag',
|
||||||
|
(string) $queryBuilder->expr()->andX(
|
||||||
|
$queryBuilder->expr()->eq(
|
||||||
|
'tx_tracking_tag.record_table_name',
|
||||||
|
$queryBuilder->createNamedParameter($tableName)
|
||||||
|
),
|
||||||
|
$queryBuilder->expr()->eq(
|
||||||
|
'tx_tracking_tag.record_uid',
|
||||||
|
$queryBuilder->quoteIdentifier($tableName . '.uid')
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public function getConstraints(
|
||||||
|
QueryBuilder $queryBuilder,
|
||||||
|
string $tableName
|
||||||
|
): array {
|
||||||
|
$constraints = [];
|
||||||
|
|
||||||
|
if ($this->getPagesToExclude() !== []) {
|
||||||
|
$constraints[] = (string) $queryBuilder->expr()->notIn(
|
||||||
|
$tableName . '.pid',
|
||||||
|
$queryBuilder->createNamedParameter(
|
||||||
|
$this->getPagesToExclude(),
|
||||||
|
Connection::PARAM_INT_ARRAY
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->getLanguageLimitation() !== []) {
|
||||||
|
$constraints[] = (string) $queryBuilder->expr()->in(
|
||||||
|
$tableName . '.sys_language_uid',
|
||||||
|
$queryBuilder->createNamedParameter(
|
||||||
|
$this->getLanguageLimitation(),
|
||||||
|
Connection::PARAM_INT_ARRAY
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->getTagConstraints() as $tagConstraint) {
|
||||||
|
$constraints[] = (string) $queryBuilder->expr()->andX(
|
||||||
|
$queryBuilder->expr()->eq(
|
||||||
|
'tx_tracking_tag.name',
|
||||||
|
$queryBuilder->createNamedParameter(
|
||||||
|
$tagConstraint->getName()
|
||||||
|
)
|
||||||
|
),
|
||||||
|
$queryBuilder->expr()->eq(
|
||||||
|
'tx_tracking_tag.value',
|
||||||
|
$queryBuilder->createNamedParameter(
|
||||||
|
$tagConstraint->getValue()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $constraints;
|
||||||
|
}
|
||||||
|
}
|
64
Classes/Dashboard/Provider/Demand/Tag.php
Normal file
64
Classes/Dashboard/Provider/Demand/Tag.php
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace DanielSiepmann\Tracking\Dashboard\Provider\Demand;
|
||||||
|
|
||||||
|
class Tag
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $value;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
string $name,
|
||||||
|
string $value
|
||||||
|
) {
|
||||||
|
// TODO: Add Validate
|
||||||
|
$this->name = $name;
|
||||||
|
$this->value = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function createFromArray(array $parameters): self
|
||||||
|
{
|
||||||
|
return new self(
|
||||||
|
$parameters['name'],
|
||||||
|
$parameters['value']
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(): string
|
||||||
|
{
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getValue(): string
|
||||||
|
{
|
||||||
|
return $this->value;
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,63 +35,35 @@ class NewestPageviews implements ListDataProviderInterface
|
||||||
private $queryBuilder;
|
private $queryBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int
|
* @var Demand
|
||||||
*/
|
*/
|
||||||
private $maxResults;
|
private $demand;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $pagesToExclude;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array<int>
|
|
||||||
*/
|
|
||||||
private $languageLimitation;
|
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
QueryBuilder $queryBuilder,
|
QueryBuilder $queryBuilder,
|
||||||
int $maxResults = 6,
|
Demand $demand
|
||||||
array $pagesToExclude = [],
|
|
||||||
array $languageLimitation = []
|
|
||||||
) {
|
) {
|
||||||
$this->queryBuilder = $queryBuilder;
|
$this->queryBuilder = $queryBuilder;
|
||||||
$this->maxResults = $maxResults;
|
$this->demand = $demand;
|
||||||
$this->pagesToExclude = $pagesToExclude;
|
|
||||||
$this->languageLimitation = $languageLimitation;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getItems(): array
|
public function getItems(): array
|
||||||
{
|
{
|
||||||
$preparedItems = [];
|
$preparedItems = [];
|
||||||
|
|
||||||
$constraints = [];
|
$constraints = $this->demand->getConstraints(
|
||||||
if (count($this->pagesToExclude)) {
|
$this->queryBuilder,
|
||||||
$constraints[] = $this->queryBuilder->expr()->notIn(
|
'tx_tracking_pageview'
|
||||||
'tx_tracking_pageview.pid',
|
);
|
||||||
$this->queryBuilder->createNamedParameter(
|
|
||||||
$this->pagesToExclude,
|
|
||||||
Connection::PARAM_INT_ARRAY
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count($this->languageLimitation)) {
|
$this->demand->addJoins($this->queryBuilder, 'tx_tracking_pageview');
|
||||||
$constraints[] = $this->queryBuilder->expr()->in(
|
|
||||||
'tx_tracking_pageview.sys_language_uid',
|
|
||||||
$this->queryBuilder->createNamedParameter(
|
|
||||||
$this->languageLimitation,
|
|
||||||
Connection::PARAM_INT_ARRAY
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->queryBuilder
|
$this->queryBuilder
|
||||||
->select('url', 'user_agent')
|
->select('url', 'user_agent')
|
||||||
->from('tx_tracking_pageview')
|
->from('tx_tracking_pageview')
|
||||||
->orderBy('crdate', 'desc')
|
->orderBy('crdate', 'desc')
|
||||||
->addOrderBy('uid', 'desc')
|
->addOrderBy('uid', 'desc')
|
||||||
->setMaxResults($this->maxResults);
|
->setMaxResults($this->demand->getMaxResults());
|
||||||
|
|
||||||
if ($constraints !== []) {
|
if ($constraints !== []) {
|
||||||
$this->queryBuilder->where(...$constraints);
|
$this->queryBuilder->where(...$constraints);
|
||||||
|
|
|
@ -43,38 +43,24 @@ class PageviewsPerDay implements ChartDataProviderInterface
|
||||||
private $queryBuilder;
|
private $queryBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int
|
* @var Demand
|
||||||
*/
|
*/
|
||||||
private $days;
|
private $demand;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array<int>
|
|
||||||
*/
|
|
||||||
private $pagesToExclude;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $dateFormat;
|
private $dateFormat;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array<int>
|
|
||||||
*/
|
|
||||||
private $languageLimitation;
|
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
LanguageService $languageService,
|
LanguageService $languageService,
|
||||||
QueryBuilder $queryBuilder,
|
QueryBuilder $queryBuilder,
|
||||||
int $days = 31,
|
Demand $demand,
|
||||||
array $pagesToExclude = [],
|
|
||||||
array $languageLimitation = [],
|
|
||||||
string $dateFormat = 'Y-m-d'
|
string $dateFormat = 'Y-m-d'
|
||||||
) {
|
) {
|
||||||
$this->languageService = $languageService;
|
$this->languageService = $languageService;
|
||||||
$this->queryBuilder = $queryBuilder;
|
$this->queryBuilder = $queryBuilder;
|
||||||
$this->days = $days;
|
$this->demand = $demand;
|
||||||
$this->pagesToExclude = $pagesToExclude;
|
|
||||||
$this->languageLimitation = $languageLimitation;
|
|
||||||
$this->dateFormat = $dateFormat;
|
$this->dateFormat = $dateFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,13 +88,13 @@ class PageviewsPerDay implements ChartDataProviderInterface
|
||||||
$labels = [];
|
$labels = [];
|
||||||
$data = [];
|
$data = [];
|
||||||
|
|
||||||
for ($daysBefore = $this->days; $daysBefore >= 0; $daysBefore--) {
|
for ($daysBefore = $this->demand->getDays(); $daysBefore >= 0; $daysBefore--) {
|
||||||
$label = date($this->dateFormat, (int) strtotime('-' . $daysBefore . ' day'));
|
$label = date($this->dateFormat, (int) strtotime('-' . $daysBefore . ' day'));
|
||||||
$labels[$label] = $label;
|
$labels[$label] = $label;
|
||||||
$data[$label] = 0;
|
$data[$label] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
$start = (int) strtotime('-' . $this->days . ' day 0:00:00');
|
$start = (int) strtotime('-' . $this->demand->getDays() . ' day 0:00:00');
|
||||||
$end = (int) strtotime('tomorrow midnight');
|
$end = (int) strtotime('tomorrow midnight');
|
||||||
|
|
||||||
|
|
||||||
|
@ -125,32 +111,19 @@ class PageviewsPerDay implements ChartDataProviderInterface
|
||||||
private function getPageviewsInPeriod(int $start, int $end): array
|
private function getPageviewsInPeriod(int $start, int $end): array
|
||||||
{
|
{
|
||||||
$constraints = [
|
$constraints = [
|
||||||
$this->queryBuilder->expr()->gte('crdate', $start),
|
$this->queryBuilder->expr()->gte('tx_tracking_pageview.crdate', $start),
|
||||||
$this->queryBuilder->expr()->lte('crdate', $end),
|
$this->queryBuilder->expr()->lte('tx_tracking_pageview.crdate', $end),
|
||||||
];
|
];
|
||||||
|
|
||||||
if (count($this->pagesToExclude)) {
|
$constraints = array_merge($constraints, $this->demand->getConstraints(
|
||||||
$constraints[] = $this->queryBuilder->expr()->notIn(
|
$this->queryBuilder,
|
||||||
'tx_tracking_pageview.pid',
|
'tx_tracking_pageview'
|
||||||
$this->queryBuilder->createNamedParameter(
|
));
|
||||||
$this->pagesToExclude,
|
|
||||||
Connection::PARAM_INT_ARRAY
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count($this->languageLimitation)) {
|
$this->demand->addJoins($this->queryBuilder, 'tx_tracking_pageview');
|
||||||
$constraints[] = $this->queryBuilder->expr()->in(
|
|
||||||
'tx_tracking_pageview.sys_language_uid',
|
|
||||||
$this->queryBuilder->createNamedParameter(
|
|
||||||
$this->languageLimitation,
|
|
||||||
Connection::PARAM_INT_ARRAY
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->queryBuilder
|
$this->queryBuilder
|
||||||
->addSelectLiteral('COUNT(*) as "count"')
|
->addSelectLiteral('COUNT(tx_tracking_pageview.uid) as "count"')
|
||||||
->from('tx_tracking_pageview')
|
->from('tx_tracking_pageview')
|
||||||
->where(...$constraints)
|
->where(...$constraints)
|
||||||
->groupBy('label')
|
->groupBy('label')
|
||||||
|
@ -158,9 +131,9 @@ class PageviewsPerDay implements ChartDataProviderInterface
|
||||||
;
|
;
|
||||||
|
|
||||||
if ($this->queryBuilder->getConnection()->getDatabasePlatform()->getName() === 'sqlite') {
|
if ($this->queryBuilder->getConnection()->getDatabasePlatform()->getName() === 'sqlite') {
|
||||||
$this->queryBuilder->addSelectLiteral('date(crdate, "unixepoch") as "label"');
|
$this->queryBuilder->addSelectLiteral('date(tx_tracking_pageview.crdate, "unixepoch") as "label"');
|
||||||
} else {
|
} else {
|
||||||
$this->queryBuilder->addSelectLiteral('FROM_UNIXTIME(crdate, "%Y-%m-%d") as "label"');
|
$this->queryBuilder->addSelectLiteral('FROM_UNIXTIME(tx_tracking_pageview.crdate, "%Y-%m-%d") as "label"');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->queryBuilder->execute()->fetchAll();
|
return $this->queryBuilder->execute()->fetchAll();
|
||||||
|
|
|
@ -36,30 +36,16 @@ class PageviewsPerOperatingSystem implements ChartDataProviderInterface
|
||||||
private $queryBuilder;
|
private $queryBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int
|
* @var Demand
|
||||||
*/
|
*/
|
||||||
private $days;
|
private $demand;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
private $maxResults;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array<int>
|
|
||||||
*/
|
|
||||||
private $languageLimitation;
|
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
QueryBuilder $queryBuilder,
|
QueryBuilder $queryBuilder,
|
||||||
int $days = 31,
|
Demand $demand
|
||||||
int $maxResults = 6,
|
|
||||||
array $languageLimitation = []
|
|
||||||
) {
|
) {
|
||||||
$this->queryBuilder = $queryBuilder;
|
$this->queryBuilder = $queryBuilder;
|
||||||
$this->days = $days;
|
$this->demand = $demand;
|
||||||
$this->maxResults = $maxResults;
|
|
||||||
$this->languageLimitation = $languageLimitation;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getChartData(): array
|
public function getChartData(): array
|
||||||
|
@ -85,33 +71,42 @@ class PageviewsPerOperatingSystem implements ChartDataProviderInterface
|
||||||
$constraints = [
|
$constraints = [
|
||||||
$this->queryBuilder->expr()->gte(
|
$this->queryBuilder->expr()->gte(
|
||||||
'tx_tracking_pageview.crdate',
|
'tx_tracking_pageview.crdate',
|
||||||
strtotime('-' . $this->days . ' day 0:00:00')
|
strtotime('-' . $this->demand->getDays() . ' day 0:00:00')
|
||||||
),
|
),
|
||||||
$this->queryBuilder->expr()->neq(
|
$this->queryBuilder->expr()->neq(
|
||||||
'tx_tracking_pageview.operating_system',
|
'operating_system',
|
||||||
$this->queryBuilder->createNamedParameter('')
|
$this->queryBuilder->createNamedParameter('')
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
if (count($this->languageLimitation)) {
|
$constraints = array_merge($constraints, $this->demand->getConstraints(
|
||||||
$constraints[] = $this->queryBuilder->expr()->in(
|
$this->queryBuilder,
|
||||||
'tx_tracking_pageview.sys_language_uid',
|
'tx_tracking_pageview'
|
||||||
$this->queryBuilder->createNamedParameter(
|
));
|
||||||
$this->languageLimitation,
|
|
||||||
Connection::PARAM_INT_ARRAY
|
$this->demand->addJoins($this->queryBuilder, 'tx_tracking_pageview');
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = $this->queryBuilder
|
$result = $this->queryBuilder
|
||||||
->selectLiteral('count(operating_system) as total')
|
->addSelect('tag.value as operating_system')
|
||||||
->addSelect('operating_system')
|
->addSelectLiteral(
|
||||||
|
'count(' . $this->queryBuilder->quoteIdentifier('operating_system') . ') as total'
|
||||||
|
)
|
||||||
->from('tx_tracking_pageview')
|
->from('tx_tracking_pageview')
|
||||||
|
->leftJoin(
|
||||||
|
'tx_tracking_pageview',
|
||||||
|
'tx_tracking_tag',
|
||||||
|
'tag',
|
||||||
|
(string) $this->queryBuilder->expr()->andX(
|
||||||
|
$this->queryBuilder->expr()->eq('tx_tracking_pageview.uid', $this->queryBuilder->quoteIdentifier('tag.record_uid')),
|
||||||
|
$this->queryBuilder->expr()->eq('tag.name', $this->queryBuilder->createNamedParameter('os')),
|
||||||
|
$this->queryBuilder->expr()->eq('tag.record_table_name', $this->queryBuilder->createNamedParameter('tx_tracking_pageview'))
|
||||||
|
)
|
||||||
|
)
|
||||||
->where(...$constraints)
|
->where(...$constraints)
|
||||||
->groupBy('tx_tracking_pageview.operating_system')
|
->groupBy('operating_system')
|
||||||
->orderBy('total', 'desc')
|
->orderBy('total', 'desc')
|
||||||
->addOrderBy('operating_system', 'asc')
|
->addOrderBy('operating_system', 'asc')
|
||||||
->setMaxResults($this->maxResults)
|
->setMaxResults($this->demand->getMaxResults())
|
||||||
->execute()
|
->execute()
|
||||||
->fetchAll();
|
->fetchAll();
|
||||||
|
|
||||||
|
|
|
@ -45,39 +45,18 @@ class PageviewsPerPage implements ChartDataProviderInterface
|
||||||
private $pageRepository;
|
private $pageRepository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int
|
* @var Demand
|
||||||
*/
|
*/
|
||||||
private $days;
|
private $demand;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
private $maxResults;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array<int>
|
|
||||||
*/
|
|
||||||
private $pagesToExclude;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array<int>
|
|
||||||
*/
|
|
||||||
private $languageLimitation;
|
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
QueryBuilder $queryBuilder,
|
QueryBuilder $queryBuilder,
|
||||||
PageRepository $pageRepository,
|
PageRepository $pageRepository,
|
||||||
int $days = 31,
|
Demand $demand
|
||||||
int $maxResults = 6,
|
|
||||||
array $pagesToExclude = [],
|
|
||||||
array $languageLimitation = []
|
|
||||||
) {
|
) {
|
||||||
$this->queryBuilder = $queryBuilder;
|
$this->queryBuilder = $queryBuilder;
|
||||||
$this->pageRepository = $pageRepository;
|
$this->pageRepository = $pageRepository;
|
||||||
$this->days = $days;
|
$this->demand = $demand;
|
||||||
$this->maxResults = $maxResults;
|
|
||||||
$this->pagesToExclude = $pagesToExclude;
|
|
||||||
$this->languageLimitation = $languageLimitation;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getChartData(): array
|
public function getChartData(): array
|
||||||
|
@ -99,45 +78,33 @@ class PageviewsPerPage implements ChartDataProviderInterface
|
||||||
{
|
{
|
||||||
$labels = [];
|
$labels = [];
|
||||||
$data = [];
|
$data = [];
|
||||||
|
|
||||||
$constraints = [
|
$constraints = [
|
||||||
$this->queryBuilder->expr()->gte(
|
(string) $this->queryBuilder->expr()->gte(
|
||||||
'tx_tracking_pageview.crdate',
|
'tx_tracking_pageview.crdate',
|
||||||
strtotime('-' . $this->days . ' day 0:00:00')
|
strtotime('-' . $this->demand->getDays() . ' day 0:00:00')
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
if (count($this->pagesToExclude)) {
|
$constraints = array_merge($constraints, $this->demand->getConstraints(
|
||||||
$constraints[] = $this->queryBuilder->expr()->notIn(
|
$this->queryBuilder,
|
||||||
'tx_tracking_pageview.pid',
|
'tx_tracking_pageview'
|
||||||
$this->queryBuilder->createNamedParameter(
|
));
|
||||||
$this->pagesToExclude,
|
$this->demand->addJoins(
|
||||||
Connection::PARAM_INT_ARRAY
|
$this->queryBuilder,
|
||||||
)
|
'tx_tracking_pageview'
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
if (count($this->languageLimitation)) {
|
|
||||||
$constraints[] = $this->queryBuilder->expr()->in(
|
|
||||||
'tx_tracking_pageview.sys_language_uid',
|
|
||||||
$this->queryBuilder->createNamedParameter(
|
|
||||||
$this->languageLimitation,
|
|
||||||
Connection::PARAM_INT_ARRAY
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = $this->queryBuilder
|
$result = $this->queryBuilder
|
||||||
->selectLiteral(
|
->selectLiteral(
|
||||||
$this->queryBuilder->expr()->count('pid', 'total'),
|
$this->queryBuilder->expr()->count('tx_tracking_pageview.pid', 'total'),
|
||||||
$this->queryBuilder->expr()->max('uid', 'latest')
|
$this->queryBuilder->expr()->max('tx_tracking_pageview.uid', 'latest')
|
||||||
)
|
)
|
||||||
->addSelect('pid')
|
->addSelect('tx_tracking_pageview.pid')
|
||||||
->from('tx_tracking_pageview')
|
->from('tx_tracking_pageview')
|
||||||
->where(...$constraints)
|
->where(...$constraints)
|
||||||
->groupBy('pid')
|
->groupBy('tx_tracking_pageview.pid')
|
||||||
->orderBy('total', 'desc')
|
->orderBy('total', 'desc')
|
||||||
->addOrderBy('latest', 'desc')
|
->addOrderBy('latest', 'desc')
|
||||||
->setMaxResults($this->maxResults)
|
->setMaxResults($this->demand->getMaxResults())
|
||||||
->execute()
|
->execute()
|
||||||
->fetchAll();
|
->fetchAll();
|
||||||
|
|
||||||
|
@ -159,8 +126,8 @@ class PageviewsPerPage implements ChartDataProviderInterface
|
||||||
private function getRecordTitle(int $uid): string
|
private function getRecordTitle(int $uid): string
|
||||||
{
|
{
|
||||||
$record = BackendUtility::getRecord('pages', $uid);
|
$record = BackendUtility::getRecord('pages', $uid);
|
||||||
if (count($this->languageLimitation) === 1 && $record !== null) {
|
if (count($this->demand->getLanguageLimitation()) === 1 && $record !== null) {
|
||||||
$record = $this->pageRepository->getRecordOverlay('pages', $record, $this->languageLimitation[0]);
|
$record = $this->pageRepository->getRecordOverlay('pages', $record, $this->demand->getLanguageLimitation()[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_array($record) === false) {
|
if (is_array($record) === false) {
|
||||||
|
|
|
@ -49,24 +49,9 @@ class Recordviews implements ChartDataProviderInterface
|
||||||
private $queryBuilder;
|
private $queryBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int
|
* @var Demand
|
||||||
*/
|
*/
|
||||||
private $days;
|
private $demand;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
private $maxResults;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array<int>
|
|
||||||
*/
|
|
||||||
private $pagesToExclude;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array<int>
|
|
||||||
*/
|
|
||||||
private $languageLimitation;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
|
@ -81,19 +66,13 @@ class Recordviews implements ChartDataProviderInterface
|
||||||
public function __construct(
|
public function __construct(
|
||||||
PageRepository $pageRepository,
|
PageRepository $pageRepository,
|
||||||
QueryBuilder $queryBuilder,
|
QueryBuilder $queryBuilder,
|
||||||
int $days = 31,
|
Demand $demand,
|
||||||
int $maxResults = 6,
|
|
||||||
array $pagesToExclude = [],
|
|
||||||
array $languageLimitation = [],
|
|
||||||
array $recordTableLimitation = [],
|
array $recordTableLimitation = [],
|
||||||
array $recordTypeLimitation = []
|
array $recordTypeLimitation = []
|
||||||
) {
|
) {
|
||||||
$this->pageRepository = $pageRepository;
|
$this->pageRepository = $pageRepository;
|
||||||
$this->queryBuilder = $queryBuilder;
|
$this->queryBuilder = $queryBuilder;
|
||||||
$this->days = $days;
|
$this->demand = $demand;
|
||||||
$this->pagesToExclude = $pagesToExclude;
|
|
||||||
$this->languageLimitation = $languageLimitation;
|
|
||||||
$this->maxResults = $maxResults;
|
|
||||||
$this->recordTableLimitation = $recordTableLimitation;
|
$this->recordTableLimitation = $recordTableLimitation;
|
||||||
$this->recordTypeLimitation = $recordTypeLimitation;
|
$this->recordTypeLimitation = $recordTypeLimitation;
|
||||||
}
|
}
|
||||||
|
@ -152,30 +131,10 @@ class Recordviews implements ChartDataProviderInterface
|
||||||
$constraints = [
|
$constraints = [
|
||||||
$this->queryBuilder->expr()->gte(
|
$this->queryBuilder->expr()->gte(
|
||||||
'tx_tracking_recordview.crdate',
|
'tx_tracking_recordview.crdate',
|
||||||
strtotime('-' . $this->days . ' day 0:00:00')
|
strtotime('-' . $this->demand->getDays() . ' day 0:00:00')
|
||||||
)
|
)
|
||||||
];
|
];
|
||||||
|
|
||||||
if (count($this->pagesToExclude)) {
|
|
||||||
$constraints[] = $this->queryBuilder->expr()->notIn(
|
|
||||||
'tx_tracking_recordview.pid',
|
|
||||||
$this->queryBuilder->createNamedParameter(
|
|
||||||
$this->pagesToExclude,
|
|
||||||
Connection::PARAM_INT_ARRAY
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count($this->languageLimitation)) {
|
|
||||||
$constraints[] = $this->queryBuilder->expr()->in(
|
|
||||||
'tx_tracking_recordview.sys_language_uid',
|
|
||||||
$this->queryBuilder->createNamedParameter(
|
|
||||||
$this->languageLimitation,
|
|
||||||
Connection::PARAM_INT_ARRAY
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count($this->recordTableLimitation)) {
|
if (count($this->recordTableLimitation)) {
|
||||||
$constraints[] = $this->queryBuilder->expr()->in(
|
$constraints[] = $this->queryBuilder->expr()->in(
|
||||||
'tx_tracking_recordview.record_table_name',
|
'tx_tracking_recordview.record_table_name',
|
||||||
|
@ -186,6 +145,15 @@ class Recordviews implements ChartDataProviderInterface
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$constraints = array_merge($constraints, $this->demand->getConstraints(
|
||||||
|
$this->queryBuilder,
|
||||||
|
'tx_tracking_recordview'
|
||||||
|
));
|
||||||
|
$this->demand->addJoins(
|
||||||
|
$this->queryBuilder,
|
||||||
|
'tx_tracking_recordview'
|
||||||
|
);
|
||||||
|
|
||||||
$result = $this->queryBuilder
|
$result = $this->queryBuilder
|
||||||
->selectLiteral(
|
->selectLiteral(
|
||||||
$this->queryBuilder->expr()->count('record', 'total'),
|
$this->queryBuilder->expr()->count('record', 'total'),
|
||||||
|
@ -197,7 +165,7 @@ class Recordviews implements ChartDataProviderInterface
|
||||||
->groupBy('record', 'record_uid', 'record_table_name')
|
->groupBy('record', 'record_uid', 'record_table_name')
|
||||||
->orderBy('total', 'desc')
|
->orderBy('total', 'desc')
|
||||||
->addOrderBy('latest', 'desc')
|
->addOrderBy('latest', 'desc')
|
||||||
->setMaxResults($this->maxResults)
|
->setMaxResults($this->demand->getMaxResults())
|
||||||
->execute();
|
->execute();
|
||||||
|
|
||||||
while ($row = $result->fetch()) {
|
while ($row = $result->fetch()) {
|
||||||
|
@ -212,8 +180,8 @@ class Recordviews implements ChartDataProviderInterface
|
||||||
$recordTypeField = $GLOBALS['TCA'][$table]['ctrl']['type'] ?? '';
|
$recordTypeField = $GLOBALS['TCA'][$table]['ctrl']['type'] ?? '';
|
||||||
|
|
||||||
$record = BackendUtility::getRecord($table, $uid);
|
$record = BackendUtility::getRecord($table, $uid);
|
||||||
if (count($this->languageLimitation) === 1 && $record !== null) {
|
if (count($this->demand->getLanguageLimitation()) === 1 && $record !== null) {
|
||||||
$record = $this->pageRepository->getRecordOverlay($table, $record, $this->languageLimitation[0]);
|
$record = $this->pageRepository->getRecordOverlay($table, $record, $this->demand->getLanguageLimitation()[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_array($record) === false) {
|
if (is_array($record) === false) {
|
||||||
|
|
88
Classes/Domain/Extractors/Bots.php
Normal file
88
Classes/Domain/Extractors/Bots.php
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace DanielSiepmann\Tracking\Domain\Extractors;
|
||||||
|
|
||||||
|
use DanielSiepmann\Tracking\Domain\Extractors\Bots\CustomBotParser;
|
||||||
|
use DanielSiepmann\Tracking\Domain\Model\Pageview;
|
||||||
|
use DanielSiepmann\Tracking\Domain\Model\Recordview;
|
||||||
|
use DeviceDetector\DeviceDetector;
|
||||||
|
|
||||||
|
class Bots implements PageviewExtractor, RecordviewExtractor
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var CustomBotParser
|
||||||
|
*/
|
||||||
|
private $customBotParser;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
CustomBotParser $customBotParser
|
||||||
|
) {
|
||||||
|
$this->customBotParser = $customBotParser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function extractTagFromPageview(Pageview $pageview): array
|
||||||
|
{
|
||||||
|
return $this->getTagsForUserAgent($pageview->getUserAgent());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function extractTagFromRecordview(Recordview $recordview): array
|
||||||
|
{
|
||||||
|
return $this->getTagsForUserAgent($recordview->getUserAgent());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Tag[]
|
||||||
|
*/
|
||||||
|
private function getTagsForUserAgent(string $userAgent): array
|
||||||
|
{
|
||||||
|
$botNameTag = new Tag('bot_name', $this->getBotName($userAgent));
|
||||||
|
|
||||||
|
if ($botNameTag->getValue() !== '') {
|
||||||
|
return [
|
||||||
|
new Tag('bot', 'yes'),
|
||||||
|
$botNameTag,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return [new Tag('bot', 'no')];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getBotName(string $userAgent): string
|
||||||
|
{
|
||||||
|
$deviceDetector = new DeviceDetector();
|
||||||
|
$deviceDetector->addBotParser($this->customBotParser);
|
||||||
|
$deviceDetector->setUserAgent($userAgent);
|
||||||
|
$deviceDetector->parse();
|
||||||
|
|
||||||
|
if ($deviceDetector->isBot() === false) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$bot = $deviceDetector->getBot();
|
||||||
|
if (is_array($bot) === false) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $bot['name'] ?? '';
|
||||||
|
}
|
||||||
|
}
|
56
Classes/Domain/Extractors/Bots/CustomBotParser.php
Normal file
56
Classes/Domain/Extractors/Bots/CustomBotParser.php
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace DanielSiepmann\Tracking\Domain\Extractors\Bots;
|
||||||
|
|
||||||
|
use DeviceDetector\Parser\Bot;
|
||||||
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
|
|
||||||
|
class CustomBotParser extends Bot
|
||||||
|
{
|
||||||
|
protected $parserName = 'customBots';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $dirName = '';
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$fixtureFile = GeneralUtility::getFileAbsFileName('EXT:tracking/Configuration/Bots.yaml');
|
||||||
|
$this->fixtureFile = basename($fixtureFile);
|
||||||
|
$this->dirName = dirname($fixtureFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getRegexesDirectory(): string
|
||||||
|
{
|
||||||
|
return $this->dirName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function parse(): ?array
|
||||||
|
{
|
||||||
|
return parent::parse();
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
* Copyright (C) 2021 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -21,17 +21,25 @@ declare(strict_types=1);
|
||||||
* 02110-1301, USA.
|
* 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace DanielSiepmann\Tracking\Domain\Model;
|
namespace DanielSiepmann\Tracking\Domain\Extractors;
|
||||||
|
|
||||||
/**
|
use DanielSiepmann\Tracking\Domain\Model\Pageview;
|
||||||
* API to extract further info out of an model.
|
use DanielSiepmann\Tracking\Domain\Model\Recordview;
|
||||||
*/
|
|
||||||
class Extractor
|
class OperatingSystem implements PageviewExtractor, RecordviewExtractor
|
||||||
{
|
{
|
||||||
public static function getOperatingSystem(HasUserAgent $model): string
|
public function extractTagFromPageview(Pageview $pageview): array
|
||||||
{
|
{
|
||||||
$userAgent = $model->getUserAgent();
|
return [new Tag('os', $this->getOperatingSystem($pageview->getUserAgent()))];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function extractTagFromRecordview(Recordview $recordview): array
|
||||||
|
{
|
||||||
|
return [new Tag('os', $this->getOperatingSystem($recordview->getUserAgent()))];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getOperatingSystem(string $userAgent): string
|
||||||
|
{
|
||||||
if (mb_stripos($userAgent, 'Android') !== false) {
|
if (mb_stripos($userAgent, 'Android') !== false) {
|
||||||
return 'Android';
|
return 'Android';
|
||||||
}
|
}
|
||||||
|
@ -57,6 +65,6 @@ class Extractor
|
||||||
return 'iOS';
|
return 'iOS';
|
||||||
}
|
}
|
||||||
|
|
||||||
return '';
|
return 'Unkown';
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -21,9 +21,17 @@ declare(strict_types=1);
|
||||||
* 02110-1301, USA.
|
* 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace DanielSiepmann\Tracking\Domain\Model;
|
namespace DanielSiepmann\Tracking\Domain\Extractors;
|
||||||
|
|
||||||
interface HasUserAgent
|
use DanielSiepmann\Tracking\Domain\Model\Pageview;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API to extract further info out of an model.
|
||||||
|
*/
|
||||||
|
interface PageviewExtractor
|
||||||
{
|
{
|
||||||
public function getUserAgent(): string;
|
/**
|
||||||
|
* @return Tag[]
|
||||||
|
*/
|
||||||
|
public function extractTagFromPageview(Pageview $pageview): array;
|
||||||
}
|
}
|
37
Classes/Domain/Extractors/RecordviewExtractor.php
Normal file
37
Classes/Domain/Extractors/RecordviewExtractor.php
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace DanielSiepmann\Tracking\Domain\Extractors;
|
||||||
|
|
||||||
|
use DanielSiepmann\Tracking\Domain\Model\Recordview;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API to extract further info out of an model.
|
||||||
|
*/
|
||||||
|
interface RecordviewExtractor
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return Tag[]
|
||||||
|
*/
|
||||||
|
public function extractTagFromRecordview(Recordview $recordview): array;
|
||||||
|
}
|
74
Classes/Domain/Extractors/Registry.php
Normal file
74
Classes/Domain/Extractors/Registry.php
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace DanielSiepmann\Tracking\Domain\Extractors;
|
||||||
|
|
||||||
|
use DanielSiepmann\Tracking\Domain\Model\Pageview;
|
||||||
|
use DanielSiepmann\Tracking\Domain\Model\Recordview;
|
||||||
|
|
||||||
|
class Registry
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var PageviewExtractor[]
|
||||||
|
*/
|
||||||
|
protected $pageviewExtractors = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var RecordviewExtractor[]
|
||||||
|
*/
|
||||||
|
protected $recordviewExtractors = [];
|
||||||
|
|
||||||
|
public function addPageviewExtractor(PageviewExtractor $extractor): void
|
||||||
|
{
|
||||||
|
$this->pageviewExtractors[] = $extractor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addRecordviewExtractor(RecordviewExtractor $extractor): void
|
||||||
|
{
|
||||||
|
$this->recordviewExtractors[] = $extractor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Tag[]
|
||||||
|
*/
|
||||||
|
public function getTagsForPageview(Pageview $pageview): array
|
||||||
|
{
|
||||||
|
$tags = [];
|
||||||
|
foreach ($this->pageviewExtractors as $extractor) {
|
||||||
|
$tags = array_merge($tags, $extractor->extractTagFromPageview($pageview));
|
||||||
|
}
|
||||||
|
return $tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Tag[]
|
||||||
|
*/
|
||||||
|
public function getTagsForRecordview(Recordview $recordview): array
|
||||||
|
{
|
||||||
|
$tags = [];
|
||||||
|
foreach ($this->recordviewExtractors as $extractor) {
|
||||||
|
$tags = array_merge($tags, $extractor->extractTagFromRecordview($recordview));
|
||||||
|
}
|
||||||
|
return $tags;
|
||||||
|
}
|
||||||
|
}
|
57
Classes/Domain/Extractors/Tag.php
Normal file
57
Classes/Domain/Extractors/Tag.php
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace DanielSiepmann\Tracking\Domain\Extractors;
|
||||||
|
|
||||||
|
class Tag
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* E.g. "os" or "bot", some unique identifier.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $name = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $value = '';
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
string $name,
|
||||||
|
string $value
|
||||||
|
) {
|
||||||
|
$this->name = $name;
|
||||||
|
$this->value = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(): string
|
||||||
|
{
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getValue(): string
|
||||||
|
{
|
||||||
|
return $this->value;
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,7 +25,7 @@ namespace DanielSiepmann\Tracking\Domain\Model;
|
||||||
|
|
||||||
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
|
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
|
||||||
|
|
||||||
class Pageview implements HasUserAgent
|
class Pageview
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var int
|
* @var int
|
||||||
|
@ -114,9 +114,4 @@ class Pageview implements HasUserAgent
|
||||||
{
|
{
|
||||||
return $this->userAgent;
|
return $this->userAgent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getOperatingSystem(): string
|
|
||||||
{
|
|
||||||
return Extractor::getOperatingSystem($this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,8 +25,13 @@ namespace DanielSiepmann\Tracking\Domain\Model;
|
||||||
|
|
||||||
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
|
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
|
||||||
|
|
||||||
class Recordview implements HasUserAgent
|
class Recordview
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
private $uid = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int
|
* @var int
|
||||||
*/
|
*/
|
||||||
|
@ -69,8 +74,10 @@ class Recordview implements HasUserAgent
|
||||||
string $url,
|
string $url,
|
||||||
string $userAgent,
|
string $userAgent,
|
||||||
int $recordUid,
|
int $recordUid,
|
||||||
string $tableName
|
string $tableName,
|
||||||
|
int $uid = 0
|
||||||
) {
|
) {
|
||||||
|
$this->uid = $uid;
|
||||||
$this->pageUid = $pageUid;
|
$this->pageUid = $pageUid;
|
||||||
$this->language = $language;
|
$this->language = $language;
|
||||||
$this->crdate = $crdate;
|
$this->crdate = $crdate;
|
||||||
|
@ -80,6 +87,11 @@ class Recordview implements HasUserAgent
|
||||||
$this->tableName = $tableName;
|
$this->tableName = $tableName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getUid(): int
|
||||||
|
{
|
||||||
|
return $this->uid;
|
||||||
|
}
|
||||||
|
|
||||||
public function getPageUid(): int
|
public function getPageUid(): int
|
||||||
{
|
{
|
||||||
return $this->pageUid;
|
return $this->pageUid;
|
||||||
|
@ -114,9 +126,4 @@ class Recordview implements HasUserAgent
|
||||||
{
|
{
|
||||||
return $this->tableName;
|
return $this->tableName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getOperatingSystem(): string
|
|
||||||
{
|
|
||||||
return Extractor::getOperatingSystem($this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
|
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
|
||||||
use TYPO3\CMS\Core\Routing\PageArguments;
|
use TYPO3\CMS\Core\Routing\PageArguments;
|
||||||
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
|
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
|
||||||
|
use TYPO3\CMS\Core\Site\SiteFinder;
|
||||||
|
|
||||||
class Factory
|
class Factory
|
||||||
{
|
{
|
||||||
|
@ -38,9 +39,16 @@ class Factory
|
||||||
*/
|
*/
|
||||||
private $expressionFactory;
|
private $expressionFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var SiteFinder
|
||||||
|
*/
|
||||||
|
private $siteFinder;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
|
SiteFinder $siteFinder,
|
||||||
ExpressionFactory $expressionFactory
|
ExpressionFactory $expressionFactory
|
||||||
) {
|
) {
|
||||||
|
$this->siteFinder = $siteFinder;
|
||||||
$this->expressionFactory = $expressionFactory;
|
$this->expressionFactory = $expressionFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,6 +83,20 @@ class Factory
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function fromDbRow(array $dbRow): Recordview
|
||||||
|
{
|
||||||
|
return new Recordview(
|
||||||
|
$dbRow['pid'],
|
||||||
|
$this->siteFinder->getSiteByPageId($dbRow['pid'])->getLanguageById($dbRow['sys_language_uid']),
|
||||||
|
new \DateTimeImmutable('@' . $dbRow['crdate']),
|
||||||
|
$dbRow['url'],
|
||||||
|
$dbRow['user_agent'],
|
||||||
|
$dbRow['record_uid'],
|
||||||
|
$dbRow['record_table_name'],
|
||||||
|
$dbRow['uid']
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private static function getLanguage(ServerRequestInterface $request): SiteLanguage
|
private static function getLanguage(ServerRequestInterface $request): SiteLanguage
|
||||||
{
|
{
|
||||||
$language = $request->getAttribute('language');
|
$language = $request->getAttribute('language');
|
||||||
|
|
|
@ -25,6 +25,7 @@ namespace DanielSiepmann\Tracking\Domain\Repository;
|
||||||
|
|
||||||
use DanielSiepmann\Tracking\Domain\Model\Pageview as Model;
|
use DanielSiepmann\Tracking\Domain\Model\Pageview as Model;
|
||||||
use DanielSiepmann\Tracking\Domain\Pageview\Factory;
|
use DanielSiepmann\Tracking\Domain\Pageview\Factory;
|
||||||
|
use DanielSiepmann\Tracking\Extension;
|
||||||
use TYPO3\CMS\Core\Database\Connection;
|
use TYPO3\CMS\Core\Database\Connection;
|
||||||
|
|
||||||
class Pageview
|
class Pageview
|
||||||
|
@ -39,33 +40,50 @@ class Pageview
|
||||||
*/
|
*/
|
||||||
private $factory;
|
private $factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Tag
|
||||||
|
*/
|
||||||
|
private $tagRepository;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
Connection $connection,
|
Connection $connection,
|
||||||
Factory $factory
|
Factory $factory,
|
||||||
|
Tag $tagRepository
|
||||||
) {
|
) {
|
||||||
$this->connection = $connection;
|
$this->connection = $connection;
|
||||||
$this->factory = $factory;
|
$this->factory = $factory;
|
||||||
|
$this->tagRepository = $tagRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function countAll(): int
|
public function findLegacyCount(): int
|
||||||
{
|
|
||||||
$result = $this->connection->createQueryBuilder()
|
|
||||||
->count('uid')
|
|
||||||
->from('tx_tracking_pageview')
|
|
||||||
->execute()
|
|
||||||
->fetchColumn();
|
|
||||||
|
|
||||||
if (is_numeric($result)) {
|
|
||||||
return (int) $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function findAll(): \Generator
|
|
||||||
{
|
{
|
||||||
$queryBuilder = $this->connection->createQueryBuilder();
|
$queryBuilder = $this->connection->createQueryBuilder();
|
||||||
$pageViews = $queryBuilder->select('*')->from('tx_tracking_pageview')->execute();
|
$queryBuilder->count('*');
|
||||||
|
$queryBuilder->from('tx_tracking_pageview');
|
||||||
|
$queryBuilder->where($queryBuilder->expr()->neq('compatible_version', $queryBuilder->createNamedParameter(Extension::getCompatibleVersionNow())));
|
||||||
|
$queryBuilder->setMaxResults(Extension::getMaximumRowsForUpdate());
|
||||||
|
|
||||||
|
$pageViews = $queryBuilder->execute()->fetchColumn();
|
||||||
|
if (is_numeric($pageViews) === false) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($pageViews > Extension::getMaximumRowsForUpdate()) {
|
||||||
|
return Extension::getMaximumRowsForUpdate();
|
||||||
|
}
|
||||||
|
return (int) $pageViews;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findLegacy(): \Generator
|
||||||
|
{
|
||||||
|
$queryBuilder = $this->connection->createQueryBuilder();
|
||||||
|
$queryBuilder->select('*');
|
||||||
|
$queryBuilder->from('tx_tracking_pageview');
|
||||||
|
$queryBuilder->where($queryBuilder->expr()->neq('compatible_version', $queryBuilder->createNamedParameter(Extension::getCompatibleVersionNow())));
|
||||||
|
$test = Extension::getCompatibleVersionNow();
|
||||||
|
$queryBuilder->setMaxResults(Extension::getMaximumRowsForUpdate());
|
||||||
|
|
||||||
|
$pageViews = $queryBuilder->execute();
|
||||||
|
|
||||||
while ($pageView = $pageViews->fetch()) {
|
while ($pageView = $pageViews->fetch()) {
|
||||||
if (is_array($pageView) === false) {
|
if (is_array($pageView) === false) {
|
||||||
|
@ -87,6 +105,8 @@ class Pageview
|
||||||
$this->getFieldsFromModel($pageview),
|
$this->getFieldsFromModel($pageview),
|
||||||
['uid' => $pageview->getUid()]
|
['uid' => $pageview->getUid()]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$this->tagRepository->updateForPageview($pageview);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function add(Model $pageview): void
|
public function add(Model $pageview): void
|
||||||
|
@ -95,6 +115,11 @@ class Pageview
|
||||||
'tx_tracking_pageview',
|
'tx_tracking_pageview',
|
||||||
$this->getFieldsFromModel($pageview)
|
$this->getFieldsFromModel($pageview)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$this->tagRepository->addForPageview(
|
||||||
|
$pageview,
|
||||||
|
(int) $this->connection->lastInsertId('tx_tracking_pageview')
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getFieldsFromModel(Model $pageview): array
|
private function getFieldsFromModel(Model $pageview): array
|
||||||
|
@ -107,7 +132,7 @@ class Pageview
|
||||||
'sys_language_uid' => $pageview->getLanguage()->getLanguageId(),
|
'sys_language_uid' => $pageview->getLanguage()->getLanguageId(),
|
||||||
'url' => $pageview->getUrl(),
|
'url' => $pageview->getUrl(),
|
||||||
'user_agent' => $pageview->getUserAgent(),
|
'user_agent' => $pageview->getUserAgent(),
|
||||||
'operating_system' => $pageview->getOperatingSystem(),
|
'compatible_version' => Extension::getCompatibleVersionNow(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,8 +24,13 @@ declare(strict_types=1);
|
||||||
namespace DanielSiepmann\Tracking\Domain\Repository;
|
namespace DanielSiepmann\Tracking\Domain\Repository;
|
||||||
|
|
||||||
use DanielSiepmann\Tracking\Domain\Model\Recordview as Model;
|
use DanielSiepmann\Tracking\Domain\Model\Recordview as Model;
|
||||||
|
use DanielSiepmann\Tracking\Domain\Recordview\Factory;
|
||||||
|
use DanielSiepmann\Tracking\Extension;
|
||||||
use TYPO3\CMS\Core\Database\Connection;
|
use TYPO3\CMS\Core\Database\Connection;
|
||||||
|
|
||||||
|
// TODO: Move common code to API class.
|
||||||
|
// Call API Class with table name
|
||||||
|
|
||||||
class Recordview
|
class Recordview
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -33,10 +38,77 @@ class Recordview
|
||||||
*/
|
*/
|
||||||
private $connection;
|
private $connection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Factory
|
||||||
|
*/
|
||||||
|
private $factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Tag
|
||||||
|
*/
|
||||||
|
private $tagRepository;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
Connection $connection
|
Connection $connection,
|
||||||
|
Factory $factory,
|
||||||
|
Tag $tagRepository
|
||||||
) {
|
) {
|
||||||
$this->connection = $connection;
|
$this->connection = $connection;
|
||||||
|
$this->factory = $factory;
|
||||||
|
$this->tagRepository = $tagRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findLegacyCount(): int
|
||||||
|
{
|
||||||
|
$queryBuilder = $this->connection->createQueryBuilder();
|
||||||
|
$queryBuilder->count('*');
|
||||||
|
$queryBuilder->from('tx_tracking_recordview');
|
||||||
|
$queryBuilder->where($queryBuilder->expr()->neq('compatible_version', $queryBuilder->createNamedParameter(Extension::getCompatibleVersionNow())));
|
||||||
|
$queryBuilder->setMaxResults(Extension::getMaximumRowsForUpdate());
|
||||||
|
|
||||||
|
$recordviews = $queryBuilder->execute()->fetchColumn();
|
||||||
|
if (is_numeric($recordviews) === false) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($recordviews > Extension::getMaximumRowsForUpdate()) {
|
||||||
|
return Extension::getMaximumRowsForUpdate();
|
||||||
|
}
|
||||||
|
return (int) $recordviews;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findLegacy(): \Generator
|
||||||
|
{
|
||||||
|
$queryBuilder = $this->connection->createQueryBuilder();
|
||||||
|
$queryBuilder->select('*');
|
||||||
|
$queryBuilder->from('tx_tracking_recordview');
|
||||||
|
$queryBuilder->where($queryBuilder->expr()->neq('compatible_version', $queryBuilder->createNamedParameter(Extension::getCompatibleVersionNow())));
|
||||||
|
$queryBuilder->setMaxResults(Extension::getMaximumRowsForUpdate());
|
||||||
|
|
||||||
|
$recordviews = $queryBuilder->execute();
|
||||||
|
|
||||||
|
while ($pageView = $recordviews->fetch()) {
|
||||||
|
if (is_array($pageView) === false) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
yield $this->factory->fromDbRow($pageView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update(Model $model): void
|
||||||
|
{
|
||||||
|
if ($model->getUid() === 0) {
|
||||||
|
throw new \InvalidArgumentException('Can not update recordview if uid is 0.', 1585770573);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->connection->update(
|
||||||
|
'tx_tracking_recordview',
|
||||||
|
$this->getFieldsFromModel($model),
|
||||||
|
['uid' => $model->getUid()]
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->tagRepository->updateForRecordview($model);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function add(Model $recordview): void
|
public function add(Model $recordview): void
|
||||||
|
@ -45,6 +117,11 @@ class Recordview
|
||||||
'tx_tracking_recordview',
|
'tx_tracking_recordview',
|
||||||
$this->getFieldsFromModel($recordview)
|
$this->getFieldsFromModel($recordview)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$this->tagRepository->addForRecordview(
|
||||||
|
$recordview,
|
||||||
|
(int) $this->connection->lastInsertId('tx_tracking_recordview')
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getFieldsFromModel(Model $recordview): array
|
private function getFieldsFromModel(Model $recordview): array
|
||||||
|
@ -56,10 +133,10 @@ class Recordview
|
||||||
'sys_language_uid' => $recordview->getLanguage()->getLanguageId(),
|
'sys_language_uid' => $recordview->getLanguage()->getLanguageId(),
|
||||||
'url' => $recordview->getUrl(),
|
'url' => $recordview->getUrl(),
|
||||||
'user_agent' => $recordview->getUserAgent(),
|
'user_agent' => $recordview->getUserAgent(),
|
||||||
'operating_system' => $recordview->getOperatingSystem(),
|
|
||||||
'record_uid' => $recordview->getRecordUid(),
|
'record_uid' => $recordview->getRecordUid(),
|
||||||
'record_table_name' => $recordview->getTableName(),
|
'record_table_name' => $recordview->getTableName(),
|
||||||
'record' => $recordview->getTableName() . '_' . $recordview->getRecordUid(),
|
'record' => $recordview->getTableName() . '_' . $recordview->getRecordUid(),
|
||||||
|
'compatible_version' => Extension::getCompatibleVersionNow(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
119
Classes/Domain/Repository/Tag.php
Normal file
119
Classes/Domain/Repository/Tag.php
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace DanielSiepmann\Tracking\Domain\Repository;
|
||||||
|
|
||||||
|
use DanielSiepmann\Tracking\Domain\Extractors\Registry;
|
||||||
|
use DanielSiepmann\Tracking\Domain\Extractors\Tag as Model;
|
||||||
|
use DanielSiepmann\Tracking\Domain\Model\Pageview;
|
||||||
|
use DanielSiepmann\Tracking\Domain\Model\Recordview;
|
||||||
|
use DanielSiepmann\Tracking\Extension;
|
||||||
|
use TYPO3\CMS\Core\Database\Connection;
|
||||||
|
|
||||||
|
class Tag
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var Connection
|
||||||
|
*/
|
||||||
|
private $connection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Registry
|
||||||
|
*/
|
||||||
|
private $extractorRegistry;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
Connection $connection,
|
||||||
|
Registry $extractorRegistry
|
||||||
|
) {
|
||||||
|
$this->connection = $connection;
|
||||||
|
$this->extractorRegistry = $extractorRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addForPageview(
|
||||||
|
Pageview $pageview,
|
||||||
|
int $recordUid
|
||||||
|
): void {
|
||||||
|
foreach ($this->extractorRegistry->getTagsForPageview($pageview) as $tag) {
|
||||||
|
$this->connection->insert(
|
||||||
|
'tx_tracking_tag',
|
||||||
|
[
|
||||||
|
'pid' => $pageview->getPageUid(),
|
||||||
|
'crdate' => $pageview->getCrdate()->format('U'),
|
||||||
|
'tstamp' => $pageview->getCrdate()->format('U'),
|
||||||
|
'record_uid' => $recordUid,
|
||||||
|
'record_table_name' => 'tx_tracking_pageview',
|
||||||
|
'name' => $tag->getName(),
|
||||||
|
'value' => $tag->getValue(),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateForPageview(
|
||||||
|
Pageview $pageview
|
||||||
|
): void {
|
||||||
|
$this->connection->delete(
|
||||||
|
'tx_tracking_tag',
|
||||||
|
[
|
||||||
|
'record_uid' => $pageview->getUid(),
|
||||||
|
'record_table_name' => 'tx_tracking_pageview',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$this->addForPageview($pageview, $pageview->getUid());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addForRecordview(
|
||||||
|
Recordview $recordview,
|
||||||
|
int $recordUid
|
||||||
|
): void {
|
||||||
|
foreach ($this->extractorRegistry->getTagsForRecordview($recordview) as $tag) {
|
||||||
|
$this->connection->insert(
|
||||||
|
'tx_tracking_tag',
|
||||||
|
[
|
||||||
|
'pid' => $recordview->getPageUid(),
|
||||||
|
'crdate' => $recordview->getCrdate()->format('U'),
|
||||||
|
'tstamp' => $recordview->getCrdate()->format('U'),
|
||||||
|
'record_uid' => $recordUid,
|
||||||
|
'record_table_name' => 'tx_tracking_recordview',
|
||||||
|
'name' => $tag->getName(),
|
||||||
|
'value' => $tag->getValue(),
|
||||||
|
'compatible_version' => Extension::getCompatibleVersionNow(),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateForRecordview(
|
||||||
|
Recordview $recordview
|
||||||
|
): void {
|
||||||
|
$this->connection->delete(
|
||||||
|
'tx_tracking_tag',
|
||||||
|
[
|
||||||
|
'record_uid' => $recordview->getUid(),
|
||||||
|
'record_table_name' => 'tx_tracking_recordview',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$this->addForRecordview($recordview, $recordview->getUid());
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,4 +28,15 @@ final class Extension
|
||||||
public const EXT_KEY = 'tracking';
|
public const EXT_KEY = 'tracking';
|
||||||
|
|
||||||
public const LANGUAGE_PATH = 'LLL:EXT:' . self::EXT_KEY . '/Resources/Private/Language/locallang.xlf';
|
public const LANGUAGE_PATH = 'LLL:EXT:' . self::EXT_KEY . '/Resources/Private/Language/locallang.xlf';
|
||||||
|
|
||||||
|
public static function getCompatibleVersionNow(): string
|
||||||
|
{
|
||||||
|
return 'v2.0.0';
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getMaximumRowsForUpdate(): int
|
||||||
|
{
|
||||||
|
// TODO: Make configurable
|
||||||
|
return 3500;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
18
Configuration/Bots.yaml
Normal file
18
Configuration/Bots.yaml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
- regex: 'nettle'
|
||||||
|
name: 'Nettle'
|
||||||
|
- regex: 'crusty'
|
||||||
|
name: 'Crusty'
|
||||||
|
- regex: 'Faraday'
|
||||||
|
name: 'Faraday'
|
||||||
|
- regex: 'newspaper'
|
||||||
|
name: 'Newspaper'
|
||||||
|
- regex: 'uni-passau'
|
||||||
|
name: 'Uni Passau'
|
||||||
|
- regex: 'Upflow'
|
||||||
|
name: 'Upflow'
|
||||||
|
- regex: 'MauiBot'
|
||||||
|
name: 'Maui Bot'
|
||||||
|
- regex: 'Java'
|
||||||
|
name: 'Java'
|
||||||
|
- regex: 'python-requests'
|
||||||
|
name: 'Python Requests'
|
40
Configuration/Services.php
Normal file
40
Configuration/Services.php
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DanielSiepmann\Tracking;
|
||||||
|
|
||||||
|
use DanielSiepmann\Tracking\Domain\Extractors\PageviewExtractor;
|
||||||
|
use DanielSiepmann\Tracking\Domain\Extractors\RecordviewExtractor;
|
||||||
|
use DanielSiepmann\Tracking\Domain\Extractors\Registry;
|
||||||
|
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
|
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||||
|
|
||||||
|
return function (ContainerConfigurator $containerConfiguration, ContainerBuilder $containerBuilder) {
|
||||||
|
$containerBuilder->registerForAutoconfiguration(PageviewExtractor::class)->addTag('tracking.extractor.pageview');
|
||||||
|
$containerBuilder->registerForAutoconfiguration(RecordviewExtractor::class)->addTag('tracking.extractor.recordview');
|
||||||
|
$containerBuilder->addCompilerPass(new class() implements CompilerPassInterface {
|
||||||
|
public function process(ContainerBuilder $containerBuilder): void
|
||||||
|
{
|
||||||
|
$registry = $containerBuilder->findDefinition(Registry::class);
|
||||||
|
foreach ($containerBuilder->findTaggedServiceIds('tracking.extractor.pageview') as $id => $tags) {
|
||||||
|
$definition = $containerBuilder->findDefinition($id);
|
||||||
|
if (!$definition->isAutoconfigured() || $definition->isAbstract()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$registry->addMethodCall('addPageviewExtractor', [$definition]);
|
||||||
|
}
|
||||||
|
foreach ($containerBuilder->findTaggedServiceIds('tracking.extractor.recordview') as $id => $tags) {
|
||||||
|
$definition = $containerBuilder->findDefinition($id);
|
||||||
|
if (!$definition->isAutoconfigured() || $definition->isAbstract()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$registry->addMethodCall('addRecordviewExtractor', [$definition]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
|
@ -43,6 +43,14 @@ services:
|
||||||
arguments:
|
arguments:
|
||||||
- 'tx_tracking_recordview'
|
- 'tx_tracking_recordview'
|
||||||
|
|
||||||
|
dbconnection.tx_tracking_tag:
|
||||||
|
class: 'TYPO3\CMS\Core\Database\Connection'
|
||||||
|
factory:
|
||||||
|
- '@TYPO3\CMS\Core\Database\ConnectionPool'
|
||||||
|
- 'getConnectionForTable'
|
||||||
|
arguments:
|
||||||
|
- 'tx_tracking_tag'
|
||||||
|
|
||||||
DanielSiepmann\Tracking\Domain\Repository\Pageview:
|
DanielSiepmann\Tracking\Domain\Repository\Pageview:
|
||||||
public: true
|
public: true
|
||||||
arguments:
|
arguments:
|
||||||
|
@ -53,18 +61,17 @@ services:
|
||||||
arguments:
|
arguments:
|
||||||
- '@dbconnection.tx_tracking_recordview'
|
- '@dbconnection.tx_tracking_recordview'
|
||||||
|
|
||||||
|
DanielSiepmann\Tracking\Domain\Repository\Tag:
|
||||||
|
public: true
|
||||||
|
arguments:
|
||||||
|
- '@dbconnection.tx_tracking_tag'
|
||||||
|
|
||||||
DanielSiepmann\Tracking\Middleware\Pageview:
|
DanielSiepmann\Tracking\Middleware\Pageview:
|
||||||
public: true
|
public: true
|
||||||
arguments:
|
arguments:
|
||||||
$rule: >
|
$rule: >
|
||||||
not (context.getAspect("backend.user").isLoggedIn())
|
not (context.getAspect("backend.user").isLoggedIn())
|
||||||
and not (context.getAspect("frontend.preview").isPreview())
|
and not (context.getAspect("frontend.preview").isPreview())
|
||||||
and traverse(request.getHeader("User-Agent"), '0')
|
|
||||||
and not (request.getHeader("User-Agent")[0] matches "/^TYPO3|TYPO3 linkvalidator/")
|
|
||||||
and not (request.getHeader("User-Agent")[0] matches "/Wget|curl|Go-http-client/")
|
|
||||||
and not (request.getHeader("User-Agent")[0] matches "/Googlebot|Bingbot|bingbot|Slurp|DuckDuckBot|Baiduspider|YandexBot|Sogou|Exabot|NextCloud-News|Feedly|XING FeedReader|CCBot|SemrushBot|SEOkicks|Twitterbot|Seekport Crawler|SemanticScholarBot|ia_archiver|PaperLiBot|TrendsmapResolver|AhrefsBot|Nuzzel/")
|
|
||||||
and not (request.getHeader("User-Agent")[0] matches "/mattermost|Slackbot|WhatsApp/")
|
|
||||||
and not (request.getHeader("User-Agent")[0] matches "/UptimeRobot|Pingdom/")
|
|
||||||
|
|
||||||
DanielSiepmann\Tracking\Middleware\Recordview:
|
DanielSiepmann\Tracking\Middleware\Recordview:
|
||||||
public: true
|
public: true
|
||||||
|
@ -75,3 +82,4 @@ services:
|
||||||
tags:
|
tags:
|
||||||
- name: 'console.command'
|
- name: 'console.command'
|
||||||
command: 'tracking:updatedata'
|
command: 'tracking:updatedata'
|
||||||
|
description: 'Updates existing data.'
|
||||||
|
|
|
@ -17,7 +17,7 @@ return [
|
||||||
],
|
],
|
||||||
'types' => [
|
'types' => [
|
||||||
'0' => [
|
'0' => [
|
||||||
'showitem' => 'sys_language_uid, pid, url, user_agent, operating_system, type, crdate',
|
'showitem' => 'sys_language_uid, pid, url, user_agent, tags, type, crdate',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'columns' => [
|
'columns' => [
|
||||||
|
@ -56,10 +56,13 @@ return [
|
||||||
'readOnly' => true,
|
'readOnly' => true,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'operating_system' => [
|
'tags' => [
|
||||||
'label' => 'LLL:EXT:tracking/Resources/Private/Language/locallang_tca.xlf:table.pageview.operating_system',
|
'label' => 'LLL:EXT:tracking/Resources/Private/Language/locallang_tca.xlf:table.pageview.tags',
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'input',
|
'type' => 'inline',
|
||||||
|
'foreign_table' => 'tx_tracking_tag',
|
||||||
|
'foreign_field' => 'record_uid',
|
||||||
|
'foreign_table_field' => 'record_table_name',
|
||||||
'readOnly' => true,
|
'readOnly' => true,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|
|
@ -17,7 +17,7 @@ return [
|
||||||
],
|
],
|
||||||
'types' => [
|
'types' => [
|
||||||
'0' => [
|
'0' => [
|
||||||
'showitem' => 'sys_language_uid, pid, record, url, user_agent, operating_system, crdate',
|
'showitem' => 'sys_language_uid, pid, record, url, user_agent, tags, crdate',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'columns' => [
|
'columns' => [
|
||||||
|
@ -56,13 +56,6 @@ return [
|
||||||
'readOnly' => true,
|
'readOnly' => true,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'operating_system' => [
|
|
||||||
'label' => 'LLL:EXT:tracking/Resources/Private/Language/locallang_tca.xlf:table.recordview.operating_system',
|
|
||||||
'config' => [
|
|
||||||
'type' => 'input',
|
|
||||||
'readOnly' => true,
|
|
||||||
],
|
|
||||||
],
|
|
||||||
'url' => [
|
'url' => [
|
||||||
'label' => 'LLL:EXT:tracking/Resources/Private/Language/locallang_tca.xlf:table.recordview.url',
|
'label' => 'LLL:EXT:tracking/Resources/Private/Language/locallang_tca.xlf:table.recordview.url',
|
||||||
'config' => [
|
'config' => [
|
||||||
|
@ -82,5 +75,15 @@ return [
|
||||||
'size' => 1,
|
'size' => 1,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
'tags' => [
|
||||||
|
'label' => 'LLL:EXT:tracking/Resources/Private/Language/locallang_tca.xlf:table.recordview.tags',
|
||||||
|
'config' => [
|
||||||
|
'type' => 'inline',
|
||||||
|
'foreign_table' => 'tx_tracking_tag',
|
||||||
|
'foreign_field' => 'record_uid',
|
||||||
|
'foreign_table_field' => 'record_table_name',
|
||||||
|
'readOnly' => true,
|
||||||
|
],
|
||||||
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
67
Configuration/TCA/tx_tracking_tag.php
Normal file
67
Configuration/TCA/tx_tracking_tag.php
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'ctrl' => [
|
||||||
|
'label' => 'name',
|
||||||
|
'label_alt' => 'value',
|
||||||
|
'label_alt_force' => true,
|
||||||
|
'default_sortby' => 'crdate DESC',
|
||||||
|
'tstamp' => 'tstamp',
|
||||||
|
'crdate' => 'crdate',
|
||||||
|
'cruser_id' => 'cruser_id',
|
||||||
|
'hideTable' => true,
|
||||||
|
'title' => 'LLL:EXT:tracking/Resources/Private/Language/locallang_tca.xlf:table.tag',
|
||||||
|
],
|
||||||
|
'types' => [
|
||||||
|
'0' => [
|
||||||
|
'showitem' => 'pid, record_uid, record_table_name, name, value',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'columns' => [
|
||||||
|
'pid' => [
|
||||||
|
'label' => 'LLL:EXT:tracking/Resources/Private/Language/locallang_tca.xlf:table.tag.pid',
|
||||||
|
'config' => [
|
||||||
|
// TYPO3 v10 does no longer allow to resolve PID relations, e.g. via select or group
|
||||||
|
// This will break internal PID handling.
|
||||||
|
'type' => 'input',
|
||||||
|
'readOnly' => true,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'record_uid' => [
|
||||||
|
'label' => 'LLL:EXT:tracking/Resources/Private/Language/locallang_tca.xlf:table.tag.record_uid',
|
||||||
|
'config' => [
|
||||||
|
'type' => 'input',
|
||||||
|
'eval' => 'int',
|
||||||
|
'readOnly' => true,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'record_table_name' => [
|
||||||
|
'label' => 'LLL:EXT:tracking/Resources/Private/Language/locallang_tca.xlf:table.tag.record_table_name',
|
||||||
|
'config' => [
|
||||||
|
'type' => 'input',
|
||||||
|
'readOnly' => true,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'crdate' => [
|
||||||
|
'label' => 'LLL:EXT:tracking/Resources/Private/Language/locallang_tca.xlf:table.tag.crdate',
|
||||||
|
'config' => [
|
||||||
|
'type' => 'input',
|
||||||
|
'eval' => 'datetime',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'name' => [
|
||||||
|
'label' => 'LLL:EXT:tracking/Resources/Private/Language/locallang_tca.xlf:table.tag.name',
|
||||||
|
'config' => [
|
||||||
|
'type' => 'input',
|
||||||
|
'readOnly' => true,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'value' => [
|
||||||
|
'label' => 'LLL:EXT:tracking/Resources/Private/Language/locallang_tca.xlf:table.tag.value',
|
||||||
|
'config' => [
|
||||||
|
'type' => 'input',
|
||||||
|
'readOnly' => true,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
65
Documentation/Changelog/2.0.0.rst
Normal file
65
Documentation/Changelog/2.0.0.rst
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
2.0.0
|
||||||
|
=====
|
||||||
|
|
||||||
|
Breaking
|
||||||
|
--------
|
||||||
|
|
||||||
|
* No longer has ``operating_system`` database column.
|
||||||
|
|
||||||
|
* No longer ships default rule to not track requests from bots.
|
||||||
|
Does track them as bots now.
|
||||||
|
|
||||||
|
How to update:
|
||||||
|
|
||||||
|
Remove custom adjustments from :file:`Services.yaml` regarding bot detection.
|
||||||
|
Instead extend built in bot extraction and adjust custom widgets to exclude those
|
||||||
|
bots.
|
||||||
|
|
||||||
|
Execute the provided command (scheduler task) to update existing data.
|
||||||
|
Bots and operating system will be extracted from stored user agent.
|
||||||
|
|
||||||
|
See: :ref:`tags`.
|
||||||
|
|
||||||
|
* Existing widgets will no longer work with custom configuration.
|
||||||
|
Configuration needs to be adjusted.
|
||||||
|
|
||||||
|
.. todo:: document how to migrate
|
||||||
|
|
||||||
|
* Widgets will not work with old data.
|
||||||
|
How to migrate data:
|
||||||
|
|
||||||
|
Execute the provided scheduler task.
|
||||||
|
It will incrementally update pageviews and recordviews.
|
||||||
|
3500 records of each will be updated per each run.
|
||||||
|
Roughly executing every 10 minutes seems to be a good idea.
|
||||||
|
|
||||||
|
Features
|
||||||
|
--------
|
||||||
|
|
||||||
|
* Added support for tags
|
||||||
|
|
||||||
|
Tags can now be added to :ref:`pageview` and :ref:`recordview`.
|
||||||
|
The extension ships with some out of the box, but further can be added, see
|
||||||
|
:ref:`tags`.
|
||||||
|
|
||||||
|
Resolves: :issue:`46`.
|
||||||
|
|
||||||
|
Sponsored by: https://www.werkraum-media.de/
|
||||||
|
|
||||||
|
* Uses ``matomo/device-detector`` library to detect bots.
|
||||||
|
Some known bots are added on top.
|
||||||
|
|
||||||
|
Fixes
|
||||||
|
-----
|
||||||
|
|
||||||
|
Nothing
|
||||||
|
|
||||||
|
Tasks
|
||||||
|
-----
|
||||||
|
|
||||||
|
Nothing
|
||||||
|
|
||||||
|
Deprecation
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Nothing
|
|
@ -41,6 +41,8 @@ The extension allows to track :ref:`pageview`,
|
||||||
as well as views to specific TYPO3 records via :ref:`recordview`,
|
as well as views to specific TYPO3 records via :ref:`recordview`,
|
||||||
e.g. records from EXT:news or EXT:tt_address.
|
e.g. records from EXT:news or EXT:tt_address.
|
||||||
|
|
||||||
|
Each of them can be extended with arbitrary tags extracted from request.
|
||||||
|
|
||||||
Missing features
|
Missing features
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
@ -90,4 +92,6 @@ in order to extract further information from them with future updates.
|
||||||
Installation
|
Installation
|
||||||
Pageview
|
Pageview
|
||||||
Recordview
|
Recordview
|
||||||
|
Tags
|
||||||
|
UpdateExistingRecords
|
||||||
Changelog
|
Changelog
|
||||||
|
|
|
@ -43,12 +43,6 @@ Let us examine an concrete example::
|
||||||
$rule: >
|
$rule: >
|
||||||
not (context.getAspect("backend.user").isLoggedIn())
|
not (context.getAspect("backend.user").isLoggedIn())
|
||||||
and not (context.getAspect("frontend.preview").isPreview())
|
and not (context.getAspect("frontend.preview").isPreview())
|
||||||
and traverse(request.getHeader("User-Agent"), '0')
|
|
||||||
and not (request.getHeader("User-Agent")[0] matches "/^TYPO3|TYPO3 linkvalidator/")
|
|
||||||
and not (request.getHeader("User-Agent")[0] matches "/^Codeception Testing/")
|
|
||||||
and not (request.getHeader("User-Agent")[0] matches "/Wget|curl|Go-http-client/")
|
|
||||||
and not (request.getHeader("User-Agent")[0] matches "/bot|spider|Slurp|Sogou|NextCloud-News|Feedly|XING FeedReader|SEOkicks|Seekport Crawler|ia_archiver|TrendsmapResolver|Nuzzel/")
|
|
||||||
and not (request.getHeader("User-Agent")[0] matches "/mattermost|Slackbot|WhatsApp/")
|
|
||||||
|
|
||||||
The first paragraph will not be explained, check out :ref:`t3coreapi:configure-dependency-injection-in-extensions` instead.
|
The first paragraph will not be explained, check out :ref:`t3coreapi:configure-dependency-injection-in-extensions` instead.
|
||||||
|
|
||||||
|
@ -71,8 +65,7 @@ Check `PSR-7: HTTP message interfaces <https://www.php-fig.org/psr/psr-7/#321-ps
|
||||||
as well as
|
as well as
|
||||||
:ref:`t3coreapi:context-api`.
|
:ref:`t3coreapi:context-api`.
|
||||||
|
|
||||||
The above example blocks tracking for requests with logged in backend user,
|
The above example blocks tracking for requests with logged in backend user.
|
||||||
as well as specific user agents like bots, TYPO3 itself and other systems.
|
|
||||||
|
|
||||||
Widgets
|
Widgets
|
||||||
-------
|
-------
|
||||||
|
|
|
@ -56,11 +56,6 @@ Let us examine an concrete example::
|
||||||
request.getQueryParams()["tx_news_pi1"] && request.getQueryParams()["tx_news_pi1"]["news"] > 0
|
request.getQueryParams()["tx_news_pi1"] && request.getQueryParams()["tx_news_pi1"]["news"] > 0
|
||||||
and not (context.getAspect("backend.user").isLoggedIn())
|
and not (context.getAspect("backend.user").isLoggedIn())
|
||||||
and not (context.getAspect("frontend.preview").isPreview())
|
and not (context.getAspect("frontend.preview").isPreview())
|
||||||
and traverse(request.getHeader("User-Agent"), '0')
|
|
||||||
and not (request.getHeader("User-Agent")[0] matches "/^TYPO3|TYPO3 linkvalidator/")
|
|
||||||
and not (request.getHeader("User-Agent")[0] matches "/Wget|curl|Go-http-client/")
|
|
||||||
and not (request.getHeader("User-Agent")[0] matches "/bot|spider|Slurp|Sogou|NextCloud-News|Feedly|XING FeedReader|SEOkicks|Seekport Crawler|ia_archiver|TrendsmapResolver|Nuzzel/")
|
|
||||||
and not (request.getHeader("User-Agent")[0] matches "/mattermost|Slackbot|WhatsApp/")
|
|
||||||
recordUid: 'traverse(request.getQueryParams(), "tx_news_pi1", "news")'
|
recordUid: 'traverse(request.getQueryParams(), "tx_news_pi1", "news")'
|
||||||
tableName: 'tx_news_domain_model_news'
|
tableName: 'tx_news_domain_model_news'
|
||||||
|
|
||||||
|
|
35
Documentation/Tags.rst
Normal file
35
Documentation/Tags.rst
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
.. _tags:
|
||||||
|
|
||||||
|
Tags
|
||||||
|
=====
|
||||||
|
|
||||||
|
Tags are attached to all tracking information like :ref:`pageview` and :ref:`recordview`.
|
||||||
|
An example for a single record would be: ``bot:"yes",bot_name:"Slack",os:"Unkown"``.
|
||||||
|
|
||||||
|
Tags are extracted whenever a new record is saved, also during :ref:`updateExistingRecords`.
|
||||||
|
|
||||||
|
The extension provides some extractors to attach tags out of the box.
|
||||||
|
Further can be provided by foreign extensions or sites.
|
||||||
|
Each extractor has to implement either ``DanielSiepmann\Tracking\Domain\Extractors\PageviewExtractor`` and \ or ``DanielSiepmann\Tracking\Domain\Extractors\RecordviewExtractor`` interface.
|
||||||
|
|
||||||
|
This allows to add arbitrary data as tags to each tracking record.
|
||||||
|
Those can then be used to generate reports or build widgets.
|
||||||
|
|
||||||
|
Existing extractors
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
The following are provided out of the box.
|
||||||
|
One can replace them using :file:`Services.yaml`.
|
||||||
|
|
||||||
|
Operating System
|
||||||
|
^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Contains old logic to detect operating system of requests.
|
||||||
|
The operating system is added as ``os`` tag, e.g.: ``os:"Macintosh"``.
|
||||||
|
|
||||||
|
Bots
|
||||||
|
^^^^
|
||||||
|
|
||||||
|
Contains old logic to detect bots of requests.
|
||||||
|
The bot is added either as ``bot:"no"``.
|
||||||
|
If a bot is detected it is added as ``bot:"yes"`` combined with its name ``bot_name:"Slack"``.
|
5
Documentation/UpdateExistingRecords.rst
Normal file
5
Documentation/UpdateExistingRecords.rst
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
.. highlight:: php
|
||||||
|
.. _updateExistingRecords:
|
||||||
|
|
||||||
|
Update existing records
|
||||||
|
=======================
|
|
@ -27,8 +27,8 @@
|
||||||
<trans-unit id="table.pageview.user_agent">
|
<trans-unit id="table.pageview.user_agent">
|
||||||
<source>User agent</source>
|
<source>User agent</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="table.pageview.operating_system">
|
<trans-unit id="table.pageview.tags">
|
||||||
<source>Operating System</source>
|
<source>Tags</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
|
||||||
<trans-unit id="table.recordview">
|
<trans-unit id="table.recordview">
|
||||||
|
@ -55,8 +55,24 @@
|
||||||
<trans-unit id="table.recordview.user_agent">
|
<trans-unit id="table.recordview.user_agent">
|
||||||
<source>User agent</source>
|
<source>User agent</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="table.recordview.operating_system">
|
<trans-unit id="table.recordview.tags">
|
||||||
<source>Operating System</source>
|
<source>Tags</source>
|
||||||
|
</trans-unit>
|
||||||
|
|
||||||
|
<trans-unit id="table.tag.pid">
|
||||||
|
<source>PID</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="table.tag.record_uid">
|
||||||
|
<source>Foreign Record UID</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="table.tag.record_table_name">
|
||||||
|
<source>Foreign Record Table Name</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="table.tag.name">
|
||||||
|
<source>Name</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="table.tag.value">
|
||||||
|
<source>Value</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace DanielSiepmann\Tracking\Tests\Functional\Command;
|
declare(strict_types=1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
@ -21,13 +21,16 @@ namespace DanielSiepmann\Tracking\Tests\Functional\Command;
|
||||||
* 02110-1301, USA.
|
* 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace DanielSiepmann\Tracking\Tests\Functional\Command;
|
||||||
|
|
||||||
use DanielSiepmann\Tracking\Command\UpdateDataCommand;
|
use DanielSiepmann\Tracking\Command\UpdateDataCommand;
|
||||||
|
use DanielSiepmann\Tracking\Extension;
|
||||||
use Symfony\Component\Console\Tester\CommandTester;
|
use Symfony\Component\Console\Tester\CommandTester;
|
||||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase as TestCase;
|
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase as TestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers DanielSiepmann\Tracking\Command\UpdateDataCommand
|
* @covers \DanielSiepmann\Tracking\Command\UpdateDataCommand
|
||||||
*/
|
*/
|
||||||
class UpdateDataCommandTest extends TestCase
|
class UpdateDataCommandTest extends TestCase
|
||||||
{
|
{
|
||||||
|
@ -44,18 +47,112 @@ class UpdateDataCommandTest extends TestCase
|
||||||
*/
|
*/
|
||||||
public function updatesAllEntriesWithMissingOperatingSystem(): void
|
public function updatesAllEntriesWithMissingOperatingSystem(): void
|
||||||
{
|
{
|
||||||
$this->importDataSet('EXT:tracking/Tests/Functional/Fixtures/UpdateDataCommandTest/PageviewsWithMissingOperatingSystem.xml');
|
$this->importDataSet('EXT:tracking/Tests/Functional/Fixtures/UpdateDataCommandTest/WithMissingOperatingSystem.xml');
|
||||||
|
|
||||||
$subject = GeneralUtility::makeInstance(UpdateDataCommand::class);
|
$subject = GeneralUtility::makeInstance(UpdateDataCommand::class);
|
||||||
$tester = new CommandTester($subject);
|
$tester = new CommandTester($subject);
|
||||||
$tester->execute([], ['capture_stderr_separately' => true]);
|
$tester->execute([], ['capture_stderr_separately' => true]);
|
||||||
|
|
||||||
static::assertSame(0, $tester->getStatusCode());
|
self::assertSame(0, $tester->getStatusCode());
|
||||||
|
|
||||||
$records = $this->getAllRecords('tx_tracking_pageview');
|
$records = $this->getAllRecords('tx_tracking_tag');
|
||||||
static::assertCount(2, $records);
|
self::assertCount(8, $records);
|
||||||
static::assertSame('Linux', $records[0]['operating_system']);
|
self::assertSame([
|
||||||
static::assertSame('Android', $records[1]['operating_system']);
|
'uid'=> '1',
|
||||||
|
'pid'=> '1',
|
||||||
|
'tstamp'=> '1630649915',
|
||||||
|
'crdate'=> '1630649915',
|
||||||
|
'cruser_id'=> '0',
|
||||||
|
'record_uid' => '1',
|
||||||
|
'record_table_name' => 'tx_tracking_pageview',
|
||||||
|
'name' => 'bot',
|
||||||
|
'value' => 'no',
|
||||||
|
'compatible_version' => Extension::getCompatibleVersionNow(),
|
||||||
|
], array_map('strval', $records[0]));
|
||||||
|
self::assertSame([
|
||||||
|
'uid'=> '2',
|
||||||
|
'pid'=> '1',
|
||||||
|
'tstamp'=> '1630649915',
|
||||||
|
'crdate'=> '1630649915',
|
||||||
|
'cruser_id'=> '0',
|
||||||
|
'record_uid' => '1',
|
||||||
|
'record_table_name' => 'tx_tracking_pageview',
|
||||||
|
'name' => 'os',
|
||||||
|
'value' => 'Linux',
|
||||||
|
'compatible_version' => Extension::getCompatibleVersionNow(),
|
||||||
|
], array_map('strval', $records[1]));
|
||||||
|
self::assertSame([
|
||||||
|
'uid'=> '3',
|
||||||
|
'pid'=> '1',
|
||||||
|
'tstamp'=> '1630649916',
|
||||||
|
'crdate'=> '1630649916',
|
||||||
|
'cruser_id'=> '0',
|
||||||
|
'record_uid' => '2',
|
||||||
|
'record_table_name' => 'tx_tracking_pageview',
|
||||||
|
'name' => 'bot',
|
||||||
|
'value' => 'no',
|
||||||
|
'compatible_version' => Extension::getCompatibleVersionNow(),
|
||||||
|
], array_map('strval', $records[2]));
|
||||||
|
self::assertSame([
|
||||||
|
'uid'=> '4',
|
||||||
|
'pid'=> '1',
|
||||||
|
'tstamp'=> '1630649916',
|
||||||
|
'crdate'=> '1630649916',
|
||||||
|
'cruser_id'=> '0',
|
||||||
|
'record_uid' => '2',
|
||||||
|
'record_table_name' => 'tx_tracking_pageview',
|
||||||
|
'name' => 'os',
|
||||||
|
'value' => 'Android',
|
||||||
|
'compatible_version' => Extension::getCompatibleVersionNow(),
|
||||||
|
], array_map('strval', $records[3]));
|
||||||
|
self::assertSame([
|
||||||
|
'uid'=> '5',
|
||||||
|
'pid'=> '1',
|
||||||
|
'tstamp'=> '1630649915',
|
||||||
|
'crdate'=> '1630649915',
|
||||||
|
'cruser_id'=> '0',
|
||||||
|
'record_uid' => '1',
|
||||||
|
'record_table_name' => 'tx_tracking_recordview',
|
||||||
|
'name' => 'bot',
|
||||||
|
'value' => 'no',
|
||||||
|
'compatible_version' => Extension::getCompatibleVersionNow(),
|
||||||
|
], array_map('strval', $records[4]));
|
||||||
|
self::assertSame([
|
||||||
|
'uid'=> '6',
|
||||||
|
'pid'=> '1',
|
||||||
|
'tstamp'=> '1630649915',
|
||||||
|
'crdate'=> '1630649915',
|
||||||
|
'cruser_id'=> '0',
|
||||||
|
'record_uid' => '1',
|
||||||
|
'record_table_name' => 'tx_tracking_recordview',
|
||||||
|
'name' => 'os',
|
||||||
|
'value' => 'Linux',
|
||||||
|
'compatible_version' => Extension::getCompatibleVersionNow(),
|
||||||
|
], array_map('strval', $records[5]));
|
||||||
|
self::assertSame([
|
||||||
|
'uid'=> '7',
|
||||||
|
'pid'=> '1',
|
||||||
|
'tstamp'=> '1630649916',
|
||||||
|
'crdate'=> '1630649916',
|
||||||
|
'cruser_id'=> '0',
|
||||||
|
'record_uid' => '2',
|
||||||
|
'record_table_name' => 'tx_tracking_recordview',
|
||||||
|
'name' => 'bot',
|
||||||
|
'value' => 'no',
|
||||||
|
'compatible_version' => Extension::getCompatibleVersionNow(),
|
||||||
|
], array_map('strval', $records[6]));
|
||||||
|
self::assertSame([
|
||||||
|
'uid'=> '8',
|
||||||
|
'pid'=> '1',
|
||||||
|
'tstamp'=> '1630649916',
|
||||||
|
'crdate'=> '1630649916',
|
||||||
|
'cruser_id'=> '0',
|
||||||
|
'record_uid' => '2',
|
||||||
|
'record_table_name' => 'tx_tracking_recordview',
|
||||||
|
'name' => 'os',
|
||||||
|
'value' => 'Android',
|
||||||
|
'compatible_version' => Extension::getCompatibleVersionNow(),
|
||||||
|
], array_map('strval', $records[7]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -63,18 +160,64 @@ class UpdateDataCommandTest extends TestCase
|
||||||
*/
|
*/
|
||||||
public function doesNotChangeExistingOperatingSystem(): void
|
public function doesNotChangeExistingOperatingSystem(): void
|
||||||
{
|
{
|
||||||
$this->importDataSet('EXT:tracking/Tests/Functional/Fixtures/UpdateDataCommandTest/PageviewsWithOperatingSystem.xml');
|
$this->importDataSet('EXT:tracking/Tests/Functional/Fixtures/UpdateDataCommandTest/WithOperatingSystem.xml');
|
||||||
|
|
||||||
$subject = GeneralUtility::makeInstance(UpdateDataCommand::class);
|
$subject = GeneralUtility::makeInstance(UpdateDataCommand::class);
|
||||||
$tester = new CommandTester($subject);
|
$tester = new CommandTester($subject);
|
||||||
$tester->execute([], ['capture_stderr_separately' => true]);
|
$tester->execute([], ['capture_stderr_separately' => true]);
|
||||||
|
|
||||||
static::assertSame(0, $tester->getStatusCode());
|
self::assertSame(0, $tester->getStatusCode());
|
||||||
|
|
||||||
$records = $this->getAllRecords('tx_tracking_pageview');
|
$records = $this->getAllRecords('tx_tracking_tag');
|
||||||
static::assertCount(2, $records);
|
self::assertCount(4, $records);
|
||||||
static::assertSame('Linux', $records[0]['operating_system']);
|
self::assertSame([
|
||||||
static::assertSame('Android', $records[1]['operating_system']);
|
'uid' => '3',
|
||||||
|
'pid' => '1',
|
||||||
|
'tstamp'=> '1630649915',
|
||||||
|
'crdate'=> '1630649915',
|
||||||
|
'cruser_id' => '0',
|
||||||
|
'record_uid' => '1',
|
||||||
|
'record_table_name' => 'tx_tracking_pageview',
|
||||||
|
'name' => 'bot',
|
||||||
|
'value' => 'no',
|
||||||
|
'compatible_version' => Extension::getCompatibleVersionNow(),
|
||||||
|
], array_map('strval', $records[0]));
|
||||||
|
self::assertSame([
|
||||||
|
'uid' => '4',
|
||||||
|
'pid' => '1',
|
||||||
|
'tstamp'=> '1630649915',
|
||||||
|
'crdate'=> '1630649915',
|
||||||
|
'cruser_id' => '0',
|
||||||
|
'record_uid' => '1',
|
||||||
|
'record_table_name' => 'tx_tracking_pageview',
|
||||||
|
'name' => 'os',
|
||||||
|
'value' => 'Linux',
|
||||||
|
'compatible_version' => Extension::getCompatibleVersionNow(),
|
||||||
|
], array_map('strval', $records[1]));
|
||||||
|
self::assertSame([
|
||||||
|
'uid' => '5',
|
||||||
|
'pid' => '1',
|
||||||
|
'tstamp'=> '1630649916',
|
||||||
|
'crdate'=> '1630649916',
|
||||||
|
'cruser_id' => '0',
|
||||||
|
'record_uid' => '2',
|
||||||
|
'record_table_name' => 'tx_tracking_pageview',
|
||||||
|
'name' => 'bot',
|
||||||
|
'value' => 'no',
|
||||||
|
'compatible_version' => Extension::getCompatibleVersionNow(),
|
||||||
|
], array_map('strval', $records[2]));
|
||||||
|
self::assertSame([
|
||||||
|
'uid' => '6',
|
||||||
|
'pid' => '1',
|
||||||
|
'tstamp'=> '1630649916',
|
||||||
|
'crdate'=> '1630649916',
|
||||||
|
'cruser_id' => '0',
|
||||||
|
'record_uid' => '2',
|
||||||
|
'record_table_name' => 'tx_tracking_pageview',
|
||||||
|
'name' => 'os',
|
||||||
|
'value' => 'Android',
|
||||||
|
'compatible_version' => Extension::getCompatibleVersionNow(),
|
||||||
|
], array_map('strval', $records[3]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -88,9 +231,38 @@ class UpdateDataCommandTest extends TestCase
|
||||||
$tester = new CommandTester($subject);
|
$tester = new CommandTester($subject);
|
||||||
$tester->execute([], ['capture_stderr_separately' => true]);
|
$tester->execute([], ['capture_stderr_separately' => true]);
|
||||||
|
|
||||||
static::assertSame(0, $tester->getStatusCode());
|
self::assertSame(0, $tester->getStatusCode());
|
||||||
|
|
||||||
$records = $this->getAllRecords('tx_tracking_pageview');
|
$records = $this->getAllRecords('tx_tracking_pageview');
|
||||||
static::assertCount(0, $records);
|
self::assertCount(0, $records);
|
||||||
|
|
||||||
|
$records = $this->getAllRecords('tx_tracking_tag');
|
||||||
|
self::assertCount(0, $records);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function doesNothingIfAllRecordsAreCompatible(): void
|
||||||
|
{
|
||||||
|
$this->importDataSet('EXT:tracking/Tests/Functional/Fixtures/UpdateDataCommandTest/WithCompatibleVersion.xml');
|
||||||
|
|
||||||
|
$subject = GeneralUtility::makeInstance(UpdateDataCommand::class);
|
||||||
|
$tester = new CommandTester($subject);
|
||||||
|
$tester->execute([], ['capture_stderr_separately' => true]);
|
||||||
|
|
||||||
|
self::assertSame(0, $tester->getStatusCode());
|
||||||
|
|
||||||
|
$records = $this->getAllRecords('tx_tracking_pageview');
|
||||||
|
self::assertCount(1, $records);
|
||||||
|
|
||||||
|
$records = $this->getAllRecords('tx_tracking_recordview');
|
||||||
|
self::assertCount(1, $records);
|
||||||
|
|
||||||
|
$records = $this->getAllRecords('tx_tracking_tag');
|
||||||
|
self::assertCount(4, $records);
|
||||||
|
foreach ($records as $record) {
|
||||||
|
self::assertSame(1663773639, $record['crdate']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace DanielSiepmann\Tracking\Tests\Functional\Dashboard\Provider;
|
declare(strict_types=1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
@ -21,13 +21,16 @@ namespace DanielSiepmann\Tracking\Tests\Functional\Dashboard\Provider;
|
||||||
* 02110-1301, USA.
|
* 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace DanielSiepmann\Tracking\Tests\Functional\Dashboard\Provider;
|
||||||
|
|
||||||
|
use DanielSiepmann\Tracking\Dashboard\Provider\Demand;
|
||||||
use DanielSiepmann\Tracking\Dashboard\Provider\NewestPageviews;
|
use DanielSiepmann\Tracking\Dashboard\Provider\NewestPageviews;
|
||||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase as TestCase;
|
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase as TestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers DanielSiepmann\Tracking\Dashboard\Provider\NewestPageviews
|
* @covers \DanielSiepmann\Tracking\Dashboard\Provider\NewestPageviews
|
||||||
*/
|
*/
|
||||||
class NewestPageviewsTest extends TestCase
|
class NewestPageviewsTest extends TestCase
|
||||||
{
|
{
|
||||||
|
@ -51,10 +54,11 @@ class NewestPageviewsTest extends TestCase
|
||||||
}
|
}
|
||||||
|
|
||||||
$subject = new NewestPageviews(
|
$subject = new NewestPageviews(
|
||||||
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview')
|
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
||||||
|
new Demand()
|
||||||
);
|
);
|
||||||
|
|
||||||
static::assertSame([
|
self::assertSame([
|
||||||
'Url 10 - User-Agent 10',
|
'Url 10 - User-Agent 10',
|
||||||
'Url 9 - User-Agent 9',
|
'Url 9 - User-Agent 9',
|
||||||
'Url 8 - User-Agent 8',
|
'Url 8 - User-Agent 8',
|
||||||
|
@ -81,10 +85,10 @@ class NewestPageviewsTest extends TestCase
|
||||||
|
|
||||||
$subject = new NewestPageviews(
|
$subject = new NewestPageviews(
|
||||||
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
||||||
2
|
new Demand(31, 2)
|
||||||
);
|
);
|
||||||
|
|
||||||
static::assertSame([
|
self::assertSame([
|
||||||
'Url 10 - User-Agent 10',
|
'Url 10 - User-Agent 10',
|
||||||
'Url 9 - User-Agent 9',
|
'Url 9 - User-Agent 9',
|
||||||
], $subject->getItems());
|
], $subject->getItems());
|
||||||
|
@ -107,11 +111,10 @@ class NewestPageviewsTest extends TestCase
|
||||||
|
|
||||||
$subject = new NewestPageviews(
|
$subject = new NewestPageviews(
|
||||||
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
||||||
6,
|
new Demand(31, 6, [9])
|
||||||
[9]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
static::assertSame([
|
self::assertSame([
|
||||||
'Url 10 - User-Agent 10',
|
'Url 10 - User-Agent 10',
|
||||||
'Url 8 - User-Agent 8',
|
'Url 8 - User-Agent 8',
|
||||||
'Url 7 - User-Agent 7',
|
'Url 7 - User-Agent 7',
|
||||||
|
@ -139,12 +142,10 @@ class NewestPageviewsTest extends TestCase
|
||||||
|
|
||||||
$subject = new NewestPageviews(
|
$subject = new NewestPageviews(
|
||||||
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
||||||
6,
|
new Demand(31, 6, [], [1])
|
||||||
[],
|
|
||||||
[1]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
static::assertSame([
|
self::assertSame([
|
||||||
'Url 9 - User-Agent 9',
|
'Url 9 - User-Agent 9',
|
||||||
'Url 7 - User-Agent 7',
|
'Url 7 - User-Agent 7',
|
||||||
'Url 5 - User-Agent 5',
|
'Url 5 - User-Agent 5',
|
||||||
|
@ -152,4 +153,6 @@ class NewestPageviewsTest extends TestCase
|
||||||
'Url 1 - User-Agent 1',
|
'Url 1 - User-Agent 1',
|
||||||
], $subject->getItems());
|
], $subject->getItems());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Add tests for new feature regarding tags
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace DanielSiepmann\Tracking\Tests\Functional\Dashboard\Provider;
|
declare(strict_types=1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
@ -21,6 +21,10 @@ namespace DanielSiepmann\Tracking\Tests\Functional\Dashboard\Provider;
|
||||||
* 02110-1301, USA.
|
* 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace DanielSiepmann\Tracking\Tests\Functional\Dashboard\Provider;
|
||||||
|
|
||||||
|
use DanielSiepmann\Tracking\Dashboard\Provider\Demand;
|
||||||
|
use DanielSiepmann\Tracking\Dashboard\Provider\Demand\Tag;
|
||||||
use DanielSiepmann\Tracking\Dashboard\Provider\PageviewsPerDay;
|
use DanielSiepmann\Tracking\Dashboard\Provider\PageviewsPerDay;
|
||||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||||
use TYPO3\CMS\Core\Localization\LanguageService;
|
use TYPO3\CMS\Core\Localization\LanguageService;
|
||||||
|
@ -28,7 +32,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase as TestCase;
|
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase as TestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers DanielSiepmann\Tracking\Dashboard\Provider\PageviewsPerDay
|
* @covers \DanielSiepmann\Tracking\Dashboard\Provider\PageviewsPerDay
|
||||||
*/
|
*/
|
||||||
class PageviewsPerDayTest extends TestCase
|
class PageviewsPerDayTest extends TestCase
|
||||||
{
|
{
|
||||||
|
@ -51,12 +55,13 @@ class PageviewsPerDayTest extends TestCase
|
||||||
|
|
||||||
$subject = new PageviewsPerDay(
|
$subject = new PageviewsPerDay(
|
||||||
GeneralUtility::makeInstance(LanguageService::class),
|
GeneralUtility::makeInstance(LanguageService::class),
|
||||||
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview')
|
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
||||||
|
new Demand()
|
||||||
);
|
);
|
||||||
|
|
||||||
$result = $subject->getChartData();
|
$result = $subject->getChartData();
|
||||||
static::assertCount(32, $result['labels']);
|
self::assertCount(32, $result['labels']);
|
||||||
static::assertCount(32, $result['datasets'][0]['data']);
|
self::assertCount(32, $result['datasets'][0]['data']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -76,12 +81,12 @@ class PageviewsPerDayTest extends TestCase
|
||||||
$subject = new PageviewsPerDay(
|
$subject = new PageviewsPerDay(
|
||||||
GeneralUtility::makeInstance(LanguageService::class),
|
GeneralUtility::makeInstance(LanguageService::class),
|
||||||
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
||||||
3
|
new Demand(3)
|
||||||
);
|
);
|
||||||
|
|
||||||
$result = $subject->getChartData();
|
$result = $subject->getChartData();
|
||||||
static::assertCount(4, $result['labels']);
|
self::assertCount(4, $result['labels']);
|
||||||
static::assertSame([
|
self::assertSame([
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
|
@ -106,13 +111,12 @@ class PageviewsPerDayTest extends TestCase
|
||||||
$subject = new PageviewsPerDay(
|
$subject = new PageviewsPerDay(
|
||||||
GeneralUtility::makeInstance(LanguageService::class),
|
GeneralUtility::makeInstance(LanguageService::class),
|
||||||
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
||||||
3,
|
new Demand(3, 0, [2])
|
||||||
[2]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$result = $subject->getChartData();
|
$result = $subject->getChartData();
|
||||||
static::assertCount(4, $result['labels']);
|
self::assertCount(4, $result['labels']);
|
||||||
static::assertSame([
|
self::assertSame([
|
||||||
1,
|
1,
|
||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
|
@ -131,18 +135,16 @@ class PageviewsPerDayTest extends TestCase
|
||||||
$subject = new PageviewsPerDay(
|
$subject = new PageviewsPerDay(
|
||||||
GeneralUtility::makeInstance(LanguageService::class),
|
GeneralUtility::makeInstance(LanguageService::class),
|
||||||
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
||||||
1,
|
new Demand(1, 0, [], []),
|
||||||
[],
|
|
||||||
[],
|
|
||||||
'd.m.Y'
|
'd.m.Y'
|
||||||
);
|
);
|
||||||
|
|
||||||
$result = $subject->getChartData();
|
$result = $subject->getChartData();
|
||||||
static::assertSame([
|
self::assertSame([
|
||||||
date('d.m.Y', strtotime('-1 day')),
|
date('d.m.Y', strtotime('-1 day')),
|
||||||
date('d.m.Y'),
|
date('d.m.Y'),
|
||||||
], $result['labels']);
|
], $result['labels']);
|
||||||
static::assertCount(2, $result['datasets'][0]['data']);
|
self::assertCount(2, $result['datasets'][0]['data']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -162,13 +164,11 @@ class PageviewsPerDayTest extends TestCase
|
||||||
$subject = new PageviewsPerDay(
|
$subject = new PageviewsPerDay(
|
||||||
GeneralUtility::makeInstance(LanguageService::class),
|
GeneralUtility::makeInstance(LanguageService::class),
|
||||||
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
||||||
11,
|
new Demand(11, 0, [], [1])
|
||||||
[],
|
|
||||||
[1]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$result = $subject->getChartData();
|
$result = $subject->getChartData();
|
||||||
static::assertSame([
|
self::assertSame([
|
||||||
0 => 0,
|
0 => 0,
|
||||||
1 => 0,
|
1 => 0,
|
||||||
2 => 1,
|
2 => 1,
|
||||||
|
@ -183,4 +183,140 @@ class PageviewsPerDayTest extends TestCase
|
||||||
11 => 0,
|
11 => 0,
|
||||||
], $result['datasets'][0]['data']);
|
], $result['datasets'][0]['data']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function respectedConfiguredTagRuleToNotIncludeBots(): void
|
||||||
|
{
|
||||||
|
$connection = $this->getConnectionPool()->getConnectionForTable('tx_tracking_pageview');
|
||||||
|
for ($i = 1; $i <= 10; $i++) {
|
||||||
|
$connection->insert('tx_tracking_pageview', [
|
||||||
|
'pid' => $i,
|
||||||
|
'uid' => $i,
|
||||||
|
'crdate' => strtotime('-' . $i . ' days'),
|
||||||
|
]);
|
||||||
|
$connection->insert('tx_tracking_tag', [
|
||||||
|
'pid' => $i,
|
||||||
|
'record_uid' => $i,
|
||||||
|
'record_table_name' => 'tx_tracking_pageview',
|
||||||
|
'name' => 'bot',
|
||||||
|
'value' => 'no',
|
||||||
|
'crdate' => strtotime('-' . $i . ' days'),
|
||||||
|
]);
|
||||||
|
$connection->insert('tx_tracking_pageview', [
|
||||||
|
'pid' => $i,
|
||||||
|
'uid' => $i * 20,
|
||||||
|
'crdate' => strtotime('-' . $i . ' days'),
|
||||||
|
]);
|
||||||
|
$connection->insert('tx_tracking_tag', [
|
||||||
|
'pid' => $i,
|
||||||
|
'record_uid' => $i * 20,
|
||||||
|
'record_table_name' => 'tx_tracking_pageview',
|
||||||
|
'name' => 'bot',
|
||||||
|
'value' => 'no',
|
||||||
|
'crdate' => strtotime('-' . $i . ' days'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$connection->insert('tx_tracking_pageview', [
|
||||||
|
'pid' => $i,
|
||||||
|
'uid' => $i * 300,
|
||||||
|
'crdate' => strtotime('-' . $i . ' days'),
|
||||||
|
]);
|
||||||
|
$connection->insert('tx_tracking_tag', [
|
||||||
|
'pid' => $i,
|
||||||
|
'record_uid' => $i * 300,
|
||||||
|
'record_table_name' => 'tx_tracking_pageview',
|
||||||
|
'name' => 'bot',
|
||||||
|
'value' => 'yes',
|
||||||
|
'crdate' => strtotime('-' . $i . ' days'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$subject = new PageviewsPerDay(
|
||||||
|
GeneralUtility::makeInstance(LanguageService::class),
|
||||||
|
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
||||||
|
new Demand(2, 0, [], [], [
|
||||||
|
Tag::createFromArray([
|
||||||
|
'name' => 'bot',
|
||||||
|
'value' => 'no',
|
||||||
|
]),
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
|
$result = $subject->getChartData();
|
||||||
|
self::assertSame([
|
||||||
|
0 => 2,
|
||||||
|
1 => 2,
|
||||||
|
2 => 0,
|
||||||
|
], $result['datasets'][0]['data']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function respectedConfiguredTagRuleToIncludeBots(): void
|
||||||
|
{
|
||||||
|
$connection = $this->getConnectionPool()->getConnectionForTable('tx_tracking_pageview');
|
||||||
|
for ($i = 1; $i <= 10; $i++) {
|
||||||
|
$connection->insert('tx_tracking_pageview', [
|
||||||
|
'pid' => $i,
|
||||||
|
'uid' => $i,
|
||||||
|
'crdate' => strtotime('-' . $i . ' days'),
|
||||||
|
]);
|
||||||
|
$connection->insert('tx_tracking_tag', [
|
||||||
|
'pid' => $i,
|
||||||
|
'record_uid' => $i,
|
||||||
|
'record_table_name' => 'tx_tracking_pageview',
|
||||||
|
'name' => 'bot',
|
||||||
|
'value' => 'no',
|
||||||
|
'crdate' => strtotime('-' . $i . ' days'),
|
||||||
|
]);
|
||||||
|
$connection->insert('tx_tracking_pageview', [
|
||||||
|
'pid' => $i,
|
||||||
|
'uid' => $i * 20,
|
||||||
|
'crdate' => strtotime('-' . $i . ' days'),
|
||||||
|
]);
|
||||||
|
$connection->insert('tx_tracking_tag', [
|
||||||
|
'pid' => $i,
|
||||||
|
'record_uid' => $i * 20,
|
||||||
|
'record_table_name' => 'tx_tracking_pageview',
|
||||||
|
'name' => 'bot',
|
||||||
|
'value' => 'no',
|
||||||
|
'crdate' => strtotime('-' . $i . ' days'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$connection->insert('tx_tracking_pageview', [
|
||||||
|
'pid' => $i,
|
||||||
|
'uid' => $i * 300,
|
||||||
|
'crdate' => strtotime('-' . $i . ' days'),
|
||||||
|
]);
|
||||||
|
$connection->insert('tx_tracking_tag', [
|
||||||
|
'pid' => $i,
|
||||||
|
'record_uid' => $i * 300,
|
||||||
|
'record_table_name' => 'tx_tracking_pageview',
|
||||||
|
'name' => 'bot',
|
||||||
|
'value' => 'yes',
|
||||||
|
'crdate' => strtotime('-' . $i . ' days'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$subject = new PageviewsPerDay(
|
||||||
|
GeneralUtility::makeInstance(LanguageService::class),
|
||||||
|
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
||||||
|
new Demand(2, 0, [], [], [
|
||||||
|
Tag::createFromArray([
|
||||||
|
'name' => 'bot',
|
||||||
|
'value' => 'yes',
|
||||||
|
]),
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
|
$result = $subject->getChartData();
|
||||||
|
self::assertSame([
|
||||||
|
0 => 1,
|
||||||
|
1 => 1,
|
||||||
|
2 => 0,
|
||||||
|
], $result['datasets'][0]['data']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace DanielSiepmann\Tracking\Tests\Functional\Dashboard\Provider;
|
declare(strict_types=1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
@ -21,13 +21,16 @@ namespace DanielSiepmann\Tracking\Tests\Functional\Dashboard\Provider;
|
||||||
* 02110-1301, USA.
|
* 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace DanielSiepmann\Tracking\Tests\Functional\Dashboard\Provider;
|
||||||
|
|
||||||
|
use DanielSiepmann\Tracking\Dashboard\Provider\Demand;
|
||||||
use DanielSiepmann\Tracking\Dashboard\Provider\PageviewsPerOperatingSystem;
|
use DanielSiepmann\Tracking\Dashboard\Provider\PageviewsPerOperatingSystem;
|
||||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase as TestCase;
|
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase as TestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers DanielSiepmann\Tracking\Dashboard\Provider\PageviewsPerOperatingSystem
|
* @covers \DanielSiepmann\Tracking\Dashboard\Provider\PageviewsPerOperatingSystem
|
||||||
*/
|
*/
|
||||||
class PageviewsPerOperatingSystemTest extends TestCase
|
class PageviewsPerOperatingSystemTest extends TestCase
|
||||||
{
|
{
|
||||||
|
@ -41,20 +44,36 @@ class PageviewsPerOperatingSystemTest extends TestCase
|
||||||
public function listsSixResultsForLast31DaysByDefault(): void
|
public function listsSixResultsForLast31DaysByDefault(): void
|
||||||
{
|
{
|
||||||
$connection = $this->getConnectionPool()->getConnectionForTable('tx_tracking_pageview');
|
$connection = $this->getConnectionPool()->getConnectionForTable('tx_tracking_pageview');
|
||||||
|
$connection->insert('tx_tracking_pageview', [
|
||||||
|
'pid' => 1,
|
||||||
|
'crdate' => time(),
|
||||||
|
]);
|
||||||
|
$connection->insert('tx_tracking_tag', [
|
||||||
|
'record_uid' => 1,
|
||||||
|
'record_table_name' => 'tx_tracking_pageview',
|
||||||
|
'name' => 'os',
|
||||||
|
'value' => 'System ' . 1,
|
||||||
|
]);
|
||||||
for ($i = 1; $i <= 10; $i++) {
|
for ($i = 1; $i <= 10; $i++) {
|
||||||
$connection->insert('tx_tracking_pageview', [
|
$connection->insert('tx_tracking_pageview', [
|
||||||
'pid' => $i,
|
'pid' => $i,
|
||||||
'operating_system' => 'System ' . $i,
|
|
||||||
'crdate' => time(),
|
'crdate' => time(),
|
||||||
]);
|
]);
|
||||||
|
$connection->insert('tx_tracking_tag', [
|
||||||
|
'record_uid' => $i,
|
||||||
|
'record_table_name' => 'tx_tracking_pageview',
|
||||||
|
'name' => 'os',
|
||||||
|
'value' => 'System ' . $i,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$subject = new PageviewsPerOperatingSystem(
|
$subject = new PageviewsPerOperatingSystem(
|
||||||
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview')
|
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
||||||
|
new Demand()
|
||||||
);
|
);
|
||||||
|
|
||||||
$result = $subject->getChartData();
|
$result = $subject->getChartData();
|
||||||
static::assertSame([
|
self::assertSame([
|
||||||
'System 1',
|
'System 1',
|
||||||
'System 10',
|
'System 10',
|
||||||
'System 2',
|
'System 2',
|
||||||
|
@ -62,7 +81,14 @@ class PageviewsPerOperatingSystemTest extends TestCase
|
||||||
'System 4',
|
'System 4',
|
||||||
'System 5',
|
'System 5',
|
||||||
], $result['labels']);
|
], $result['labels']);
|
||||||
static::assertCount(6, $result['datasets'][0]['data']);
|
self::assertSame([
|
||||||
|
'2',
|
||||||
|
'1',
|
||||||
|
'1',
|
||||||
|
'1',
|
||||||
|
'1',
|
||||||
|
'1',
|
||||||
|
], array_map('strval', $result['datasets'][0]['data']));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -74,36 +100,61 @@ class PageviewsPerOperatingSystemTest extends TestCase
|
||||||
$connection = $this->getConnectionPool()->getConnectionForTable('tx_tracking_pageview');
|
$connection = $this->getConnectionPool()->getConnectionForTable('tx_tracking_pageview');
|
||||||
$connection->insert('tx_tracking_pageview', [
|
$connection->insert('tx_tracking_pageview', [
|
||||||
'pid' => 1,
|
'pid' => 1,
|
||||||
'operating_system' => 'System 1',
|
|
||||||
'crdate' => time(),
|
'crdate' => time(),
|
||||||
]);
|
]);
|
||||||
|
$connection->insert('tx_tracking_tag', [
|
||||||
|
'record_uid' => '1',
|
||||||
|
'record_table_name' => 'tx_tracking_pageview',
|
||||||
|
'name' => 'os',
|
||||||
|
'value' => 'System 1',
|
||||||
|
]);
|
||||||
$connection->insert('tx_tracking_pageview', [
|
$connection->insert('tx_tracking_pageview', [
|
||||||
'pid' => 2,
|
'pid' => 2,
|
||||||
'operating_system' => 'System 2',
|
|
||||||
'crdate' => time(),
|
'crdate' => time(),
|
||||||
]);
|
]);
|
||||||
|
$connection->insert('tx_tracking_tag', [
|
||||||
|
'record_uid' => '2',
|
||||||
|
'record_table_name' => 'tx_tracking_pageview',
|
||||||
|
'name' => 'os',
|
||||||
|
'value' => 'System 2',
|
||||||
|
]);
|
||||||
$connection->insert('tx_tracking_pageview', [
|
$connection->insert('tx_tracking_pageview', [
|
||||||
'pid' => 3,
|
'pid' => 3,
|
||||||
'operating_system' => 'System 3',
|
|
||||||
'crdate' => time(),
|
'crdate' => time(),
|
||||||
]);
|
]);
|
||||||
|
$connection->insert('tx_tracking_tag', [
|
||||||
|
'record_uid' => '3',
|
||||||
|
'record_table_name' => 'tx_tracking_pageview',
|
||||||
|
'name' => 'os',
|
||||||
|
'value' => 'System 3',
|
||||||
|
]);
|
||||||
$connection->insert('tx_tracking_pageview', [
|
$connection->insert('tx_tracking_pageview', [
|
||||||
'pid' => 2,
|
'pid' => 3,
|
||||||
'operating_system' => 'System 2',
|
|
||||||
'crdate' => time(),
|
'crdate' => time(),
|
||||||
]);
|
]);
|
||||||
|
$connection->insert('tx_tracking_tag', [
|
||||||
|
'record_uid' => '4',
|
||||||
|
'record_table_name' => 'tx_tracking_pageview',
|
||||||
|
'name' => 'os',
|
||||||
|
'value' => 'System 2',
|
||||||
|
]);
|
||||||
|
|
||||||
$subject = new PageviewsPerOperatingSystem(
|
$subject = new PageviewsPerOperatingSystem(
|
||||||
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview')
|
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
||||||
|
new Demand()
|
||||||
);
|
);
|
||||||
|
|
||||||
$result = $subject->getChartData();
|
$result = $subject->getChartData();
|
||||||
static::assertSame([
|
self::assertSame([
|
||||||
'System 2',
|
'System 2',
|
||||||
'System 1',
|
'System 1',
|
||||||
'System 3',
|
'System 3',
|
||||||
], $result['labels']);
|
], $result['labels']);
|
||||||
static::assertCount(3, $result['datasets'][0]['data']);
|
self::assertSame([
|
||||||
|
'2',
|
||||||
|
'1',
|
||||||
|
'1',
|
||||||
|
], array_map('strval', $result['datasets'][0]['data']));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -115,31 +166,49 @@ class PageviewsPerOperatingSystemTest extends TestCase
|
||||||
$connection = $this->getConnectionPool()->getConnectionForTable('tx_tracking_pageview');
|
$connection = $this->getConnectionPool()->getConnectionForTable('tx_tracking_pageview');
|
||||||
$connection->insert('tx_tracking_pageview', [
|
$connection->insert('tx_tracking_pageview', [
|
||||||
'pid' => 1,
|
'pid' => 1,
|
||||||
'operating_system' => 'System 1',
|
|
||||||
'crdate' => strtotime('-3 days'),
|
'crdate' => strtotime('-3 days'),
|
||||||
]);
|
]);
|
||||||
|
$connection->insert('tx_tracking_tag', [
|
||||||
|
'record_uid' => '1',
|
||||||
|
'record_table_name' => 'tx_tracking_pageview',
|
||||||
|
'name' => 'os',
|
||||||
|
'value' => 'System 1',
|
||||||
|
]);
|
||||||
$connection->insert('tx_tracking_pageview', [
|
$connection->insert('tx_tracking_pageview', [
|
||||||
'pid' => 2,
|
'pid' => 2,
|
||||||
'operating_system' => 'System 2',
|
|
||||||
'crdate' => strtotime('-2 days'),
|
'crdate' => strtotime('-2 days'),
|
||||||
]);
|
]);
|
||||||
|
$connection->insert('tx_tracking_tag', [
|
||||||
|
'record_uid' => '2',
|
||||||
|
'record_table_name' => 'tx_tracking_pageview',
|
||||||
|
'name' => 'os',
|
||||||
|
'value' => 'System 2',
|
||||||
|
]);
|
||||||
$connection->insert('tx_tracking_pageview', [
|
$connection->insert('tx_tracking_pageview', [
|
||||||
'pid' => 3,
|
'pid' => 3,
|
||||||
'operating_system' => 'System 3',
|
|
||||||
'crdate' => strtotime('-1 days'),
|
'crdate' => strtotime('-1 days'),
|
||||||
]);
|
]);
|
||||||
|
$connection->insert('tx_tracking_tag', [
|
||||||
|
'record_uid' => '3',
|
||||||
|
'record_table_name' => 'tx_tracking_pageview',
|
||||||
|
'name' => 'os',
|
||||||
|
'value' => 'System 3',
|
||||||
|
]);
|
||||||
|
|
||||||
$subject = new PageviewsPerOperatingSystem(
|
$subject = new PageviewsPerOperatingSystem(
|
||||||
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
||||||
2
|
new Demand(2)
|
||||||
);
|
);
|
||||||
|
|
||||||
$result = $subject->getChartData();
|
$result = $subject->getChartData();
|
||||||
static::assertSame([
|
self::assertSame([
|
||||||
'System 2',
|
'System 2',
|
||||||
'System 3',
|
'System 3',
|
||||||
], $result['labels']);
|
], $result['labels']);
|
||||||
static::assertCount(2, $result['datasets'][0]['data']);
|
self::assertSame([
|
||||||
|
'1',
|
||||||
|
'1',
|
||||||
|
], array_map('strval', $result['datasets'][0]['data']));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -152,25 +221,34 @@ class PageviewsPerOperatingSystemTest extends TestCase
|
||||||
for ($i = 1; $i <= 10; $i++) {
|
for ($i = 1; $i <= 10; $i++) {
|
||||||
$connection->insert('tx_tracking_pageview', [
|
$connection->insert('tx_tracking_pageview', [
|
||||||
'pid' => $i,
|
'pid' => $i,
|
||||||
'operating_system' => 'System ' . $i,
|
|
||||||
'crdate' => time(),
|
'crdate' => time(),
|
||||||
]);
|
]);
|
||||||
|
$connection->insert('tx_tracking_tag', [
|
||||||
|
'record_uid' => $i,
|
||||||
|
'record_table_name' => 'tx_tracking_pageview',
|
||||||
|
'name' => 'os',
|
||||||
|
'value' => 'System ' . $i,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$subject = new PageviewsPerOperatingSystem(
|
$subject = new PageviewsPerOperatingSystem(
|
||||||
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
||||||
31,
|
new Demand(31, 4)
|
||||||
4
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$result = $subject->getChartData();
|
$result = $subject->getChartData();
|
||||||
static::assertSame([
|
self::assertSame([
|
||||||
'System 1',
|
'System 1',
|
||||||
'System 10',
|
'System 10',
|
||||||
'System 2',
|
'System 2',
|
||||||
'System 3',
|
'System 3',
|
||||||
], $result['labels']);
|
], $result['labels']);
|
||||||
static::assertCount(4, $result['datasets'][0]['data']);
|
self::assertSame([
|
||||||
|
'1',
|
||||||
|
'1',
|
||||||
|
'1',
|
||||||
|
'1',
|
||||||
|
], array_map('strval', $result['datasets'][0]['data']));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -184,26 +262,37 @@ class PageviewsPerOperatingSystemTest extends TestCase
|
||||||
$connection->insert('tx_tracking_pageview', [
|
$connection->insert('tx_tracking_pageview', [
|
||||||
'pid' => $i,
|
'pid' => $i,
|
||||||
'sys_language_uid' => $i % 2,
|
'sys_language_uid' => $i % 2,
|
||||||
'operating_system' => 'System ' . $i,
|
|
||||||
'crdate' => time(),
|
'crdate' => time(),
|
||||||
]);
|
]);
|
||||||
|
$connection->insert('tx_tracking_tag', [
|
||||||
|
'record_uid' => $i,
|
||||||
|
'record_table_name' => 'tx_tracking_pageview',
|
||||||
|
'name' => 'os',
|
||||||
|
'value' => 'System ' . $i,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$subject = new PageviewsPerOperatingSystem(
|
$subject = new PageviewsPerOperatingSystem(
|
||||||
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
||||||
31,
|
new Demand(31, 6, [], [1])
|
||||||
6,
|
|
||||||
[1]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$result = $subject->getChartData();
|
$result = $subject->getChartData();
|
||||||
static::assertSame([
|
self::assertSame([
|
||||||
'System 1',
|
'System 1',
|
||||||
'System 3',
|
'System 3',
|
||||||
'System 5',
|
'System 5',
|
||||||
'System 7',
|
'System 7',
|
||||||
'System 9',
|
'System 9',
|
||||||
], $result['labels']);
|
], $result['labels']);
|
||||||
static::assertCount(5, $result['datasets'][0]['data']);
|
self::assertSame([
|
||||||
|
'1',
|
||||||
|
'1',
|
||||||
|
'1',
|
||||||
|
'1',
|
||||||
|
'1',
|
||||||
|
], array_map('strval', $result['datasets'][0]['data']));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Add tests for new feature regarding tags
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace DanielSiepmann\Tracking\Tests\Functional\Dashboard\Provider;
|
declare(strict_types=1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
@ -21,6 +21,10 @@ namespace DanielSiepmann\Tracking\Tests\Functional\Dashboard\Provider;
|
||||||
* 02110-1301, USA.
|
* 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace DanielSiepmann\Tracking\Tests\Functional\Dashboard\Provider;
|
||||||
|
|
||||||
|
use DanielSiepmann\Tracking\Dashboard\Provider\Demand;
|
||||||
|
use DanielSiepmann\Tracking\Dashboard\Provider\Demand\Tag;
|
||||||
use DanielSiepmann\Tracking\Dashboard\Provider\PageviewsPerPage;
|
use DanielSiepmann\Tracking\Dashboard\Provider\PageviewsPerPage;
|
||||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||||
use TYPO3\CMS\Core\Domain\Repository\PageRepository;
|
use TYPO3\CMS\Core\Domain\Repository\PageRepository;
|
||||||
|
@ -28,7 +32,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase as TestCase;
|
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase as TestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers DanielSiepmann\Tracking\Dashboard\Provider\PageviewsPerPage
|
* @covers \DanielSiepmann\Tracking\Dashboard\Provider\PageviewsPerPage
|
||||||
*/
|
*/
|
||||||
class PageviewsPerPageTest extends TestCase
|
class PageviewsPerPageTest extends TestCase
|
||||||
{
|
{
|
||||||
|
@ -46,17 +50,19 @@ class PageviewsPerPageTest extends TestCase
|
||||||
for ($i = 1; $i <= 10; $i++) {
|
for ($i = 1; $i <= 10; $i++) {
|
||||||
$connection->insert('tx_tracking_pageview', [
|
$connection->insert('tx_tracking_pageview', [
|
||||||
'pid' => $i,
|
'pid' => $i,
|
||||||
|
'uid' => $i,
|
||||||
'crdate' => time(),
|
'crdate' => time(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$subject = new PageviewsPerPage(
|
$subject = new PageviewsPerPage(
|
||||||
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
||||||
GeneralUtility::makeInstance(PageRepository::class)
|
GeneralUtility::makeInstance(PageRepository::class),
|
||||||
|
new Demand()
|
||||||
);
|
);
|
||||||
|
|
||||||
$result = $subject->getChartData();
|
$result = $subject->getChartData();
|
||||||
static::assertSame([
|
self::assertSame([
|
||||||
'Page 10',
|
'Page 10',
|
||||||
'Page 9',
|
'Page 9',
|
||||||
'Page 8',
|
'Page 8',
|
||||||
|
@ -64,7 +70,7 @@ class PageviewsPerPageTest extends TestCase
|
||||||
'Page 6',
|
'Page 6',
|
||||||
'Page 5',
|
'Page 5',
|
||||||
], $result['labels']);
|
], $result['labels']);
|
||||||
static::assertCount(6, $result['datasets'][0]['data']);
|
self::assertCount(6, $result['datasets'][0]['data']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -93,16 +99,17 @@ class PageviewsPerPageTest extends TestCase
|
||||||
|
|
||||||
$subject = new PageviewsPerPage(
|
$subject = new PageviewsPerPage(
|
||||||
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
||||||
GeneralUtility::makeInstance(PageRepository::class)
|
GeneralUtility::makeInstance(PageRepository::class),
|
||||||
|
new Demand()
|
||||||
);
|
);
|
||||||
|
|
||||||
$result = $subject->getChartData();
|
$result = $subject->getChartData();
|
||||||
static::assertSame([
|
self::assertSame([
|
||||||
'Page 2',
|
'Page 2',
|
||||||
'Page 3',
|
'Page 3',
|
||||||
'Page 1',
|
'Page 1',
|
||||||
], $result['labels']);
|
], $result['labels']);
|
||||||
static::assertCount(3, $result['datasets'][0]['data']);
|
self::assertCount(3, $result['datasets'][0]['data']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -128,15 +135,15 @@ class PageviewsPerPageTest extends TestCase
|
||||||
$subject = new PageviewsPerPage(
|
$subject = new PageviewsPerPage(
|
||||||
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
||||||
GeneralUtility::makeInstance(PageRepository::class),
|
GeneralUtility::makeInstance(PageRepository::class),
|
||||||
2
|
new Demand(2)
|
||||||
);
|
);
|
||||||
|
|
||||||
$result = $subject->getChartData();
|
$result = $subject->getChartData();
|
||||||
static::assertSame([
|
self::assertSame([
|
||||||
'Page 3',
|
'Page 3',
|
||||||
'Page 2',
|
'Page 2',
|
||||||
], $result['labels']);
|
], $result['labels']);
|
||||||
static::assertCount(2, $result['datasets'][0]['data']);
|
self::assertCount(2, $result['datasets'][0]['data']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -156,18 +163,17 @@ class PageviewsPerPageTest extends TestCase
|
||||||
$subject = new PageviewsPerPage(
|
$subject = new PageviewsPerPage(
|
||||||
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
||||||
GeneralUtility::makeInstance(PageRepository::class),
|
GeneralUtility::makeInstance(PageRepository::class),
|
||||||
31,
|
new Demand(31, 4)
|
||||||
4
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$result = $subject->getChartData();
|
$result = $subject->getChartData();
|
||||||
static::assertSame([
|
self::assertSame([
|
||||||
'Page 10',
|
'Page 10',
|
||||||
'Page 9',
|
'Page 9',
|
||||||
'Page 8',
|
'Page 8',
|
||||||
'Page 7',
|
'Page 7',
|
||||||
], $result['labels']);
|
], $result['labels']);
|
||||||
static::assertCount(4, $result['datasets'][0]['data']);
|
self::assertCount(4, $result['datasets'][0]['data']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -187,19 +193,17 @@ class PageviewsPerPageTest extends TestCase
|
||||||
$subject = new PageviewsPerPage(
|
$subject = new PageviewsPerPage(
|
||||||
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
||||||
GeneralUtility::makeInstance(PageRepository::class),
|
GeneralUtility::makeInstance(PageRepository::class),
|
||||||
31,
|
new Demand(31, 6, [1, 2, 3, 4, 5, 6])
|
||||||
6,
|
|
||||||
[1, 2, 3, 4, 5, 6]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$result = $subject->getChartData();
|
$result = $subject->getChartData();
|
||||||
static::assertSame([
|
self::assertSame([
|
||||||
'Page 10',
|
'Page 10',
|
||||||
'Page 9',
|
'Page 9',
|
||||||
'Page 8',
|
'Page 8',
|
||||||
'Page 7',
|
'Page 7',
|
||||||
], $result['labels']);
|
], $result['labels']);
|
||||||
static::assertCount(4, $result['datasets'][0]['data']);
|
self::assertCount(4, $result['datasets'][0]['data']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -235,18 +239,15 @@ class PageviewsPerPageTest extends TestCase
|
||||||
$subject = new PageviewsPerPage(
|
$subject = new PageviewsPerPage(
|
||||||
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
||||||
GeneralUtility::makeInstance(PageRepository::class),
|
GeneralUtility::makeInstance(PageRepository::class),
|
||||||
31,
|
new Demand(31, 6, [], [1])
|
||||||
6,
|
|
||||||
[],
|
|
||||||
[1]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$result = $subject->getChartData();
|
$result = $subject->getChartData();
|
||||||
static::assertSame([
|
self::assertSame([
|
||||||
'Page 2',
|
'Page 2',
|
||||||
'Page 1',
|
'Page 1',
|
||||||
], $result['labels']);
|
], $result['labels']);
|
||||||
static::assertCount(2, $result['datasets'][0]['data']);
|
self::assertCount(2, $result['datasets'][0]['data']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -282,18 +283,141 @@ class PageviewsPerPageTest extends TestCase
|
||||||
$subject = new PageviewsPerPage(
|
$subject = new PageviewsPerPage(
|
||||||
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
||||||
GeneralUtility::makeInstance(PageRepository::class),
|
GeneralUtility::makeInstance(PageRepository::class),
|
||||||
31,
|
new Demand(31, 6, [], [1, 0])
|
||||||
6,
|
|
||||||
[],
|
|
||||||
[1, '0']
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$result = $subject->getChartData();
|
$result = $subject->getChartData();
|
||||||
static::assertSame([
|
self::assertSame([
|
||||||
'Page 2',
|
'Page 2',
|
||||||
'Page 1',
|
'Page 1',
|
||||||
'Page 3',
|
'Page 3',
|
||||||
], $result['labels']);
|
], $result['labels']);
|
||||||
static::assertCount(3, $result['datasets'][0]['data']);
|
self::assertCount(3, $result['datasets'][0]['data']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function respectedConfiguredTagRuleToNotIncludeBots(): void
|
||||||
|
{
|
||||||
|
$this->importDataSet('EXT:tracking/Tests/Functional/Fixtures/Pages.xml');
|
||||||
|
$connection = $this->getConnectionPool()->getConnectionForTable('tx_tracking_pageview');
|
||||||
|
for ($i = 1; $i <= 10; $i++) {
|
||||||
|
$connection->insert('tx_tracking_pageview', [
|
||||||
|
'pid' => $i,
|
||||||
|
'uid' => $i,
|
||||||
|
'crdate' => time(),
|
||||||
|
]);
|
||||||
|
$connection->insert('tx_tracking_tag', [
|
||||||
|
'pid' => $i,
|
||||||
|
'uid' => $i,
|
||||||
|
'record_uid' => $i,
|
||||||
|
'record_table_name' => 'tx_tracking_pageview',
|
||||||
|
'name' => 'bot',
|
||||||
|
'value' => 'no',
|
||||||
|
'crdate' => time(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
for ($i = 11; $i <= 20; $i++) {
|
||||||
|
$connection->insert('tx_tracking_pageview', [
|
||||||
|
'pid' => $i,
|
||||||
|
'uid' => $i,
|
||||||
|
'crdate' => time(),
|
||||||
|
]);
|
||||||
|
$connection->insert('tx_tracking_tag', [
|
||||||
|
'pid' => $i,
|
||||||
|
'uid' => $i,
|
||||||
|
'record_uid' => $i,
|
||||||
|
'record_table_name' => 'tx_tracking_pageview',
|
||||||
|
'name' => 'bot',
|
||||||
|
'value' => 'yes',
|
||||||
|
'crdate' => time(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$subject = new PageviewsPerPage(
|
||||||
|
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
||||||
|
GeneralUtility::makeInstance(PageRepository::class),
|
||||||
|
new Demand(31, 6, [], [], [
|
||||||
|
Tag::createFromArray([
|
||||||
|
'name' => 'bot',
|
||||||
|
'value' => 'no',
|
||||||
|
]),
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
|
$result = $subject->getChartData();
|
||||||
|
self::assertSame([
|
||||||
|
'Page 10',
|
||||||
|
'Page 9',
|
||||||
|
'Page 8',
|
||||||
|
'Page 7',
|
||||||
|
'Page 6',
|
||||||
|
'Page 5',
|
||||||
|
], $result['labels']);
|
||||||
|
self::assertCount(6, $result['datasets'][0]['data']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function respectedConfiguredTagRuleToIncludeBots(): void
|
||||||
|
{
|
||||||
|
$this->importDataSet('EXT:tracking/Tests/Functional/Fixtures/Pages.xml');
|
||||||
|
$connection = $this->getConnectionPool()->getConnectionForTable('tx_tracking_pageview');
|
||||||
|
for ($i = 1; $i <= 10; $i++) {
|
||||||
|
$connection->insert('tx_tracking_pageview', [
|
||||||
|
'pid' => $i,
|
||||||
|
'uid' => $i,
|
||||||
|
'crdate' => time(),
|
||||||
|
]);
|
||||||
|
$connection->insert('tx_tracking_tag', [
|
||||||
|
'pid' => $i,
|
||||||
|
'uid' => $i,
|
||||||
|
'record_uid' => $i,
|
||||||
|
'record_table_name' => 'tx_tracking_pageview',
|
||||||
|
'name' => 'bot',
|
||||||
|
'value' => 'no',
|
||||||
|
'crdate' => time(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
for ($i = 11; $i <= 20; $i++) {
|
||||||
|
$connection->insert('tx_tracking_pageview', [
|
||||||
|
'pid' => $i,
|
||||||
|
'uid' => $i,
|
||||||
|
'crdate' => time(),
|
||||||
|
]);
|
||||||
|
$connection->insert('tx_tracking_tag', [
|
||||||
|
'pid' => $i,
|
||||||
|
'uid' => $i,
|
||||||
|
'record_uid' => $i,
|
||||||
|
'record_table_name' => 'tx_tracking_pageview',
|
||||||
|
'name' => 'bot',
|
||||||
|
'value' => 'yes',
|
||||||
|
'crdate' => time(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$subject = new PageviewsPerPage(
|
||||||
|
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
|
||||||
|
GeneralUtility::makeInstance(PageRepository::class),
|
||||||
|
new Demand(31, 6, [], [], [
|
||||||
|
Tag::createFromArray([
|
||||||
|
'name' => 'bot',
|
||||||
|
'value' => 'yes',
|
||||||
|
]),
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
|
$result = $subject->getChartData();
|
||||||
|
self::assertSame([
|
||||||
|
'Page 20',
|
||||||
|
'Page 19',
|
||||||
|
'Page 18',
|
||||||
|
'Page 17',
|
||||||
|
'Page 16',
|
||||||
|
'Page 15',
|
||||||
|
], $result['labels']);
|
||||||
|
self::assertCount(6, $result['datasets'][0]['data']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace DanielSiepmann\Tracking\Tests\Functional\Dashboard\Provider;
|
declare(strict_types=1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
@ -21,13 +21,16 @@ namespace DanielSiepmann\Tracking\Tests\Functional\Dashboard\Provider;
|
||||||
* 02110-1301, USA.
|
* 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace DanielSiepmann\Tracking\Tests\Functional\Dashboard\Provider;
|
||||||
|
|
||||||
|
use DanielSiepmann\Tracking\Dashboard\Provider\Demand;
|
||||||
use DanielSiepmann\Tracking\Dashboard\Provider\Recordviews;
|
use DanielSiepmann\Tracking\Dashboard\Provider\Recordviews;
|
||||||
use TYPO3\CMS\Core\Domain\Repository\PageRepository;
|
use TYPO3\CMS\Core\Domain\Repository\PageRepository;
|
||||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase as TestCase;
|
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase as TestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers DanielSiepmann\Tracking\Dashboard\Provider\Recordviews
|
* @covers \DanielSiepmann\Tracking\Dashboard\Provider\Recordviews
|
||||||
*/
|
*/
|
||||||
class RecordviewsTest extends TestCase
|
class RecordviewsTest extends TestCase
|
||||||
{
|
{
|
||||||
|
@ -53,11 +56,12 @@ class RecordviewsTest extends TestCase
|
||||||
|
|
||||||
$subject = new Recordviews(
|
$subject = new Recordviews(
|
||||||
GeneralUtility::makeInstance(PageRepository::class),
|
GeneralUtility::makeInstance(PageRepository::class),
|
||||||
$this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview')
|
$this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'),
|
||||||
|
new Demand()
|
||||||
);
|
);
|
||||||
|
|
||||||
$result = $subject->getChartData();
|
$result = $subject->getChartData();
|
||||||
static::assertSame([
|
self::assertSame([
|
||||||
'Category 10',
|
'Category 10',
|
||||||
'Category 9',
|
'Category 9',
|
||||||
'Category 8',
|
'Category 8',
|
||||||
|
@ -65,7 +69,7 @@ class RecordviewsTest extends TestCase
|
||||||
'Category 6',
|
'Category 6',
|
||||||
'Category 5',
|
'Category 5',
|
||||||
], $result['labels']);
|
], $result['labels']);
|
||||||
static::assertCount(6, $result['datasets'][0]['data']);
|
self::assertCount(6, $result['datasets'][0]['data']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -103,16 +107,16 @@ class RecordviewsTest extends TestCase
|
||||||
$subject = new Recordviews(
|
$subject = new Recordviews(
|
||||||
GeneralUtility::makeInstance(PageRepository::class),
|
GeneralUtility::makeInstance(PageRepository::class),
|
||||||
$this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'),
|
$this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'),
|
||||||
2
|
new Demand(2)
|
||||||
);
|
);
|
||||||
|
|
||||||
$result = $subject->getChartData();
|
$result = $subject->getChartData();
|
||||||
static::assertSame([
|
self::assertSame([
|
||||||
'Category 2',
|
'Category 2',
|
||||||
'Category 3',
|
'Category 3',
|
||||||
'Category 1',
|
'Category 1',
|
||||||
], $result['labels']);
|
], $result['labels']);
|
||||||
static::assertCount(3, $result['datasets'][0]['data']);
|
self::assertCount(3, $result['datasets'][0]['data']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -144,15 +148,15 @@ class RecordviewsTest extends TestCase
|
||||||
$subject = new Recordviews(
|
$subject = new Recordviews(
|
||||||
GeneralUtility::makeInstance(PageRepository::class),
|
GeneralUtility::makeInstance(PageRepository::class),
|
||||||
$this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'),
|
$this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'),
|
||||||
2
|
new Demand(2)
|
||||||
);
|
);
|
||||||
|
|
||||||
$result = $subject->getChartData();
|
$result = $subject->getChartData();
|
||||||
static::assertSame([
|
self::assertSame([
|
||||||
'Category 3',
|
'Category 3',
|
||||||
'Category 2',
|
'Category 2',
|
||||||
], $result['labels']);
|
], $result['labels']);
|
||||||
static::assertCount(2, $result['datasets'][0]['data']);
|
self::assertCount(2, $result['datasets'][0]['data']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -174,16 +178,15 @@ class RecordviewsTest extends TestCase
|
||||||
$subject = new Recordviews(
|
$subject = new Recordviews(
|
||||||
GeneralUtility::makeInstance(PageRepository::class),
|
GeneralUtility::makeInstance(PageRepository::class),
|
||||||
$this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'),
|
$this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'),
|
||||||
31,
|
new Demand(31, 2)
|
||||||
2
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$result = $subject->getChartData();
|
$result = $subject->getChartData();
|
||||||
static::assertSame([
|
self::assertSame([
|
||||||
'Category 10',
|
'Category 10',
|
||||||
'Category 9',
|
'Category 9',
|
||||||
], $result['labels']);
|
], $result['labels']);
|
||||||
static::assertCount(2, $result['datasets'][0]['data']);
|
self::assertCount(2, $result['datasets'][0]['data']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -206,20 +209,18 @@ class RecordviewsTest extends TestCase
|
||||||
$subject = new Recordviews(
|
$subject = new Recordviews(
|
||||||
GeneralUtility::makeInstance(PageRepository::class),
|
GeneralUtility::makeInstance(PageRepository::class),
|
||||||
$this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'),
|
$this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'),
|
||||||
31,
|
new Demand(31, 6, [1, 2, 3, 4, 5])
|
||||||
6,
|
|
||||||
[1, 2, 3, 4, 5]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$result = $subject->getChartData();
|
$result = $subject->getChartData();
|
||||||
static::assertSame([
|
self::assertSame([
|
||||||
'Category 10',
|
'Category 10',
|
||||||
'Category 9',
|
'Category 9',
|
||||||
'Category 8',
|
'Category 8',
|
||||||
'Category 7',
|
'Category 7',
|
||||||
'Category 6',
|
'Category 6',
|
||||||
], $result['labels']);
|
], $result['labels']);
|
||||||
static::assertCount(5, $result['datasets'][0]['data']);
|
self::assertCount(5, $result['datasets'][0]['data']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -247,20 +248,17 @@ class RecordviewsTest extends TestCase
|
||||||
$subject = new Recordviews(
|
$subject = new Recordviews(
|
||||||
GeneralUtility::makeInstance(PageRepository::class),
|
GeneralUtility::makeInstance(PageRepository::class),
|
||||||
$this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'),
|
$this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'),
|
||||||
31,
|
new Demand(31, 6),
|
||||||
6,
|
|
||||||
[],
|
|
||||||
[],
|
|
||||||
['sys_category']
|
['sys_category']
|
||||||
);
|
);
|
||||||
|
|
||||||
$result = $subject->getChartData();
|
$result = $subject->getChartData();
|
||||||
static::assertSame([
|
self::assertSame([
|
||||||
'Category 3',
|
'Category 3',
|
||||||
'Category 2',
|
'Category 2',
|
||||||
'Category 1',
|
'Category 1',
|
||||||
], $result['labels']);
|
], $result['labels']);
|
||||||
static::assertCount(3, $result['datasets'][0]['data']);
|
self::assertCount(3, $result['datasets'][0]['data']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -286,20 +284,17 @@ class RecordviewsTest extends TestCase
|
||||||
$subject = new Recordviews(
|
$subject = new Recordviews(
|
||||||
GeneralUtility::makeInstance(PageRepository::class),
|
GeneralUtility::makeInstance(PageRepository::class),
|
||||||
$this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'),
|
$this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'),
|
||||||
31,
|
new Demand(31, 6),
|
||||||
6,
|
|
||||||
[],
|
|
||||||
[],
|
|
||||||
[],
|
[],
|
||||||
['1', 2]
|
['1', 2]
|
||||||
);
|
);
|
||||||
|
|
||||||
$result = $subject->getChartData();
|
$result = $subject->getChartData();
|
||||||
static::assertSame([
|
self::assertSame([
|
||||||
'Content element 2',
|
'Content element 2',
|
||||||
'Content element 1',
|
'Content element 1',
|
||||||
], $result['labels']);
|
], $result['labels']);
|
||||||
static::assertCount(2, $result['datasets'][0]['data']);
|
self::assertCount(2, $result['datasets'][0]['data']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -334,20 +329,15 @@ class RecordviewsTest extends TestCase
|
||||||
$subject = new Recordviews(
|
$subject = new Recordviews(
|
||||||
GeneralUtility::makeInstance(PageRepository::class),
|
GeneralUtility::makeInstance(PageRepository::class),
|
||||||
$this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'),
|
$this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'),
|
||||||
31,
|
new Demand(31, 6, [], [1])
|
||||||
6,
|
|
||||||
[],
|
|
||||||
[1],
|
|
||||||
[],
|
|
||||||
[]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$result = $subject->getChartData();
|
$result = $subject->getChartData();
|
||||||
static::assertSame([
|
self::assertSame([
|
||||||
'Category 2',
|
'Category 2',
|
||||||
'Kategorie 1',
|
'Kategorie 1',
|
||||||
], $result['labels']);
|
], $result['labels']);
|
||||||
static::assertCount(2, $result['datasets'][0]['data']);
|
self::assertCount(2, $result['datasets'][0]['data']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -382,19 +372,16 @@ class RecordviewsTest extends TestCase
|
||||||
$subject = new Recordviews(
|
$subject = new Recordviews(
|
||||||
GeneralUtility::makeInstance(PageRepository::class),
|
GeneralUtility::makeInstance(PageRepository::class),
|
||||||
$this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'),
|
$this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'),
|
||||||
31,
|
new Demand(31, 6, [], [1, 0])
|
||||||
6,
|
|
||||||
[],
|
|
||||||
[1, 0],
|
|
||||||
[],
|
|
||||||
[]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$result = $subject->getChartData();
|
$result = $subject->getChartData();
|
||||||
static::assertSame([
|
self::assertSame([
|
||||||
'Category 1',
|
'Category 1',
|
||||||
'Category 2',
|
'Category 2',
|
||||||
], $result['labels']);
|
], $result['labels']);
|
||||||
static::assertCount(2, $result['datasets'][0]['data']);
|
self::assertCount(2, $result['datasets'][0]['data']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Add tests for new feature regarding tags
|
||||||
}
|
}
|
||||||
|
|
183
Tests/Functional/Domain/Extractors/BotsTest.php
Normal file
183
Tests/Functional/Domain/Extractors/BotsTest.php
Normal file
|
@ -0,0 +1,183 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace DanielSiepmann\Tracking\Tests\Functional\Domain\Extractors;
|
||||||
|
|
||||||
|
use DanielSiepmann\Tracking\Domain\Extractors\Bots;
|
||||||
|
use DanielSiepmann\Tracking\Domain\Extractors\Bots\CustomBotParser;
|
||||||
|
use DanielSiepmann\Tracking\Domain\Model\Extractor;
|
||||||
|
use DanielSiepmann\Tracking\Domain\Model\Pageview;
|
||||||
|
use DanielSiepmann\Tracking\Domain\Model\Recordview;
|
||||||
|
use DeviceDetector\DeviceDetector;
|
||||||
|
use Prophecy\PhpUnit\ProphecyTrait;
|
||||||
|
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase as TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers \DanielSiepmann\Tracking\Domain\Extractors\Bots
|
||||||
|
*/
|
||||||
|
class BotsTest extends TestCase
|
||||||
|
{
|
||||||
|
use ProphecyTrait;
|
||||||
|
|
||||||
|
protected $testExtensionsToLoad = [
|
||||||
|
'typo3conf/ext/tracking',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @dataProvider possibleUserStringWithBots
|
||||||
|
* @testdox Bot $expectedBot is extracted from Pageview UserAgent string: $userAgent
|
||||||
|
*/
|
||||||
|
public function returnsBotForPageview(string $userAgent, string $expectedBot): void
|
||||||
|
{
|
||||||
|
$model = $this->prophesize(Pageview::class);
|
||||||
|
$model->getUserAgent()->willReturn($userAgent);
|
||||||
|
|
||||||
|
$extractor = new Bots(new CustomBotParser());
|
||||||
|
$tags = $extractor->extractTagFromPageview($model->reveal());
|
||||||
|
|
||||||
|
self::assertCount(2, $tags);
|
||||||
|
self::assertSame('bot', $tags[0]->getName());
|
||||||
|
self::assertSame('yes', $tags[0]->getValue());
|
||||||
|
self::assertSame('bot_name', $tags[1]->getName());
|
||||||
|
self::assertSame($expectedBot, $tags[1]->getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @dataProvider possibleUserStringWithBots
|
||||||
|
* @testdox Bot $expectedBot is extracted from Recordview UserAgent string: $userAgent
|
||||||
|
*/
|
||||||
|
public function returnsBotForRecordview(string $userAgent, string $expectedBot): void
|
||||||
|
{
|
||||||
|
$model = $this->prophesize(Recordview::class);
|
||||||
|
$model->getUserAgent()->willReturn($userAgent);
|
||||||
|
|
||||||
|
$extractor = new Bots(new CustomBotParser());
|
||||||
|
$tags = $extractor->extractTagFromRecordview($model->reveal());
|
||||||
|
|
||||||
|
self::assertCount(2, $tags);
|
||||||
|
self::assertSame('bot', $tags[0]->getName());
|
||||||
|
self::assertSame('yes', $tags[0]->getValue());
|
||||||
|
self::assertSame('bot_name', $tags[1]->getName());
|
||||||
|
self::assertSame($expectedBot, $tags[1]->getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function possibleUserStringWithBots(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
0 => [
|
||||||
|
'userAgent' => 'nettle (+https://www.nettle.sk)',
|
||||||
|
'expectedBot' => 'Nettle',
|
||||||
|
],
|
||||||
|
1 => [
|
||||||
|
'userAgent' => 'MauiBot (crawler.feedback+wc@gmail.com)',
|
||||||
|
'expectedBot' => 'Generic Bot',
|
||||||
|
],
|
||||||
|
2 => [
|
||||||
|
'userAgent' => 'facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)',
|
||||||
|
'expectedBot' => 'Facebook External Hit',
|
||||||
|
],
|
||||||
|
3 => [
|
||||||
|
'userAgent' => 'Java/11.0.10',
|
||||||
|
'expectedBot' => 'Java',
|
||||||
|
],
|
||||||
|
4 => [
|
||||||
|
'userAgent' => 'newspaper/0.2.8',
|
||||||
|
'expectedBot' => 'Newspaper',
|
||||||
|
],
|
||||||
|
5 => [
|
||||||
|
'userAgent' => 'Tiny Tiny RSS/21.05-326850845 (http://tt-rss.org/)',
|
||||||
|
'expectedBot' => 'Tiny Tiny RSS',
|
||||||
|
],
|
||||||
|
6 => [
|
||||||
|
'userAgent' => 'BacklinkCrawler (http://www.backlinktest.com/crawler.html)',
|
||||||
|
'expectedBot' => 'BacklinkCrawler',
|
||||||
|
],
|
||||||
|
7 => [
|
||||||
|
'userAgent' => 'CCBot/2.0 (https://commoncrawl.org/faq/)',
|
||||||
|
'expectedBot' => 'ccBot crawler',
|
||||||
|
],
|
||||||
|
8 => [
|
||||||
|
'userAgent' => 'Tiny Tiny RSS/21.04-e8f78181f (http://tt-rss.org/)',
|
||||||
|
'expectedBot' => 'Tiny Tiny RSS',
|
||||||
|
],
|
||||||
|
9 => [
|
||||||
|
'userAgent' => 'ltx71 - (http://ltx71.com/)',
|
||||||
|
'expectedBot' => 'LTX71',
|
||||||
|
],
|
||||||
|
10 => [
|
||||||
|
'userAgent' => 'FeedFetcher-Google; (+http://www.google.com/feedfetcher.html)',
|
||||||
|
'expectedBot' => 'Googlebot',
|
||||||
|
],
|
||||||
|
11 => [
|
||||||
|
'userAgent' => 'colly - https://github.com/gocolly/colly',
|
||||||
|
'expectedBot' => 'colly',
|
||||||
|
],
|
||||||
|
12 => [
|
||||||
|
'userAgent' => 'WordPress.com; https://serdargunes.wordpress.com',
|
||||||
|
'expectedBot' => 'WordPress',
|
||||||
|
],
|
||||||
|
13 => [
|
||||||
|
'userAgent' => 'Tiny Tiny RSS/21.03-2f402d598 (http://tt-rss.org/)',
|
||||||
|
'expectedBot' => 'Tiny Tiny RSS',
|
||||||
|
],
|
||||||
|
14 => [
|
||||||
|
'userAgent' => 'netEstate NE Crawler (+http://www.website-datenbank.de/)',
|
||||||
|
'expectedBot' => 'netEstate',
|
||||||
|
],
|
||||||
|
15 => [
|
||||||
|
'userAgent' => 'python-requests/2.18.1',
|
||||||
|
'expectedBot' => 'Python Requests',
|
||||||
|
],
|
||||||
|
16 => [
|
||||||
|
'userAgent' => 'PocketParser/2.0 (+https://getpocket.com/pocketparser_ua)',
|
||||||
|
'expectedBot' => 'PocketParser',
|
||||||
|
],
|
||||||
|
17 => [
|
||||||
|
'userAgent' => 'Faraday v0.17.3',
|
||||||
|
'expectedBot' => 'Faraday',
|
||||||
|
],
|
||||||
|
18 => [
|
||||||
|
'userAgent' => 'hgfAlphaXCrawl/0.1 (+https://www.fim.uni-passau.de/data-science/forschung/open-search)',
|
||||||
|
'expectedBot' => 'Generic Bot',
|
||||||
|
],
|
||||||
|
19 => [
|
||||||
|
'userAgent' => 'Upflow/1.0',
|
||||||
|
'expectedBot' => 'Upflow',
|
||||||
|
],
|
||||||
|
20 => [
|
||||||
|
'userAgent' => 'crusty/0.12.0',
|
||||||
|
'expectedBot' => 'Crusty',
|
||||||
|
],
|
||||||
|
21 => [
|
||||||
|
'userAgent' => 'TelegramBot (like TwitterBot)',
|
||||||
|
'expectedBot' => 'TelegramBot',
|
||||||
|
],
|
||||||
|
22 => [
|
||||||
|
'userAgent' => 'python-requests/2.25.1',
|
||||||
|
'expectedBot' => 'Python Requests',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Recordview;
|
declare(strict_types=1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
@ -21,6 +21,8 @@ namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Recordview;
|
||||||
* 02110-1301, USA.
|
* 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Recordview;
|
||||||
|
|
||||||
use DanielSiepmann\Tracking\Domain\Model\RecordRule;
|
use DanielSiepmann\Tracking\Domain\Model\RecordRule;
|
||||||
use DanielSiepmann\Tracking\Domain\Model\Recordview;
|
use DanielSiepmann\Tracking\Domain\Model\Recordview;
|
||||||
use DanielSiepmann\Tracking\Domain\Recordview\Factory;
|
use DanielSiepmann\Tracking\Domain\Recordview\Factory;
|
||||||
|
@ -31,7 +33,7 @@ use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
|
||||||
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
|
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers DanielSiepmann\Tracking\Domain\Recordview\Factory
|
* @covers \DanielSiepmann\Tracking\Domain\Recordview\Factory
|
||||||
*/
|
*/
|
||||||
class FactoryTest extends FunctionalTestCase
|
class FactoryTest extends FunctionalTestCase
|
||||||
{
|
{
|
||||||
|
@ -67,7 +69,7 @@ class FactoryTest extends FunctionalTestCase
|
||||||
$subject = $this->get(Factory::class);
|
$subject = $this->get(Factory::class);
|
||||||
|
|
||||||
$result = $subject->fromRequest($request->reveal(), $rule->reveal());
|
$result = $subject->fromRequest($request->reveal(), $rule->reveal());
|
||||||
static::assertInstanceOf(Recordview::class, $result);
|
self::assertInstanceOf(Recordview::class, $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -96,7 +98,7 @@ class FactoryTest extends FunctionalTestCase
|
||||||
$subject = $this->get(Factory::class);
|
$subject = $this->get(Factory::class);
|
||||||
|
|
||||||
$result = $subject->fromRequest($request->reveal(), $rule->reveal());
|
$result = $subject->fromRequest($request->reveal(), $rule->reveal());
|
||||||
static::assertSame('Some User Agent', $result->getUserAgent());
|
self::assertSame('Some User Agent', $result->getUserAgent());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -125,7 +127,7 @@ class FactoryTest extends FunctionalTestCase
|
||||||
$subject = $this->get(Factory::class);
|
$subject = $this->get(Factory::class);
|
||||||
|
|
||||||
$result = $subject->fromRequest($request->reveal(), $rule->reveal());
|
$result = $subject->fromRequest($request->reveal(), $rule->reveal());
|
||||||
static::assertSame('https://example.com', $result->getUrl());
|
self::assertSame('https://example.com', $result->getUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -154,7 +156,7 @@ class FactoryTest extends FunctionalTestCase
|
||||||
$subject = $this->get(Factory::class);
|
$subject = $this->get(Factory::class);
|
||||||
|
|
||||||
$result = $subject->fromRequest($request->reveal(), $rule->reveal());
|
$result = $subject->fromRequest($request->reveal(), $rule->reveal());
|
||||||
static::assertInstanceOf(\DateTimeImmutable::class, $result->getCrdate());
|
self::assertInstanceOf(\DateTimeImmutable::class, $result->getCrdate());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -183,7 +185,7 @@ class FactoryTest extends FunctionalTestCase
|
||||||
$subject = $this->get(Factory::class);
|
$subject = $this->get(Factory::class);
|
||||||
|
|
||||||
$result = $subject->fromRequest($request->reveal(), $rule->reveal());
|
$result = $subject->fromRequest($request->reveal(), $rule->reveal());
|
||||||
static::assertSame($language->reveal(), $result->getLanguage());
|
self::assertSame($language->reveal(), $result->getLanguage());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -212,7 +214,7 @@ class FactoryTest extends FunctionalTestCase
|
||||||
$subject = $this->get(Factory::class);
|
$subject = $this->get(Factory::class);
|
||||||
|
|
||||||
$result = $subject->fromRequest($request->reveal(), $rule->reveal());
|
$result = $subject->fromRequest($request->reveal(), $rule->reveal());
|
||||||
static::assertSame(10, $result->getPageUid());
|
self::assertSame(10, $result->getPageUid());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -241,7 +243,7 @@ class FactoryTest extends FunctionalTestCase
|
||||||
$subject = $this->get(Factory::class);
|
$subject = $this->get(Factory::class);
|
||||||
|
|
||||||
$result = $subject->fromRequest($request->reveal(), $rule->reveal());
|
$result = $subject->fromRequest($request->reveal(), $rule->reveal());
|
||||||
static::assertSame(20, $result->getRecordUid());
|
self::assertSame(20, $result->getRecordUid());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -270,6 +272,6 @@ class FactoryTest extends FunctionalTestCase
|
||||||
$subject = $this->get(Factory::class);
|
$subject = $this->get(Factory::class);
|
||||||
|
|
||||||
$result = $subject->fromRequest($request->reveal(), $rule->reveal());
|
$result = $subject->fromRequest($request->reveal(), $rule->reveal());
|
||||||
static::assertSame('sys_category', $result->getTableName());
|
self::assertSame('sys_category', $result->getTableName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,4 +58,54 @@
|
||||||
<uid>10</uid>
|
<uid>10</uid>
|
||||||
<title>Page 10</title>
|
<title>Page 10</title>
|
||||||
</pages>
|
</pages>
|
||||||
|
<pages>
|
||||||
|
<pid>1</pid>
|
||||||
|
<uid>12</uid>
|
||||||
|
<title>Page 12</title>
|
||||||
|
</pages>
|
||||||
|
<pages>
|
||||||
|
<pid>1</pid>
|
||||||
|
<uid>13</uid>
|
||||||
|
<title>Page 13</title>
|
||||||
|
</pages>
|
||||||
|
<pages>
|
||||||
|
<pid>1</pid>
|
||||||
|
<uid>14</uid>
|
||||||
|
<title>Page 14</title>
|
||||||
|
</pages>
|
||||||
|
<pages>
|
||||||
|
<pid>1</pid>
|
||||||
|
<uid>15</uid>
|
||||||
|
<title>Page 15</title>
|
||||||
|
</pages>
|
||||||
|
<pages>
|
||||||
|
<pid>1</pid>
|
||||||
|
<uid>16</uid>
|
||||||
|
<title>Page 16</title>
|
||||||
|
</pages>
|
||||||
|
<pages>
|
||||||
|
<pid>1</pid>
|
||||||
|
<uid>17</uid>
|
||||||
|
<title>Page 17</title>
|
||||||
|
</pages>
|
||||||
|
<pages>
|
||||||
|
<pid>1</pid>
|
||||||
|
<uid>18</uid>
|
||||||
|
<title>Page 18</title>
|
||||||
|
</pages>
|
||||||
|
<pages>
|
||||||
|
<pid>1</pid>
|
||||||
|
<uid>19</uid>
|
||||||
|
<title>Page 19</title>
|
||||||
|
</pages>
|
||||||
|
<pages>
|
||||||
|
<pid>1</pid>
|
||||||
|
<uid>20</uid>
|
||||||
|
<title>Page 20</title>
|
||||||
|
</pages>
|
||||||
|
<pages>
|
||||||
|
<pid>1</pid>
|
||||||
|
<uid>21</uid>
|
||||||
|
<title>Page 21</title>
|
||||||
|
</pages>
|
||||||
</dataset>
|
</dataset>
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
<uid>1</uid>
|
<uid>1</uid>
|
||||||
<url>https://example.com/path</url>
|
<url>https://example.com/path</url>
|
||||||
<user_agent>Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36</user_agent>
|
<user_agent>Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36</user_agent>
|
||||||
<operating_system></operating_system>
|
|
||||||
</tx_tracking_pageview>
|
</tx_tracking_pageview>
|
||||||
<tx_tracking_recordview>
|
<tx_tracking_recordview>
|
||||||
<pid>1</pid>
|
<pid>1</pid>
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<dataset>
|
|
||||||
<pages>
|
|
||||||
<pid>0</pid>
|
|
||||||
<uid>1</uid>
|
|
||||||
</pages>
|
|
||||||
|
|
||||||
<tx_tracking_pageview>
|
|
||||||
<pid>1</pid>
|
|
||||||
<uid>1</uid>
|
|
||||||
<url>https://example.com/path</url>
|
|
||||||
<user_agent>Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36</user_agent>
|
|
||||||
<operating_system></operating_system>
|
|
||||||
</tx_tracking_pageview>
|
|
||||||
<tx_tracking_pageview>
|
|
||||||
<pid>1</pid>
|
|
||||||
<uid>2</uid>
|
|
||||||
<url>https://example.com/path</url>
|
|
||||||
<user_agent>Dalvik/2.1.0 (Linux; U; Android 9; ONEPLUS A3003 Build/PKQ1.181203.001)</user_agent>
|
|
||||||
<operating_system></operating_system>
|
|
||||||
</tx_tracking_pageview>
|
|
||||||
</dataset>
|
|
|
@ -1,22 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<dataset>
|
|
||||||
<pages>
|
|
||||||
<pid>0</pid>
|
|
||||||
<uid>1</uid>
|
|
||||||
</pages>
|
|
||||||
|
|
||||||
<tx_tracking_pageview>
|
|
||||||
<pid>1</pid>
|
|
||||||
<uid>1</uid>
|
|
||||||
<url>https://example.com/path</url>
|
|
||||||
<user_agent>Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36</user_agent>
|
|
||||||
<operating_system>Linux</operating_system>
|
|
||||||
</tx_tracking_pageview>
|
|
||||||
<tx_tracking_pageview>
|
|
||||||
<pid>1</pid>
|
|
||||||
<uid>2</uid>
|
|
||||||
<url>https://example.com/path</url>
|
|
||||||
<user_agent>Dalvik/2.1.0 (Linux; U; Android 9; ONEPLUS A3003 Build/PKQ1.181203.001)</user_agent>
|
|
||||||
<operating_system>Android</operating_system>
|
|
||||||
</tx_tracking_pageview>
|
|
||||||
</dataset>
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<dataset>
|
||||||
|
<pages>
|
||||||
|
<pid>0</pid>
|
||||||
|
<uid>1</uid>
|
||||||
|
</pages>
|
||||||
|
|
||||||
|
<tx_tracking_pageview>
|
||||||
|
<pid>1</pid>
|
||||||
|
<uid>1</uid>
|
||||||
|
<tstamp>1630649915</tstamp>
|
||||||
|
<cruser_id>0</cruser_id>
|
||||||
|
<url>https://example.com/path</url>
|
||||||
|
<user_agent>Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36</user_agent>
|
||||||
|
<compatible_version>v2.0.0</compatible_version>
|
||||||
|
</tx_tracking_pageview>
|
||||||
|
<tx_tracking_recordview>
|
||||||
|
<pid>1</pid>
|
||||||
|
<uid>1</uid>
|
||||||
|
<tstamp>1630649915</tstamp>
|
||||||
|
<cruser_id>0</cruser_id>
|
||||||
|
<url>https://example.com/path</url>
|
||||||
|
<user_agent>Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36</user_agent>
|
||||||
|
<record_uid>1</record_uid>
|
||||||
|
<record_table_name>sys_category</record_table_name>
|
||||||
|
<compatible_version>v2.0.0</compatible_version>
|
||||||
|
</tx_tracking_recordview>
|
||||||
|
<tx_tracking_tag>
|
||||||
|
<pid>1</pid>
|
||||||
|
<uid>1</uid>
|
||||||
|
<crdate>1663773639</crdate>
|
||||||
|
<record_uid>1</record_uid>
|
||||||
|
<record_table_name>tx_tracking_pageview</record_table_name>
|
||||||
|
<name>bot</name>
|
||||||
|
<value>no</value>
|
||||||
|
<compatible_version>v2.0.0</compatible_version>
|
||||||
|
</tx_tracking_tag>
|
||||||
|
<tx_tracking_tag>
|
||||||
|
<pid>1</pid>
|
||||||
|
<uid>v2</uid>
|
||||||
|
<crdate>1663773639</crdate>
|
||||||
|
<record_uid>1</record_uid>
|
||||||
|
<record_table_name>tx_tracking_pageview</record_table_name>
|
||||||
|
<name>os</name>
|
||||||
|
<value>Linux</value>
|
||||||
|
<compatible_version>v2.0.0</compatible_version>
|
||||||
|
</tx_tracking_tag>
|
||||||
|
<tx_tracking_tag>
|
||||||
|
<pid>1</pid>
|
||||||
|
<uid>3</uid>
|
||||||
|
<crdate>1663773639</crdate>
|
||||||
|
<record_uid>1</record_uid>
|
||||||
|
<record_table_name>tx_tracking_recordview</record_table_name>
|
||||||
|
<name>bot</name>
|
||||||
|
<value>no</value>
|
||||||
|
<compatible_version>v2.0.0</compatible_version>
|
||||||
|
</tx_tracking_tag>
|
||||||
|
<tx_tracking_tag>
|
||||||
|
<pid>1</pid>
|
||||||
|
<uid>4</uid>
|
||||||
|
<crdate>1663773639</crdate>
|
||||||
|
<record_uid>1</record_uid>
|
||||||
|
<record_table_name>tx_tracking_recordview</record_table_name>
|
||||||
|
<name>os</name>
|
||||||
|
<value>Linux</value>
|
||||||
|
<compatible_version>v2.0.0</compatible_version>
|
||||||
|
</tx_tracking_tag>
|
||||||
|
</dataset>
|
|
@ -0,0 +1,48 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<dataset>
|
||||||
|
<pages>
|
||||||
|
<pid>0</pid>
|
||||||
|
<uid>1</uid>
|
||||||
|
</pages>
|
||||||
|
|
||||||
|
<tx_tracking_pageview>
|
||||||
|
<pid>1</pid>
|
||||||
|
<uid>1</uid>
|
||||||
|
<crdate>1630649915</crdate>
|
||||||
|
<tstamp>1630649915</tstamp>
|
||||||
|
<cruser_id>0</cruser_id>
|
||||||
|
<url>https://example.com/path</url>
|
||||||
|
<user_agent>Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36</user_agent>
|
||||||
|
</tx_tracking_pageview>
|
||||||
|
<tx_tracking_pageview>
|
||||||
|
<pid>1</pid>
|
||||||
|
<uid>2</uid>
|
||||||
|
<crdate>1630649916</crdate>
|
||||||
|
<tstamp>1630649916</tstamp>
|
||||||
|
<cruser_id>0</cruser_id>
|
||||||
|
<url>https://example.com/path</url>
|
||||||
|
<user_agent>Dalvik/2.1.0 (Linux; U; Android 9; ONEPLUS A3003 Build/PKQ1.181203.001)</user_agent>
|
||||||
|
</tx_tracking_pageview>
|
||||||
|
<tx_tracking_recordview>
|
||||||
|
<pid>1</pid>
|
||||||
|
<uid>1</uid>
|
||||||
|
<crdate>1630649915</crdate>
|
||||||
|
<tstamp>1630649915</tstamp>
|
||||||
|
<cruser_id>0</cruser_id>
|
||||||
|
<url>https://example.com/path</url>
|
||||||
|
<user_agent>Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36</user_agent>
|
||||||
|
<record_uid>1</record_uid>
|
||||||
|
<record_table_name>sys_category</record_table_name>
|
||||||
|
</tx_tracking_recordview>
|
||||||
|
<tx_tracking_recordview>
|
||||||
|
<pid>1</pid>
|
||||||
|
<uid>2</uid>
|
||||||
|
<crdate>1630649916</crdate>
|
||||||
|
<tstamp>1630649916</tstamp>
|
||||||
|
<cruser_id>0</cruser_id>
|
||||||
|
<url>https://example.com/path</url>
|
||||||
|
<user_agent>Dalvik/2.1.0 (Linux; U; Android 9; ONEPLUS A3003 Build/PKQ1.181203.001)</user_agent>
|
||||||
|
<record_uid>1</record_uid>
|
||||||
|
<record_table_name>sys_category</record_table_name>
|
||||||
|
</tx_tracking_recordview>
|
||||||
|
</dataset>
|
|
@ -0,0 +1,50 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<dataset>
|
||||||
|
<pages>
|
||||||
|
<pid>0</pid>
|
||||||
|
<uid>1</uid>
|
||||||
|
</pages>
|
||||||
|
|
||||||
|
<tx_tracking_pageview>
|
||||||
|
<pid>1</pid>
|
||||||
|
<uid>1</uid>
|
||||||
|
<crdate>1630649915</crdate>
|
||||||
|
<tstamp>1630649915</tstamp>
|
||||||
|
<cruser_id>0</cruser_id>
|
||||||
|
<url>https://example.com/path</url>
|
||||||
|
<user_agent>Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36</user_agent>
|
||||||
|
</tx_tracking_pageview>
|
||||||
|
<tx_tracking_tag>
|
||||||
|
<pid>1</pid>
|
||||||
|
<uid>1</uid>
|
||||||
|
<crdate>1630649915</crdate>
|
||||||
|
<tstamp>1630649915</tstamp>
|
||||||
|
<cruser_id>0</cruser_id>
|
||||||
|
<record_uid>1</record_uid>
|
||||||
|
<record_table_name>tx_tracking_pageview</record_table_name>
|
||||||
|
<name>os</name>
|
||||||
|
<value>Linux</value>
|
||||||
|
<compatible_version>2.0.0</compatible_version>
|
||||||
|
</tx_tracking_tag>
|
||||||
|
<tx_tracking_pageview>
|
||||||
|
<pid>1</pid>
|
||||||
|
<uid>2</uid>
|
||||||
|
<crdate>1630649916</crdate>
|
||||||
|
<tstamp>1630649916</tstamp>
|
||||||
|
<cruser_id>0</cruser_id>
|
||||||
|
<url>https://example.com/path</url>
|
||||||
|
<user_agent>Dalvik/2.1.0 (Linux; U; Android 9; ONEPLUS A3003 Build/PKQ1.181203.001)</user_agent>
|
||||||
|
</tx_tracking_pageview>
|
||||||
|
<tx_tracking_tag>
|
||||||
|
<pid>1</pid>
|
||||||
|
<uid>2</uid>
|
||||||
|
<crdate>1630649916</crdate>
|
||||||
|
<tstamp>1630649916</tstamp>
|
||||||
|
<cruser_id>0</cruser_id>
|
||||||
|
<record_uid>2</record_uid>
|
||||||
|
<record_table_name>tx_tracking_pageview</record_table_name>
|
||||||
|
<name>os</name>
|
||||||
|
<value>Android</value>
|
||||||
|
<compatible_version>2.0.0</compatible_version>
|
||||||
|
</tx_tracking_tag>
|
||||||
|
</dataset>
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace DanielSiepmann\Tracking\Tests\Functional;
|
declare(strict_types=1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2021 Daniel Siepmann <coding@daniel-siepmann.de>
|
* Copyright (C) 2021 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
@ -21,6 +21,8 @@ namespace DanielSiepmann\Tracking\Tests\Functional;
|
||||||
* 02110-1301, USA.
|
* 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace DanielSiepmann\Tracking\Tests\Functional;
|
||||||
|
|
||||||
use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
|
use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
|
||||||
use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequestContext;
|
use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequestContext;
|
||||||
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase as TestCase;
|
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase as TestCase;
|
||||||
|
@ -62,12 +64,68 @@ class PageviewTest extends TestCase
|
||||||
|
|
||||||
$records = $this->getAllRecords('tx_tracking_pageview');
|
$records = $this->getAllRecords('tx_tracking_pageview');
|
||||||
self::assertCount(1, $records);
|
self::assertCount(1, $records);
|
||||||
self::assertSame('1', (string)$records[0]['pid']);
|
self::assertSame(1, $records[0]['pid']);
|
||||||
self::assertSame('1', (string)$records[0]['uid']);
|
self::assertSame(1, $records[0]['uid']);
|
||||||
self::assertSame('http://localhost/?id=1', $records[0]['url']);
|
self::assertSame('http://localhost/?id=1', $records[0]['url']);
|
||||||
self::assertSame('Mozilla/5.0 (Macintosh; Intel Mac OS X x.y; rv:42.0) Gecko/20100101 Firefox/42.0', $records[0]['user_agent']);
|
self::assertSame('Mozilla/5.0 (Macintosh; Intel Mac OS X x.y; rv:42.0) Gecko/20100101 Firefox/42.0', $records[0]['user_agent']);
|
||||||
self::assertSame('Macintosh', $records[0]['operating_system']);
|
|
||||||
self::assertSame('0', (string)$records[0]['type']);
|
self::assertSame('0', (string)$records[0]['type']);
|
||||||
|
|
||||||
|
$records = $this->getAllRecords('tx_tracking_tag');
|
||||||
|
self::assertCount(2, $records);
|
||||||
|
|
||||||
|
self::assertSame(1, $records[0]['pid']);
|
||||||
|
self::assertSame(1, $records[0]['record_uid']);
|
||||||
|
self::assertSame('tx_tracking_pageview', $records[0]['record_table_name']);
|
||||||
|
self::assertSame('bot', $records[0]['name']);
|
||||||
|
self::assertSame('no', $records[0]['value']);
|
||||||
|
|
||||||
|
self::assertSame(1, $records[1]['pid']);
|
||||||
|
self::assertSame(1, $records[1]['record_uid']);
|
||||||
|
self::assertSame('tx_tracking_pageview', $records[1]['record_table_name']);
|
||||||
|
self::assertSame('os', $records[1]['name']);
|
||||||
|
self::assertSame('Macintosh', $records[1]['value']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function trackedWithBotResolvedToTags(): void
|
||||||
|
{
|
||||||
|
$request = new InternalRequest();
|
||||||
|
$request = $request->withPageId(1);
|
||||||
|
$request = $request->withHeader('User-Agent', 'Slackbot-LinkExpanding 1.0 (+https://api.slack.com/robots)');
|
||||||
|
$response = $this->executeFrontendRequest($request);
|
||||||
|
|
||||||
|
self::assertSame(200, $response->getStatusCode());
|
||||||
|
|
||||||
|
$records = $this->getAllRecords('tx_tracking_pageview');
|
||||||
|
self::assertCount(1, $records);
|
||||||
|
self::assertSame(1, $records[0]['pid']);
|
||||||
|
self::assertSame(1, $records[0]['uid']);
|
||||||
|
self::assertSame('http://localhost/?id=1', $records[0]['url']);
|
||||||
|
self::assertSame('Slackbot-LinkExpanding 1.0 (+https://api.slack.com/robots)', $records[0]['user_agent']);
|
||||||
|
self::assertSame('0', (string)$records[0]['type']);
|
||||||
|
|
||||||
|
$records = $this->getAllRecords('tx_tracking_tag');
|
||||||
|
self::assertCount(3, $records);
|
||||||
|
|
||||||
|
self::assertSame(1, $records[0]['pid']);
|
||||||
|
self::assertSame(1, $records[0]['record_uid']);
|
||||||
|
self::assertSame('tx_tracking_pageview', $records[0]['record_table_name']);
|
||||||
|
self::assertSame('bot', $records[0]['name']);
|
||||||
|
self::assertSame('yes', $records[0]['value']);
|
||||||
|
|
||||||
|
self::assertSame(1, $records[1]['pid']);
|
||||||
|
self::assertSame(1, $records[1]['record_uid']);
|
||||||
|
self::assertSame('tx_tracking_pageview', $records[1]['record_table_name']);
|
||||||
|
self::assertSame('bot_name', $records[1]['name']);
|
||||||
|
self::assertSame('Slackbot', $records[1]['value']);
|
||||||
|
|
||||||
|
self::assertSame(1, $records[2]['pid']);
|
||||||
|
self::assertSame(1, $records[2]['record_uid']);
|
||||||
|
self::assertSame('tx_tracking_pageview', $records[2]['record_table_name']);
|
||||||
|
self::assertSame('os', $records[2]['name']);
|
||||||
|
self::assertSame('Unkown', $records[2]['value']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -85,7 +143,7 @@ class PageviewTest extends TestCase
|
||||||
|
|
||||||
self::assertSame(200, $response->getStatusCode());
|
self::assertSame(200, $response->getStatusCode());
|
||||||
|
|
||||||
$records = $this->getAllRecords('tx_tracking_pageview');
|
self::assertCount(0, $this->getAllRecords('tx_tracking_pageview'));
|
||||||
self::assertCount(0, $records);
|
self::assertCount(0, $this->getAllRecords('tx_tracking_tag'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace DanielSiepmann\Tracking\Tests\Functional;
|
declare(strict_types=1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2021 Daniel Siepmann <coding@daniel-siepmann.de>
|
* Copyright (C) 2021 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
@ -21,6 +21,8 @@ namespace DanielSiepmann\Tracking\Tests\Functional;
|
||||||
* 02110-1301, USA.
|
* 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace DanielSiepmann\Tracking\Tests\Functional;
|
||||||
|
|
||||||
use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
|
use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
|
||||||
use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequestContext;
|
use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequestContext;
|
||||||
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase as TestCase;
|
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase as TestCase;
|
||||||
|
@ -54,6 +56,7 @@ class RecordviewTest extends TestCase
|
||||||
*/
|
*/
|
||||||
public function trackedWhenAllowed(): void
|
public function trackedWhenAllowed(): void
|
||||||
{
|
{
|
||||||
|
$this->setUpBackendUserFromFixture(1);
|
||||||
$request = new InternalRequest();
|
$request = new InternalRequest();
|
||||||
$request = $request->withPageId(1);
|
$request = $request->withPageId(1);
|
||||||
$request = $request->withQueryParameter('topic_id', 1);
|
$request = $request->withQueryParameter('topic_id', 1);
|
||||||
|
@ -64,14 +67,28 @@ class RecordviewTest extends TestCase
|
||||||
|
|
||||||
$records = $this->getAllRecords('tx_tracking_recordview');
|
$records = $this->getAllRecords('tx_tracking_recordview');
|
||||||
self::assertCount(1, $records);
|
self::assertCount(1, $records);
|
||||||
self::assertSame('1', (string)$records[0]['pid']);
|
self::assertSame(1, $records[0]['pid']);
|
||||||
self::assertSame('1', (string)$records[0]['uid']);
|
self::assertSame(1, $records[0]['uid']);
|
||||||
self::assertSame('http://localhost/?id=1&topic_id=1', $records[0]['url']);
|
self::assertSame('http://localhost/?id=1&topic_id=1', $records[0]['url']);
|
||||||
self::assertSame('Mozilla/5.0 (Macintosh; Intel Mac OS X x.y; rv:42.0) Gecko/20100101 Firefox/42.0', $records[0]['user_agent']);
|
self::assertSame('Mozilla/5.0 (Macintosh; Intel Mac OS X x.y; rv:42.0) Gecko/20100101 Firefox/42.0', $records[0]['user_agent']);
|
||||||
self::assertSame('Macintosh', $records[0]['operating_system']);
|
|
||||||
self::assertSame('sys_category_1', $records[0]['record']);
|
self::assertSame('sys_category_1', $records[0]['record']);
|
||||||
self::assertSame('1', (string)$records[0]['record_uid']);
|
self::assertSame(1, $records[0]['record_uid']);
|
||||||
self::assertSame('sys_category', $records[0]['record_table_name']);
|
self::assertSame('sys_category', $records[0]['record_table_name']);
|
||||||
|
|
||||||
|
$records = $this->getAllRecords('tx_tracking_tag');
|
||||||
|
self::assertCount(4, $records);
|
||||||
|
|
||||||
|
self::assertSame(1, $records[2]['pid']);
|
||||||
|
self::assertSame(1, $records[2]['record_uid']);
|
||||||
|
self::assertSame('tx_tracking_recordview', $records[2]['record_table_name']);
|
||||||
|
self::assertSame('bot', $records[2]['name']);
|
||||||
|
self::assertSame('no', $records[2]['value']);
|
||||||
|
|
||||||
|
self::assertSame(1, $records[3]['pid']);
|
||||||
|
self::assertSame(1, $records[3]['record_uid']);
|
||||||
|
self::assertSame('tx_tracking_recordview', $records[3]['record_table_name']);
|
||||||
|
self::assertSame('os', $records[3]['name']);
|
||||||
|
self::assertSame('Macintosh', $records[3]['value']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace DanielSiepmann\Tracking\Tests\Functional;
|
declare(strict_types=1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2021 Daniel Siepmann <coding@daniel-siepmann.de>
|
* Copyright (C) 2021 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
@ -21,13 +21,15 @@ namespace DanielSiepmann\Tracking\Tests\Functional;
|
||||||
* 02110-1301, USA.
|
* 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace DanielSiepmann\Tracking\Tests\Functional;
|
||||||
|
|
||||||
use DanielSiepmann\Tracking\Functional\CopyingPageWithRecordsWorks;
|
use DanielSiepmann\Tracking\Functional\CopyingPageWithRecordsWorks;
|
||||||
use TYPO3\CMS\Core\DataHandling\DataHandler;
|
use TYPO3\CMS\Core\DataHandling\DataHandler;
|
||||||
use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
|
use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
|
||||||
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase as TestCase;
|
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase as TestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers \DanielSiepmann\Tracking\Functional\CopyingPageWithRecordsWorks
|
* @covers \DanielSiepmann\Tracking\Hooks\DataHandler
|
||||||
* @testdox This extension works with TYPO3 feature:
|
* @testdox This extension works with TYPO3 feature:
|
||||||
*/
|
*/
|
||||||
class Typo3FeaturesTest extends TestCase
|
class Typo3FeaturesTest extends TestCase
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Model;
|
declare(strict_types=1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
@ -21,32 +21,54 @@ namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Model;
|
||||||
* 02110-1301, USA.
|
* 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Extractors;
|
||||||
|
|
||||||
|
use DanielSiepmann\Tracking\Domain\Extractors\OperatingSystem;
|
||||||
use DanielSiepmann\Tracking\Domain\Model\Extractor;
|
use DanielSiepmann\Tracking\Domain\Model\Extractor;
|
||||||
use DanielSiepmann\Tracking\Domain\Model\HasUserAgent;
|
use DanielSiepmann\Tracking\Domain\Model\Pageview;
|
||||||
|
use DanielSiepmann\Tracking\Domain\Model\Recordview;
|
||||||
use Prophecy\PhpUnit\ProphecyTrait;
|
use Prophecy\PhpUnit\ProphecyTrait;
|
||||||
use TYPO3\TestingFramework\Core\Unit\UnitTestCase as TestCase;
|
use TYPO3\TestingFramework\Core\Unit\UnitTestCase as TestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers DanielSiepmann\Tracking\Domain\Model\Extractor
|
* @covers \DanielSiepmann\Tracking\Domain\Extractors\OperatingSystem
|
||||||
*/
|
*/
|
||||||
class ExtractorTest extends TestCase
|
class OperatingSystemTest extends TestCase
|
||||||
{
|
{
|
||||||
use ProphecyTrait;
|
use ProphecyTrait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @test
|
* @test
|
||||||
* @dataProvider possibleUserStringWithOperatingSystems
|
* @dataProvider possibleUserStringWithOperatingSystems
|
||||||
* @testdox Operating system $expectedOperatingSystem is extracted from UserAgent string: $userAgent
|
* @testdox Operating system $expectedOperatingSystem is extracted from Pageview UserAgent string: $userAgent
|
||||||
*/
|
*/
|
||||||
public function returnsOperatingSystem(string $userAgent, string $expectedOperatingSystem): void
|
public function returnsOperatingSystemForPageview(string $userAgent, string $expectedOperatingSystem): void
|
||||||
{
|
{
|
||||||
$model = $this->prophesize(HasUserAgent::class);
|
$model = $this->prophesize(Pageview::class);
|
||||||
$model->getUserAgent()->willReturn($userAgent);
|
$model->getUserAgent()->willReturn($userAgent);
|
||||||
|
|
||||||
static::assertSame(
|
$extractor = new OperatingSystem();
|
||||||
$expectedOperatingSystem,
|
$tags = $extractor->extractTagFromPageview($model->reveal());
|
||||||
Extractor::getOperatingSystem($model->reveal())
|
|
||||||
);
|
self::assertCount(1, $tags);
|
||||||
|
self::assertSame($expectedOperatingSystem, $tags[0]->getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @dataProvider possibleUserStringWithOperatingSystems
|
||||||
|
* @testdox Operating system $expectedOperatingSystem is extracted from Recordview UserAgent string: $userAgent
|
||||||
|
*/
|
||||||
|
public function returnsOperatingSystemForRecordview(string $userAgent, string $expectedOperatingSystem): void
|
||||||
|
{
|
||||||
|
$model = $this->prophesize(Recordview::class);
|
||||||
|
$model->getUserAgent()->willReturn($userAgent);
|
||||||
|
|
||||||
|
$extractor = new OperatingSystem();
|
||||||
|
$tags = $extractor->extractTagFromRecordview($model->reveal());
|
||||||
|
|
||||||
|
self::assertCount(1, $tags);
|
||||||
|
self::assertSame($expectedOperatingSystem, $tags[0]->getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function possibleUserStringWithOperatingSystems(): array
|
public function possibleUserStringWithOperatingSystems(): array
|
||||||
|
@ -62,11 +84,11 @@ class ExtractorTest extends TestCase
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'userAgent' => 'Apache-HttpClient/4.5.2 (Java/1.8.0_151)',
|
'userAgent' => 'Apache-HttpClient/4.5.2 (Java/1.8.0_151)',
|
||||||
'expectedOperatingSystem' => '',
|
'expectedOperatingSystem' => 'Unkown',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'userAgent' => 'AwarioSmartBot/1.0 (+https://awario.com/bots.html; bots@awario.com)',
|
'userAgent' => 'AwarioSmartBot/1.0 (+https://awario.com/bots.html; bots@awario.com)',
|
||||||
'expectedOperatingSystem' => '',
|
'expectedOperatingSystem' => 'Unkown',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'userAgent' => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)',
|
'userAgent' => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)',
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Model;
|
declare(strict_types=1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
@ -21,13 +21,15 @@ namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Model;
|
||||||
* 02110-1301, USA.
|
* 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Model;
|
||||||
|
|
||||||
use DanielSiepmann\Tracking\Domain\Model\Pageview;
|
use DanielSiepmann\Tracking\Domain\Model\Pageview;
|
||||||
use Prophecy\PhpUnit\ProphecyTrait;
|
use Prophecy\PhpUnit\ProphecyTrait;
|
||||||
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
|
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
|
||||||
use TYPO3\TestingFramework\Core\Unit\UnitTestCase as TestCase;
|
use TYPO3\TestingFramework\Core\Unit\UnitTestCase as TestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers DanielSiepmann\Tracking\Domain\Model\Pageview
|
* @covers \DanielSiepmann\Tracking\Domain\Model\Pageview
|
||||||
*/
|
*/
|
||||||
class PageviewTest extends TestCase
|
class PageviewTest extends TestCase
|
||||||
{
|
{
|
||||||
|
@ -49,7 +51,7 @@ class PageviewTest extends TestCase
|
||||||
''
|
''
|
||||||
);
|
);
|
||||||
|
|
||||||
static::assertInstanceOf(Pageview::class, $subject);
|
self::assertInstanceOf(Pageview::class, $subject);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -68,7 +70,7 @@ class PageviewTest extends TestCase
|
||||||
''
|
''
|
||||||
);
|
);
|
||||||
|
|
||||||
static::assertSame(500, $subject->getPageUid());
|
self::assertSame(500, $subject->getPageUid());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -87,7 +89,7 @@ class PageviewTest extends TestCase
|
||||||
''
|
''
|
||||||
);
|
);
|
||||||
|
|
||||||
static::assertSame($language->reveal(), $subject->getLanguage());
|
self::assertSame($language->reveal(), $subject->getLanguage());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -107,7 +109,7 @@ class PageviewTest extends TestCase
|
||||||
''
|
''
|
||||||
);
|
);
|
||||||
|
|
||||||
static::assertSame($crdate, $subject->getCrdate());
|
self::assertSame($crdate, $subject->getCrdate());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -126,7 +128,7 @@ class PageviewTest extends TestCase
|
||||||
''
|
''
|
||||||
);
|
);
|
||||||
|
|
||||||
static::assertSame(999, $subject->getPageType());
|
self::assertSame(999, $subject->getPageType());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -145,7 +147,7 @@ class PageviewTest extends TestCase
|
||||||
''
|
''
|
||||||
);
|
);
|
||||||
|
|
||||||
static::assertSame('https://example.com/path.html', $subject->getUrl());
|
self::assertSame('https://example.com/path.html', $subject->getUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -164,7 +166,7 @@ class PageviewTest extends TestCase
|
||||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0'
|
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0'
|
||||||
);
|
);
|
||||||
|
|
||||||
static::assertSame(
|
self::assertSame(
|
||||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0',
|
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0',
|
||||||
$subject->getUserAgent()
|
$subject->getUserAgent()
|
||||||
);
|
);
|
||||||
|
@ -186,7 +188,7 @@ class PageviewTest extends TestCase
|
||||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0'
|
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0'
|
||||||
);
|
);
|
||||||
|
|
||||||
static::assertSame(
|
self::assertSame(
|
||||||
0,
|
0,
|
||||||
$subject->getUid()
|
$subject->getUid()
|
||||||
);
|
);
|
||||||
|
@ -209,31 +211,9 @@ class PageviewTest extends TestCase
|
||||||
10
|
10
|
||||||
);
|
);
|
||||||
|
|
||||||
static::assertSame(
|
self::assertSame(
|
||||||
10,
|
10,
|
||||||
$subject->getUid()
|
$subject->getUid()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @test
|
|
||||||
*/
|
|
||||||
public function returnsOperatingSystem(): void
|
|
||||||
{
|
|
||||||
$language = $this->prophesize(SiteLanguage::class);
|
|
||||||
|
|
||||||
$subject = new Pageview(
|
|
||||||
0,
|
|
||||||
$language->reveal(),
|
|
||||||
new \DateTimeImmutable(),
|
|
||||||
0,
|
|
||||||
'',
|
|
||||||
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36'
|
|
||||||
);
|
|
||||||
|
|
||||||
static::assertSame(
|
|
||||||
'Linux',
|
|
||||||
$subject->getOperatingSystem()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Model;
|
declare(strict_types=1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
@ -21,11 +21,13 @@ namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Model;
|
||||||
* 02110-1301, USA.
|
* 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Model;
|
||||||
|
|
||||||
use DanielSiepmann\Tracking\Domain\Model\RecordRule;
|
use DanielSiepmann\Tracking\Domain\Model\RecordRule;
|
||||||
use TYPO3\TestingFramework\Core\Unit\UnitTestCase as TestCase;
|
use TYPO3\TestingFramework\Core\Unit\UnitTestCase as TestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers DanielSiepmann\Tracking\Domain\Model\RecordRule
|
* @covers \DanielSiepmann\Tracking\Domain\Model\RecordRule
|
||||||
*/
|
*/
|
||||||
class RecordRuleTest extends TestCase
|
class RecordRuleTest extends TestCase
|
||||||
{
|
{
|
||||||
|
@ -40,7 +42,7 @@ class RecordRuleTest extends TestCase
|
||||||
''
|
''
|
||||||
);
|
);
|
||||||
|
|
||||||
static::assertInstanceOf(RecordRule::class, $subject);
|
self::assertInstanceOf(RecordRule::class, $subject);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -55,7 +57,7 @@ class RecordRuleTest extends TestCase
|
||||||
'tableName' => '',
|
'tableName' => '',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
static::assertInstanceOf(RecordRule::class, $subject);
|
self::assertInstanceOf(RecordRule::class, $subject);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -76,9 +78,9 @@ class RecordRuleTest extends TestCase
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
static::assertCount(2, $result);
|
self::assertCount(2, $result);
|
||||||
static::assertInstanceOf(RecordRule::class, $result[0]);
|
self::assertInstanceOf(RecordRule::class, $result[0]);
|
||||||
static::assertInstanceOf(RecordRule::class, $result[1]);
|
self::assertInstanceOf(RecordRule::class, $result[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -92,7 +94,7 @@ class RecordRuleTest extends TestCase
|
||||||
''
|
''
|
||||||
);
|
);
|
||||||
|
|
||||||
static::assertSame('match expression', $subject->getMatchesExpression());
|
self::assertSame('match expression', $subject->getMatchesExpression());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -106,7 +108,7 @@ class RecordRuleTest extends TestCase
|
||||||
''
|
''
|
||||||
);
|
);
|
||||||
|
|
||||||
static::assertSame('match expression', $subject->getUidExpression());
|
self::assertSame('match expression', $subject->getUidExpression());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -120,6 +122,6 @@ class RecordRuleTest extends TestCase
|
||||||
'table_name'
|
'table_name'
|
||||||
);
|
);
|
||||||
|
|
||||||
static::assertSame('table_name', $subject->getTableName());
|
self::assertSame('table_name', $subject->getTableName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Model;
|
declare(strict_types=1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
@ -21,13 +21,15 @@ namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Model;
|
||||||
* 02110-1301, USA.
|
* 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Model;
|
||||||
|
|
||||||
use DanielSiepmann\Tracking\Domain\Model\Recordview;
|
use DanielSiepmann\Tracking\Domain\Model\Recordview;
|
||||||
use Prophecy\PhpUnit\ProphecyTrait;
|
use Prophecy\PhpUnit\ProphecyTrait;
|
||||||
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
|
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
|
||||||
use TYPO3\TestingFramework\Core\Unit\UnitTestCase as TestCase;
|
use TYPO3\TestingFramework\Core\Unit\UnitTestCase as TestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers DanielSiepmann\Tracking\Domain\Model\Recordview
|
* @covers \DanielSiepmann\Tracking\Domain\Model\Recordview
|
||||||
*/
|
*/
|
||||||
class RecordviewTest extends TestCase
|
class RecordviewTest extends TestCase
|
||||||
{
|
{
|
||||||
|
@ -50,7 +52,7 @@ class RecordviewTest extends TestCase
|
||||||
'sys_category'
|
'sys_category'
|
||||||
);
|
);
|
||||||
|
|
||||||
static::assertInstanceOf(Recordview::class, $subject);
|
self::assertInstanceOf(Recordview::class, $subject);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -70,7 +72,7 @@ class RecordviewTest extends TestCase
|
||||||
'sys_category'
|
'sys_category'
|
||||||
);
|
);
|
||||||
|
|
||||||
static::assertSame(500, $subject->getPageUid());
|
self::assertSame(500, $subject->getPageUid());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -90,7 +92,7 @@ class RecordviewTest extends TestCase
|
||||||
'sys_category'
|
'sys_category'
|
||||||
);
|
);
|
||||||
|
|
||||||
static::assertSame($language->reveal(), $subject->getLanguage());
|
self::assertSame($language->reveal(), $subject->getLanguage());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -111,7 +113,7 @@ class RecordviewTest extends TestCase
|
||||||
'sys_category'
|
'sys_category'
|
||||||
);
|
);
|
||||||
|
|
||||||
static::assertSame($crdate, $subject->getCrdate());
|
self::assertSame($crdate, $subject->getCrdate());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -131,7 +133,7 @@ class RecordviewTest extends TestCase
|
||||||
'sys_category'
|
'sys_category'
|
||||||
);
|
);
|
||||||
|
|
||||||
static::assertSame('https://example.com/path.html', $subject->getUrl());
|
self::assertSame('https://example.com/path.html', $subject->getUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -151,7 +153,7 @@ class RecordviewTest extends TestCase
|
||||||
'sys_category'
|
'sys_category'
|
||||||
);
|
);
|
||||||
|
|
||||||
static::assertSame(
|
self::assertSame(
|
||||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0',
|
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0',
|
||||||
$subject->getUserAgent()
|
$subject->getUserAgent()
|
||||||
);
|
);
|
||||||
|
@ -174,7 +176,7 @@ class RecordviewTest extends TestCase
|
||||||
'sys_category'
|
'sys_category'
|
||||||
);
|
);
|
||||||
|
|
||||||
static::assertSame(
|
self::assertSame(
|
||||||
10,
|
10,
|
||||||
$subject->getRecordUid()
|
$subject->getRecordUid()
|
||||||
);
|
);
|
||||||
|
@ -197,32 +199,9 @@ class RecordviewTest extends TestCase
|
||||||
'sys_category'
|
'sys_category'
|
||||||
);
|
);
|
||||||
|
|
||||||
static::assertSame(
|
self::assertSame(
|
||||||
'sys_category',
|
'sys_category',
|
||||||
$subject->getTableName()
|
$subject->getTableName()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @test
|
|
||||||
*/
|
|
||||||
public function returnsOperatingSystem(): void
|
|
||||||
{
|
|
||||||
$language = $this->prophesize(SiteLanguage::class);
|
|
||||||
|
|
||||||
$subject = new Recordview(
|
|
||||||
0,
|
|
||||||
$language->reveal(),
|
|
||||||
new \DateTimeImmutable(),
|
|
||||||
'',
|
|
||||||
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36',
|
|
||||||
10,
|
|
||||||
'sys_category'
|
|
||||||
);
|
|
||||||
|
|
||||||
static::assertSame(
|
|
||||||
'Linux',
|
|
||||||
$subject->getOperatingSystem()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Pageview;
|
declare(strict_types=1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
@ -21,6 +21,8 @@ namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Pageview;
|
||||||
* 02110-1301, USA.
|
* 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Pageview;
|
||||||
|
|
||||||
use DanielSiepmann\Tracking\Domain\Model\Pageview;
|
use DanielSiepmann\Tracking\Domain\Model\Pageview;
|
||||||
use DanielSiepmann\Tracking\Domain\Pageview\Factory;
|
use DanielSiepmann\Tracking\Domain\Pageview\Factory;
|
||||||
use Prophecy\PhpUnit\ProphecyTrait;
|
use Prophecy\PhpUnit\ProphecyTrait;
|
||||||
|
@ -33,7 +35,7 @@ use TYPO3\CMS\Core\Site\SiteFinder;
|
||||||
use TYPO3\TestingFramework\Core\Unit\UnitTestCase as TestCase;
|
use TYPO3\TestingFramework\Core\Unit\UnitTestCase as TestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers DanielSiepmann\Tracking\Domain\Pageview\Factory
|
* @covers \DanielSiepmann\Tracking\Domain\Pageview\Factory
|
||||||
*/
|
*/
|
||||||
class FactoryTest extends TestCase
|
class FactoryTest extends TestCase
|
||||||
{
|
{
|
||||||
|
@ -59,7 +61,7 @@ class FactoryTest extends TestCase
|
||||||
$subject = new Factory($this->prophesize(SiteFinder::class)->reveal());
|
$subject = new Factory($this->prophesize(SiteFinder::class)->reveal());
|
||||||
|
|
||||||
$result = $subject->fromRequest($request->reveal());
|
$result = $subject->fromRequest($request->reveal());
|
||||||
static::assertInstanceOf(Pageview::class, $result);
|
self::assertInstanceOf(Pageview::class, $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -84,7 +86,7 @@ class FactoryTest extends TestCase
|
||||||
$subject = new Factory($this->prophesize(SiteFinder::class)->reveal());
|
$subject = new Factory($this->prophesize(SiteFinder::class)->reveal());
|
||||||
|
|
||||||
$result = $subject->fromRequest($request->reveal());
|
$result = $subject->fromRequest($request->reveal());
|
||||||
static::assertSame(
|
self::assertSame(
|
||||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0',
|
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0',
|
||||||
$result->getUserAgent()
|
$result->getUserAgent()
|
||||||
);
|
);
|
||||||
|
@ -110,7 +112,7 @@ class FactoryTest extends TestCase
|
||||||
$subject = new Factory($this->prophesize(SiteFinder::class)->reveal());
|
$subject = new Factory($this->prophesize(SiteFinder::class)->reveal());
|
||||||
|
|
||||||
$result = $subject->fromRequest($request->reveal());
|
$result = $subject->fromRequest($request->reveal());
|
||||||
static::assertSame(
|
self::assertSame(
|
||||||
'https://example.com/path?query=params&some=more#anchor',
|
'https://example.com/path?query=params&some=more#anchor',
|
||||||
$result->getUrl()
|
$result->getUrl()
|
||||||
);
|
);
|
||||||
|
@ -136,7 +138,7 @@ class FactoryTest extends TestCase
|
||||||
$subject = new Factory($this->prophesize(SiteFinder::class)->reveal());
|
$subject = new Factory($this->prophesize(SiteFinder::class)->reveal());
|
||||||
|
|
||||||
$result = $subject->fromRequest($request->reveal());
|
$result = $subject->fromRequest($request->reveal());
|
||||||
static::assertSame(
|
self::assertSame(
|
||||||
50,
|
50,
|
||||||
$result->getPageType()
|
$result->getPageType()
|
||||||
);
|
);
|
||||||
|
@ -162,7 +164,7 @@ class FactoryTest extends TestCase
|
||||||
$subject = new Factory($this->prophesize(SiteFinder::class)->reveal());
|
$subject = new Factory($this->prophesize(SiteFinder::class)->reveal());
|
||||||
|
|
||||||
$result = $subject->fromRequest($request->reveal());
|
$result = $subject->fromRequest($request->reveal());
|
||||||
static::assertInstanceOf(\DateTimeImmutable::class, $result->getCrdate());
|
self::assertInstanceOf(\DateTimeImmutable::class, $result->getCrdate());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -185,7 +187,7 @@ class FactoryTest extends TestCase
|
||||||
$subject = new Factory($this->prophesize(SiteFinder::class)->reveal());
|
$subject = new Factory($this->prophesize(SiteFinder::class)->reveal());
|
||||||
|
|
||||||
$result = $subject->fromRequest($request->reveal());
|
$result = $subject->fromRequest($request->reveal());
|
||||||
static::assertInstanceOf(SiteLanguage::class, $result->getLanguage());
|
self::assertInstanceOf(SiteLanguage::class, $result->getLanguage());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -208,7 +210,7 @@ class FactoryTest extends TestCase
|
||||||
$subject = new Factory($this->prophesize(SiteFinder::class)->reveal());
|
$subject = new Factory($this->prophesize(SiteFinder::class)->reveal());
|
||||||
|
|
||||||
$result = $subject->fromRequest($request->reveal());
|
$result = $subject->fromRequest($request->reveal());
|
||||||
static::assertSame(
|
self::assertSame(
|
||||||
10,
|
10,
|
||||||
$result->getPageUid()
|
$result->getPageUid()
|
||||||
);
|
);
|
||||||
|
@ -237,13 +239,13 @@ class FactoryTest extends TestCase
|
||||||
'user_agent' => 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36',
|
'user_agent' => 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
static::assertInstanceOf(Pageview::class, $result);
|
self::assertInstanceOf(Pageview::class, $result);
|
||||||
static::assertSame(1, $result->getUid());
|
self::assertSame(1, $result->getUid());
|
||||||
static::assertSame(2, $result->getPageUid());
|
self::assertSame(2, $result->getPageUid());
|
||||||
static::assertSame($siteLanguage->reveal(), $result->getLanguage());
|
self::assertSame($siteLanguage->reveal(), $result->getLanguage());
|
||||||
static::assertSame('1533906435', $result->getCrdate()->format('U'));
|
self::assertSame('1533906435', $result->getCrdate()->format('U'));
|
||||||
static::assertSame(0, $result->getPageType());
|
self::assertSame(0, $result->getPageType());
|
||||||
static::assertSame('https://example.com/path', $result->getUrl());
|
self::assertSame('https://example.com/path', $result->getUrl());
|
||||||
static::assertSame('Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36', $result->getUserAgent());
|
self::assertSame('Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36', $result->getUserAgent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,231 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Repository;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
use DanielSiepmann\Tracking\Domain\Model\Pageview as Model;
|
|
||||||
use DanielSiepmann\Tracking\Domain\Pageview\Factory;
|
|
||||||
use DanielSiepmann\Tracking\Domain\Repository\Pageview;
|
|
||||||
use Doctrine\DBAL\Statement;
|
|
||||||
use Prophecy\PhpUnit\ProphecyTrait;
|
|
||||||
use TYPO3\CMS\Core\Database\Connection;
|
|
||||||
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
|
|
||||||
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
|
|
||||||
use TYPO3\TestingFramework\Core\Unit\UnitTestCase as TestCase;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @covers DanielSiepmann\Tracking\Domain\Repository\Pageview
|
|
||||||
*/
|
|
||||||
class PageviewTest extends TestCase
|
|
||||||
{
|
|
||||||
use ProphecyTrait;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @test
|
|
||||||
*/
|
|
||||||
public function modelCanBeAdded(): void
|
|
||||||
{
|
|
||||||
$connection = $this->prophesize(Connection::class);
|
|
||||||
$factory = $this->prophesize(Factory::class);
|
|
||||||
|
|
||||||
$dateTime = $this->prophesize(\DateTimeImmutable::class);
|
|
||||||
$dateTime->format('U')->willReturn(1582660189);
|
|
||||||
|
|
||||||
$language = $this->prophesize(SiteLanguage::class);
|
|
||||||
$language->getLanguageId()->willReturn(2);
|
|
||||||
|
|
||||||
$model = $this->prophesize(Model::class);
|
|
||||||
$model->getPageUid()->willReturn(10);
|
|
||||||
$model->getCrdate()->willReturn($dateTime->reveal());
|
|
||||||
$model->getPageType()->willReturn(999);
|
|
||||||
$model->getLanguage()->willReturn($language->reveal());
|
|
||||||
$model->getUrl()->willReturn('https://example.com/path.html');
|
|
||||||
$model->getUserAgent()->willReturn('Mozilla/5.0 (Windows NT 10.0) Gecko/20100101 Firefox/74.0');
|
|
||||||
$model->getOperatingSystem()->willReturn('Linux');
|
|
||||||
|
|
||||||
$connection->insert(
|
|
||||||
'tx_tracking_pageview',
|
|
||||||
[
|
|
||||||
'pid' => 10,
|
|
||||||
'crdate' => 1582660189,
|
|
||||||
'tstamp' => 1582660189,
|
|
||||||
'type' => 999,
|
|
||||||
'sys_language_uid' => 2,
|
|
||||||
'url' => 'https://example.com/path.html',
|
|
||||||
'user_agent' => 'Mozilla/5.0 (Windows NT 10.0) Gecko/20100101 Firefox/74.0',
|
|
||||||
'operating_system' => 'Linux',
|
|
||||||
]
|
|
||||||
)->willReturn(1)->shouldBeCalledTimes(1);
|
|
||||||
|
|
||||||
$subject = new Pageview($connection->reveal(), $factory->reveal());
|
|
||||||
$subject->add($model->reveal());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @test
|
|
||||||
*/
|
|
||||||
public function throwsExceptionIfModelToUodateHasNoUid(): void
|
|
||||||
{
|
|
||||||
$connection = $this->prophesize(Connection::class);
|
|
||||||
$factory = $this->prophesize(Factory::class);
|
|
||||||
|
|
||||||
$model = $this->prophesize(Model::class);
|
|
||||||
$model->getUid()->willReturn(0);
|
|
||||||
|
|
||||||
$subject = new Pageview($connection->reveal(), $factory->reveal());
|
|
||||||
$this->expectExceptionMessage('Can not update pageview if uid is 0.');
|
|
||||||
$subject->update($model->reveal());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @test
|
|
||||||
*/
|
|
||||||
public function modelCanBeUpdated(): void
|
|
||||||
{
|
|
||||||
$connection = $this->prophesize(Connection::class);
|
|
||||||
$factory = $this->prophesize(Factory::class);
|
|
||||||
|
|
||||||
$dateTime = $this->prophesize(\DateTimeImmutable::class);
|
|
||||||
$dateTime->format('U')->willReturn(1582660189);
|
|
||||||
|
|
||||||
$language = $this->prophesize(SiteLanguage::class);
|
|
||||||
$language->getLanguageId()->willReturn(2);
|
|
||||||
|
|
||||||
$model = $this->prophesize(Model::class);
|
|
||||||
$model->getUid()->willReturn(1);
|
|
||||||
$model->getPageUid()->willReturn(10);
|
|
||||||
$model->getCrdate()->willReturn($dateTime->reveal());
|
|
||||||
$model->getPageType()->willReturn(999);
|
|
||||||
$model->getLanguage()->willReturn($language->reveal());
|
|
||||||
$model->getUrl()->willReturn('https://example.com/path.html');
|
|
||||||
$model->getUserAgent()->willReturn('Mozilla/5.0 (Windows NT 10.0) Gecko/20100101 Firefox/74.0');
|
|
||||||
$model->getOperatingSystem()->willReturn('Linux');
|
|
||||||
|
|
||||||
$connection->update(
|
|
||||||
'tx_tracking_pageview',
|
|
||||||
[
|
|
||||||
'pid' => 10,
|
|
||||||
'crdate' => 1582660189,
|
|
||||||
'tstamp' => 1582660189,
|
|
||||||
'type' => 999,
|
|
||||||
'sys_language_uid' => 2,
|
|
||||||
'url' => 'https://example.com/path.html',
|
|
||||||
'user_agent' => 'Mozilla/5.0 (Windows NT 10.0) Gecko/20100101 Firefox/74.0',
|
|
||||||
'operating_system' => 'Linux',
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'uid' => 1
|
|
||||||
]
|
|
||||||
)->willReturn(1)->shouldBeCalledTimes(1);
|
|
||||||
|
|
||||||
$subject = new Pageview($connection->reveal(), $factory->reveal());
|
|
||||||
$subject->update($model->reveal());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @test
|
|
||||||
*/
|
|
||||||
public function returnsACountOfAllModels(): void
|
|
||||||
{
|
|
||||||
$statement = $this->prophesize(Statement::class);
|
|
||||||
$statement->fetchColumn()->willReturn(10);
|
|
||||||
|
|
||||||
$queryBuilder = $this->prophesize(QueryBuilder::class);
|
|
||||||
$queryBuilder->count('uid')->willReturn($queryBuilder->reveal());
|
|
||||||
$queryBuilder->from('tx_tracking_pageview')->willReturn($queryBuilder->reveal());
|
|
||||||
$queryBuilder->execute()->willReturn($statement->reveal());
|
|
||||||
|
|
||||||
$connection = $this->prophesize(Connection::class);
|
|
||||||
$connection->createQueryBuilder()->willReturn($queryBuilder->reveal());
|
|
||||||
|
|
||||||
$factory = $this->prophesize(Factory::class);
|
|
||||||
|
|
||||||
$subject = new Pageview($connection->reveal(), $factory->reveal());
|
|
||||||
static::assertSame(10, $subject->countAll());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @test
|
|
||||||
*/
|
|
||||||
public function returnsAllModells(): void
|
|
||||||
{
|
|
||||||
$statement = $this->prophesize(Statement::class);
|
|
||||||
$statement->fetch()->willReturn(
|
|
||||||
[
|
|
||||||
'pid' => '10',
|
|
||||||
'crdate' => '1595948372',
|
|
||||||
'type' => '0',
|
|
||||||
'sys_language_uid' => '0',
|
|
||||||
'url' => 'https://example.com/path/file.html',
|
|
||||||
'user_agent' => 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36',
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'pid' => '9',
|
|
||||||
'crdate' => '1595948376',
|
|
||||||
'type' => '0',
|
|
||||||
'sys_language_uid' => '0',
|
|
||||||
'url' => 'https://example.com/path/file.html',
|
|
||||||
'user_agent' => 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36',
|
|
||||||
],
|
|
||||||
false
|
|
||||||
);
|
|
||||||
|
|
||||||
$queryBuilder = $this->prophesize(QueryBuilder::class);
|
|
||||||
$queryBuilder->select('*')->willReturn($queryBuilder->reveal());
|
|
||||||
$queryBuilder->from('tx_tracking_pageview')->willReturn($queryBuilder->reveal());
|
|
||||||
$queryBuilder->execute()->willReturn($statement->reveal());
|
|
||||||
|
|
||||||
$connection = $this->prophesize(Connection::class);
|
|
||||||
$connection->createQueryBuilder()->willReturn($queryBuilder->reveal());
|
|
||||||
|
|
||||||
$model1 = $this->prophesize(Model::class);
|
|
||||||
$model1->getPageUid()->willReturn(10);
|
|
||||||
$model2 = $this->prophesize(Model::class);
|
|
||||||
$model2->getPageUid()->willReturn(9);
|
|
||||||
|
|
||||||
$factory = $this->prophesize(Factory::class);
|
|
||||||
$factory->fromDbRow([
|
|
||||||
'pid' => '10',
|
|
||||||
'crdate' => '1595948372',
|
|
||||||
'type' => '0',
|
|
||||||
'sys_language_uid' => '0',
|
|
||||||
'url' => 'https://example.com/path/file.html',
|
|
||||||
'user_agent' => 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36',
|
|
||||||
])->willReturn($model1->reveal());
|
|
||||||
$factory->fromDbRow([
|
|
||||||
'pid' => '9',
|
|
||||||
'crdate' => '1595948376',
|
|
||||||
'type' => '0',
|
|
||||||
'sys_language_uid' => '0',
|
|
||||||
'url' => 'https://example.com/path/file.html',
|
|
||||||
'user_agent' => 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36',
|
|
||||||
])->willReturn($model2->reveal());
|
|
||||||
|
|
||||||
$subject = new Pageview($connection->reveal(), $factory->reveal());
|
|
||||||
static::assertCount(2, $subject->findAll());
|
|
||||||
|
|
||||||
$pageUid = 10;
|
|
||||||
foreach ($subject->findAll() as $model) {
|
|
||||||
static::assertSame($pageUid, $model->getPageUid());
|
|
||||||
--$pageUid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,80 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Repository;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
use DanielSiepmann\Tracking\Domain\Model\Recordview as Model;
|
|
||||||
use DanielSiepmann\Tracking\Domain\Repository\Recordview;
|
|
||||||
use Prophecy\PhpUnit\ProphecyTrait;
|
|
||||||
use TYPO3\CMS\Core\Database\Connection;
|
|
||||||
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
|
|
||||||
use TYPO3\TestingFramework\Core\Unit\UnitTestCase as TestCase;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @covers DanielSiepmann\Tracking\Domain\Repository\Recordview
|
|
||||||
*/
|
|
||||||
class RecordviewTest extends TestCase
|
|
||||||
{
|
|
||||||
use ProphecyTrait;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @test
|
|
||||||
*/
|
|
||||||
public function modelCanBeAdded(): void
|
|
||||||
{
|
|
||||||
$connection = $this->prophesize(Connection::class);
|
|
||||||
|
|
||||||
$dateTime = $this->prophesize(\DateTimeImmutable::class);
|
|
||||||
$dateTime->format('U')->willReturn(1582660189);
|
|
||||||
|
|
||||||
$language = $this->prophesize(SiteLanguage::class);
|
|
||||||
$language->getLanguageId()->willReturn(2);
|
|
||||||
|
|
||||||
$model = $this->prophesize(Model::class);
|
|
||||||
$model->getPageUid()->willReturn(10);
|
|
||||||
$model->getCrdate()->willReturn($dateTime->reveal());
|
|
||||||
$model->getLanguage()->willReturn($language->reveal());
|
|
||||||
$model->getUrl()->willReturn('https://example.com/path.html');
|
|
||||||
$model->getUserAgent()->willReturn('Mozilla/5.0 (Windows NT 10.0) Gecko/20100101 Firefox/74.0');
|
|
||||||
$model->getOperatingSystem()->willReturn('Linux');
|
|
||||||
$model->getRecordUid()->willReturn(10);
|
|
||||||
$model->getTableName()->willReturn('sys_category');
|
|
||||||
|
|
||||||
$connection->insert(
|
|
||||||
'tx_tracking_recordview',
|
|
||||||
[
|
|
||||||
'pid' => 10,
|
|
||||||
'crdate' => 1582660189,
|
|
||||||
'tstamp' => 1582660189,
|
|
||||||
'sys_language_uid' => 2,
|
|
||||||
'url' => 'https://example.com/path.html',
|
|
||||||
'user_agent' => 'Mozilla/5.0 (Windows NT 10.0) Gecko/20100101 Firefox/74.0',
|
|
||||||
'operating_system' => 'Linux',
|
|
||||||
'record_uid' => 10,
|
|
||||||
'record_table_name' => 'sys_category',
|
|
||||||
'record' => 'sys_category_10',
|
|
||||||
]
|
|
||||||
)->willReturn(1)->shouldBeCalledTimes(1);
|
|
||||||
|
|
||||||
$subject = new Recordview($connection->reveal());
|
|
||||||
$subject->add($model->reveal());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -36,7 +36,8 @@
|
||||||
"symfony/expression-language": "^5.2",
|
"symfony/expression-language": "^5.2",
|
||||||
"typo3/cms-backend": "^10.4 || ^11.5",
|
"typo3/cms-backend": "^10.4 || ^11.5",
|
||||||
"typo3/cms-core": "^10.4 || ^11.5",
|
"typo3/cms-core": "^10.4 || ^11.5",
|
||||||
"typo3/cms-dashboard": "^10.4 || ^11.5"
|
"typo3/cms-dashboard": "^10.4 || ^11.5",
|
||||||
|
"matomo/device-detector": "^6.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^9.0",
|
"phpunit/phpunit": "^9.0",
|
||||||
|
|
|
@ -1,21 +1,34 @@
|
||||||
CREATE TABLE tx_tracking_pageview (
|
CREATE TABLE tx_tracking_pageview (
|
||||||
url text,
|
url text,
|
||||||
user_agent text,
|
user_agent text,
|
||||||
operating_system varchar(255) DEFAULT '' NOT NULL,
|
|
||||||
type int(11) unsigned DEFAULT '0' NOT NULL,
|
type int(11) unsigned DEFAULT '0' NOT NULL,
|
||||||
|
compatible_version varchar(11) DEFAULT 'v1.1.4' NOT NULL,
|
||||||
|
|
||||||
KEY page_views_per_page (pid,uid,crdate),
|
KEY page_views_per_page (pid,uid,crdate),
|
||||||
KEY language (l10n_parent,sys_language_uid),
|
KEY language (l10n_parent,sys_language_uid),
|
||||||
|
KEY compatible_version (compatible_version),
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE tx_tracking_recordview (
|
CREATE TABLE tx_tracking_recordview (
|
||||||
url text,
|
url text,
|
||||||
user_agent text,
|
user_agent text,
|
||||||
operating_system varchar(255) DEFAULT '' NOT NULL,
|
|
||||||
record varchar(255) DEFAULT '' NOT NULL,
|
record varchar(255) DEFAULT '' NOT NULL,
|
||||||
record_uid int(11) unsigned DEFAULT '0' NOT NULL,
|
record_uid int(11) unsigned DEFAULT '0' NOT NULL,
|
||||||
record_table_name varchar(255) DEFAULT '' NOT NULL,
|
record_table_name varchar(255) DEFAULT '' NOT NULL,
|
||||||
|
compatible_version varchar(11) DEFAULT 'v1.1.4' NOT NULL,
|
||||||
|
|
||||||
KEY record_views_per_page (pid,uid,crdate),
|
KEY record_views_per_page (pid,uid,crdate),
|
||||||
KEY language (l10n_parent,sys_language_uid),
|
KEY language (l10n_parent,sys_language_uid),
|
||||||
|
KEY compatible_version (compatible_version),
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE tx_tracking_tag (
|
||||||
|
record_uid int(11) unsigned DEFAULT '0' NOT NULL,
|
||||||
|
record_table_name varchar(255) DEFAULT '' NOT NULL,
|
||||||
|
name varchar(255) DEFAULT '' NOT NULL,
|
||||||
|
value longtext DEFAULT '' NOT NULL,
|
||||||
|
compatible_version varchar(11) DEFAULT 'v2.0.0' NOT NULL,
|
||||||
|
|
||||||
|
KEY combined_identifier (record_uid,record_table_name,name,value),
|
||||||
|
KEY compatible_version (compatible_version),
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue