Initial commit: CloudOps infrastructure platform

This commit is contained in:
root
2026-04-09 19:58:57 +02:00
commit 1166a52f26
7762 changed files with 839452 additions and 0 deletions

View File

@@ -0,0 +1,173 @@
<?php
namespace Mautic\StatsBundle\Aggregate;
use Mautic\StatsBundle\Aggregate\Collection\DAO\StatDAO;
use Mautic\StatsBundle\Aggregate\Collection\DAO\StatsDAO;
use Mautic\StatsBundle\Aggregate\Helper\CalculatorHelper;
class Calculator
{
public function __construct(
private StatsDAO $statsDAO,
private ?\DateTimeInterface $fromDateTime = null,
private ?\DateTimeInterface $toDateTime = null,
) {
}
/**
* @param string $labelFormat
*
* @throws \Exception
*/
public function getSumsByYear($labelFormat = 'Y'): StatDAO
{
$statDAO = new StatDAO();
$lastYear = $this->fromDateTime ? $this->fromDateTime->format('Y') : null;
foreach ($this->statsDAO->getYears() as $thisYear => $stats) {
CalculatorHelper::fillInMissingYears($statDAO, $lastYear, $thisYear, $labelFormat);
$statDAO->addStat(
CalculatorHelper::getYearLabel($thisYear, $labelFormat),
$stats->getSum()
);
$lastYear = $thisYear;
}
if ($this->toDateTime) {
CalculatorHelper::fillInMissingYears($statDAO, $lastYear, $this->toDateTime->format('Y'), $labelFormat);
}
return $statDAO;
}
/**
* @param string $labelFormat
*
* @throws \Exception
*/
public function getSumsByMonth($labelFormat = 'Y-m'): StatDAO
{
$statDAO = new StatDAO();
$lastMonth = $this->fromDateTime ? $this->fromDateTime->format('Y-m') : null;
foreach ($this->statsDAO->getMonths() as $thisMonth => $stats) {
CalculatorHelper::fillInMissingMonths($statDAO, $lastMonth, $thisMonth, $labelFormat);
$statDAO->addStat(
CalculatorHelper::getMonthLabel($thisMonth, $labelFormat),
$stats->getSum()
);
$lastMonth = $thisMonth;
}
if ($this->toDateTime) {
CalculatorHelper::fillInMissingMonths($statDAO, $lastMonth, $this->toDateTime->format('Y-m'), $labelFormat);
}
return $statDAO;
}
/**
* @param string $labelFormat
*
* @throws \Exception
*/
public function getSumsByDay($labelFormat = 'Y-m-d'): StatDAO
{
$statDAO = new StatDAO();
$yesterday = $this->fromDateTime ? $this->fromDateTime->format('Y-m-d') : null;
foreach ($this->statsDAO->getDays() as $today => $stats) {
CalculatorHelper::fillInMissingDays($statDAO, $yesterday, $today, $labelFormat);
$statDAO->addStat(
CalculatorHelper::getDayLabel($today, $labelFormat),
$stats->getSum()
);
$yesterday = $today;
}
if ($this->toDateTime) {
CalculatorHelper::fillInMissingDays($statDAO, $yesterday, $this->toDateTime->format('Y-m-d'), $labelFormat);
}
return $statDAO;
}
/**
* @param string $labelFormat
*
* @throws \Exception
*/
public function getSumsByWeek($labelFormat = 'Y-W'): StatDAO
{
$statDAO = new StatDAO();
$yesterday = $this->fromDateTime ? $this->fromDateTime->format('Y-W') : null;
foreach ($this->statsDAO->getWeeks() as $today => $stats) {
CalculatorHelper::fillInMissingWeeks($statDAO, $yesterday, $today, $labelFormat);
$statDAO->addStat(
$today,
$stats->getCount()
);
$yesterday = $today;
}
$yesterday = (new \DateTime(CalculatorHelper::getWeekDateString($yesterday)))->modify('+1 week')->format('Y-W');
if ($this->toDateTime) {
/** @var \DateTime $tomorrow */
$tomorrow = clone $this->toDateTime;
CalculatorHelper::fillInMissingWeeks($statDAO, $yesterday, $tomorrow->modify('+1 week')->format('Y-W'), $labelFormat);
}
return $statDAO;
}
/**
* @param string $labelFormat
*
* @throws \Exception
*/
public function getCountsByHour($labelFormat = 'Y-m-d H'): StatDAO
{
$statDAO = new StatDAO();
$lastHour = $this->fromDateTime ? $this->fromDateTime->format('Y-m-d H') : null;
foreach ($this->statsDAO->getHours() as $thisHour => $stats) {
CalculatorHelper::fillInMissingHours($statDAO, $lastHour, $thisHour, $labelFormat);
$statDAO->addStat(
CalculatorHelper::getHourLabel($thisHour, $labelFormat),
$stats->getCount()
);
$lastHour = $thisHour;
}
if ($this->toDateTime) {
CalculatorHelper::fillInMissingHours($statDAO, $lastHour, $this->toDateTime->format('Y-m-d H'), $labelFormat);
}
return $statDAO;
}
public function getSum(): StatDAO
{
$statDAO = new StatDAO();
$sum = 0;
foreach ($this->statsDAO->getYears() as $stats) {
$sum += $stats->getSum();
}
return $statDAO;
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace Mautic\StatsBundle\Aggregate\Collection\DAO;
class StatDAO
{
private array $stats = [];
/**
* @return $this
*/
public function addStat($key, $value)
{
if (!isset($this->stats[$key])) {
$this->stats[$key] = 0;
}
$this->stats[$key] += $value;
return $this;
}
/**
* @return mixed
*/
public function getStat($key)
{
if (!isset($this->stats[$key])) {
throw new \InvalidArgumentException($key.' does not exist');
}
return $this->stats[$key];
}
/**
* @return array
*/
public function getStats()
{
return $this->stats;
}
}

View File

@@ -0,0 +1,130 @@
<?php
namespace Mautic\StatsBundle\Aggregate\Collection\DAO;
use Mautic\StatsBundle\Aggregate\Collection\Stats\DayStat;
use Mautic\StatsBundle\Aggregate\Collection\Stats\HourStat;
use Mautic\StatsBundle\Aggregate\Collection\Stats\MonthStat;
use Mautic\StatsBundle\Aggregate\Collection\Stats\WeekStat;
use Mautic\StatsBundle\Aggregate\Collection\Stats\YearStat;
use Mautic\StatsBundle\Aggregate\Helper\CalculatorHelper;
class StatsDAO
{
/**
* @var YearStat[]
*/
private array $years = [];
/**
* @return YearStat
*/
public function getYear($year)
{
if (!isset($this->years[$year])) {
$this->years[$year] = new YearStat($year);
}
return $this->years[$year];
}
/**
* @return YearStat[]
*/
public function getYears()
{
ksort($this->years);
return $this->years;
}
/**
* @return MonthStat[]
*
* @throws \Exception
*/
public function getMonths(): array
{
$flattenedMonths = [];
foreach ($this->years as $yearStats) {
$months = $yearStats->getStats();
foreach ($months as $month => $monthStats) {
$flattenedMonths[$month] = $monthStats;
}
}
ksort($flattenedMonths);
return $flattenedMonths;
}
/**
* @return WeekStat[]
*
* @throws \Exception
*/
public function getWeeks(): array
{
$flattenedWeeks = [];
foreach ($this->getDays() as $day => $stats) {
$week = CalculatorHelper::getWeekFromDayString($day);
if (!isset($flattenedWeeks[$week])) {
$flattenedWeeks[$week] = new WeekStat();
$flattenedWeeks[$week]->setCount($stats->getSum());
} else {
$flattenedWeeks[$week]->addToCount($stats->getSum());
}
}
ksort($flattenedWeeks);
return $flattenedWeeks;
}
/**
* @return DayStat[]
*
* @throws \Exception
*/
public function getDays(): array
{
$flattenedDays = [];
$months = $this->getMonths();
foreach ($months as $monthStats) {
$stats = $monthStats->getStats();
foreach ($stats as $day => $dayStats) {
$flattenedDays[$day] = $dayStats;
}
}
ksort($flattenedDays);
return $flattenedDays;
}
/**
* @return HourStat[]
*
* @throws \Exception
*/
public function getHours(): array
{
$flattenedHours = [];
$days = $this->getDays();
foreach ($days as $dayStats) {
$stats = $dayStats->getStats();
foreach ($stats as $hour => $hourStat) {
$flattenedHours[$hour] = $hourStat;
}
}
ksort($flattenedHours);
return $flattenedHours;
}
}

View File

@@ -0,0 +1,106 @@
<?php
namespace Mautic\StatsBundle\Aggregate\Collection;
use Mautic\StatsBundle\Aggregate\Calculator;
use Mautic\StatsBundle\Aggregate\Collection\DAO\StatsDAO;
use Mautic\StatsBundle\Aggregate\Helper\CalculatorHelper;
class StatCollection
{
private StatsDAO $stats;
private ?Calculator $calculator = null;
public function __construct()
{
$this->stats = new StatsDAO();
}
/**
* @param int $year
* @param int $month
* @param int $day
* @param int $hour
* @param int $count
*
* @return $this
*
* @throws \Exception
*/
public function addStat($year, $month, $day, $hour, $count)
{
$this->stats
->getYear($year)
->getMonth($month)
->getDay($day)
->getHour($hour)
->setCount($count);
return $this;
}
/**
* @param int $count
*
* @return $this
*
* @throws \Exception
*/
public function addStatByDateTime(\DateTime $dateTime, $count)
{
$dateTime->setTimezone(new \DateTimeZone('UTC'));
$this->addStat(
$dateTime->format('Y'),
$dateTime->format('n'),
$dateTime->format('j'),
$dateTime->format('H'),
$count
);
return $this;
}
/**
* @return $this
*
* @throws \Exception
*/
public function addStatByDateTimeStringInUTC($dateTimeInUTC, $count)
{
if (preg_match('/([0-9]{4})\\s([0-9]{2})/', $dateTimeInUTC, $matches)) { // Is this a week?
$dateTimeString = CalculatorHelper::getWeekDateString($matches[1].'-'.$matches[2]);
$dateTime = new \DateTime($dateTimeString, new \DateTimeZone('UTC'));
} elseif (4 === strlen($dateTimeInUTC) and is_numeric($dateTimeInUTC)) {
$dateTime = (new \DateTime('now', new \DateTimeZone('UTC')))
->setDate($dateTimeInUTC, 1, 1)
->setTime(0, 0);
} else {
$dateTime = new \DateTime($dateTimeInUTC, new \DateTimeZone('UTC'));
}
$this->addStatByDateTime($dateTime, $count);
return $this;
}
/**
* @return StatsDAO
*/
public function getStats()
{
return $this->stats;
}
/**
* @return Calculator
*/
public function getCalculator(\DateTime $fromDateTime, \DateTime $toDateTime)
{
if (is_null($this->calculator)) {
$this->calculator = new Calculator($this->stats, $fromDateTime, $toDateTime);
}
return $this->calculator;
}
}

View File

@@ -0,0 +1,63 @@
<?php
namespace Mautic\StatsBundle\Aggregate\Collection\Stats;
class DayStat implements StatInterface
{
/**
* @var HourStat[]
*/
private array $stats = [];
/**
* @param string $day "2019-11-07" format
*/
public function __construct(
private $day,
) {
}
/**
* @param int $hour
*
* @return HourStat
*
* @throws \Exception
*/
public function getHour($hour)
{
$key = (new \DateTime("{$this->day} $hour:00:00"))->format('Y-m-d H');
if (!isset($this->stats[$key])) {
$this->stats[$key] = new HourStat($key);
}
return $this->stats[$key];
}
/**
* @return HourStat[]
*/
public function getStats()
{
return $this->stats;
}
/**
* @return int
*/
public function getSum()
{
$sum = 0;
foreach ($this->stats as $stat) {
$sum += $stat->getCount();
}
return $sum;
}
public function getCount(): int
{
return count($this->stats);
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace Mautic\StatsBundle\Aggregate\Collection\Stats;
class HourStat
{
private int $count = 0;
/**
* @param string $hour "2018-12-07 12" format
*/
public function __construct(
private $hour,
) {
}
/**
* @return string
*/
public function getHour()
{
return $this->hour;
}
/**
* @param int $count
*/
public function setCount($count): void
{
$this->count = (int) $count;
}
public function getCount(): int
{
return $this->count;
}
}

View File

@@ -0,0 +1,63 @@
<?php
namespace Mautic\StatsBundle\Aggregate\Collection\Stats;
class MonthStat implements StatInterface
{
/**
* @var DayStat[]
*/
private array $stats = [];
/**
* @param string $month "2019-01" format
*/
public function __construct(
private $month,
) {
}
/**
* @param int $day
*
* @return DayStat
*
* @throws \Exception
*/
public function getDay($day)
{
$key = (new \DateTime("{$this->month}-$day 00:00:00"))->format('Y-m-d');
if (!isset($this->stats[$key])) {
$this->stats[$key] = new DayStat($key);
}
return $this->stats[$key];
}
/**
* @return DayStat[]
*/
public function getStats()
{
return $this->stats;
}
/**
* @return int
*/
public function getSum()
{
$sum = 0;
foreach ($this->stats as $stat) {
$sum += $stat->getSum();
}
return $sum;
}
public function getCount(): int
{
return count($this->stats);
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace Mautic\StatsBundle\Aggregate\Collection\Stats;
interface StatInterface
{
/**
* @return array
*/
public function getStats();
/**
* @return int
*/
public function getSum();
/**
* @return int
*/
public function getCount();
}

View File

@@ -0,0 +1,29 @@
<?php
namespace Mautic\StatsBundle\Aggregate\Collection\Stats;
class WeekStat
{
private int $count = 0;
public function getCount(): int
{
return $this->count;
}
/**
* @param int $count
*/
public function setCount($count): void
{
$this->count = (int) $count;
}
/**
* @param int $count
*/
public function addToCount($count): void
{
$this->count += $count;
}
}

View File

@@ -0,0 +1,65 @@
<?php
namespace Mautic\StatsBundle\Aggregate\Collection\Stats;
class YearStat implements StatInterface
{
/**
* @var MonthStat[]
*/
private array $stats = [];
private int $year;
/**
* @param int $year
*/
public function __construct($year)
{
$this->year = (int) $year;
}
/**
* @param int $month
*
* @return MonthStat
*
* @throws \Exception
*/
public function getMonth($month)
{
$key = (new \DateTime("{$this->year}-$month-01 00:00:00"))->format('Y-m');
if (!isset($this->stats[$key])) {
$this->stats[$key] = new MonthStat($key);
}
return $this->stats[$key];
}
/**
* @return MonthStat[]
*/
public function getStats()
{
return $this->stats;
}
/**
* @return int
*/
public function getSum()
{
$sum = 0;
foreach ($this->stats as $stat) {
$sum += $stat->getSum();
}
return $sum;
}
public function getCount(): int
{
return count($this->stats);
}
}

View File

@@ -0,0 +1,35 @@
<?php
namespace Mautic\StatsBundle\Aggregate;
use Mautic\StatsBundle\Aggregate\Collection\StatCollection;
use Mautic\StatsBundle\Event\AggregateStatRequestEvent;
use Mautic\StatsBundle\Event\Options\FetchOptions;
use Mautic\StatsBundle\StatEvents;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
class Collector
{
public function __construct(
private EventDispatcherInterface $eventDispatcher,
) {
}
/**
* @param string $statName
*
* @return StatCollection
*/
public function fetchStats($statName, \DateTime $fromDateTime, \DateTime $toDateTime, ?FetchOptions $fetchOptions = null)
{
if (null === $fetchOptions) {
$fetchOptions = new FetchOptions();
}
$event = new AggregateStatRequestEvent($statName, $fromDateTime, $toDateTime, $fetchOptions);
$this->eventDispatcher->dispatch($event, StatEvents::AGGREGATE_STAT_REQUEST);
return $event->getStatCollection();
}
}

View File

@@ -0,0 +1,210 @@
<?php
namespace Mautic\StatsBundle\Aggregate\Helper;
use Mautic\StatsBundle\Aggregate\Collection\DAO\StatDAO;
class CalculatorHelper
{
/**
* @throws \Exception
*/
public static function getYearLabel($year, $labelFormat): string
{
return (new \DateTime(self::getYearDateString($year)))->format($labelFormat);
}
public static function getYearDateString($year): string
{
return "$year-01-01 00:00:00";
}
/**
* @param string $lastYear
* @param string $thisYear
* @param string $labelFormat
*
* @throws \Exception
*/
public static function fillInMissingYears(StatDAO $statDAO, $lastYear, $thisYear, $labelFormat): void
{
if (!$lastYear) {
return;
}
$lastYear = new \DateTime(self::getYearDateString($lastYear));
$thisYear = new \DateTime(self::getYearDateString($thisYear));
if (!isset($statDAO->getStats()[$lastYear->format($labelFormat)])) {
$statDAO->addStat($lastYear->format($labelFormat), 0);
}
while ($lastYear < $thisYear) {
$lastYear->modify('+1 year');
$statDAO->addStat($lastYear->format($labelFormat), 0);
}
}
/**
* @throws \Exception
*/
public static function getMonthLabel($month, $labelFormat): string
{
return (new \DateTime(self::getMonthDateString($month)))->format($labelFormat);
}
public static function getMonthDateString($month): string
{
return "$month-01 00:00:00";
}
/**
* @param string $lastMonth
* @param string $thisMonth
* @param string $labelFormat
*
* @throws \Exception
*/
public static function fillInMissingMonths(StatDAO $statDAO, $lastMonth, $thisMonth, $labelFormat): void
{
if (!$lastMonth) {
return;
}
$lastMonth = new \DateTime(self::getMonthDateString($lastMonth));
$thisMonth = new \DateTime(self::getMonthDateString($thisMonth));
if (!isset($statDAO->getStats()[$lastMonth->format($labelFormat)])) {
$statDAO->addStat($lastMonth->format($labelFormat), 0);
}
while ($lastMonth < $thisMonth) {
$lastMonth->modify('+1 month');
$statDAO->addStat($lastMonth->format($labelFormat), 0);
}
}
/**
* @throws \Exception
*/
public static function getDayLabel($day, $labelFormat): string
{
return (new \DateTime(self::getDayDateString($day)))->format($labelFormat);
}
public static function getDayDateString($day): string
{
return "$day 00:00:00";
}
/**
* @param string $date
*
* @throws \Exception
*/
public static function getWeekFromDayString($date): string
{
return (new \DateTime($date))->format('Y-W');
}
/**
* @param string $date
* @param string $labelFormat
*
* @throws \Exception
*/
public static function getWeekLabel($date, $labelFormat = 'Y-W'): string
{
return (new \DateTime(self::getWeekDateString($date)))->format($labelFormat);
}
public static function getWeekDateString($date): string
{
if (!preg_match('/^([0-9]{4})-([0-9]{2})$/', $date, $matches)) {
throw new \InvalidArgumentException('Invalid argument, Y-W format is required.');
}
$year = $matches[1];
$week = $matches[2];
return date('Y-m-d 00:00:00', strtotime($year.'W'.$week.'1'));
}
/**
* @param string $yesterday
* @param string $today
* @param string $labelFormat
*
* @throws \Exception
*/
public static function fillInMissingWeeks(StatDAO $statDAO, $yesterday, $today, $labelFormat): void
{
if (!$yesterday) {
return;
}
$yesterday = new \DateTime(self::getWeekDateString($yesterday));
$today = new \DateTime(self::getWeekDateString($today));
while ($yesterday < $today) {
$statDAO->addStat($yesterday->format($labelFormat), 0);
$yesterday->modify('+1 week');
}
}
/**
* @param string $yesterday
* @param string $today
* @param string $labelFormat
*
* @throws \Exception
*/
public static function fillInMissingDays(StatDAO $statDAO, $yesterday, $today, $labelFormat): void
{
if (!$yesterday) {
return;
}
$yesterday = (new \DateTime(self::getDayDateString($yesterday)))->modify('-1 day');
$today = new \DateTime(self::getDayDateString($today));
while ($yesterday < $today) {
$yesterday->modify('+1 day');
$statDAO->addStat($yesterday->format($labelFormat), 0);
}
}
/**
* @throws \Exception
*/
public static function getHourLabel($hour, $labelFormat): string
{
return (new \DateTime(self::getHourDateString($hour)))->format($labelFormat);
}
public static function getHourDateString($hour): string
{
return "$hour:00:00";
}
/**
* @param string $lastHour
* @param string $thisHour
* @param string $labelFormat
*
* @throws \Exception
*/
public static function fillInMissingHours(StatDAO $statDAO, $lastHour, $thisHour, $labelFormat): void
{
if (!$lastHour) {
return;
}
$lastHour = new \DateTime(self::getHourDateString($lastHour));
$thisHour = new \DateTime(self::getHourDateString($thisHour));
while ($lastHour < $thisHour) {
$lastHour->modify('+1 hour');
$statDAO->addStat($lastHour->format($labelFormat), 0);
}
}
}

View File

@@ -0,0 +1,14 @@
<?php
return [
'services' => [
'other' => [
'mautic.stats.aggregate.collector' => [
'class' => Mautic\StatsBundle\Aggregate\Collector::class,
'arguments' => [
'event_dispatcher',
],
],
],
],
];

View File

@@ -0,0 +1,22 @@
<?php
declare(strict_types=1);
use Mautic\CoreBundle\DependencyInjection\MauticCoreExtension;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return function (ContainerConfigurator $configurator): void {
$services = $configurator->services()
->defaults()
->autowire()
->autoconfigure()
->public();
$excludes = [
'Aggregate/Collection',
'Aggregate/Calculator.php',
];
$services->load('Mautic\\StatsBundle\\', '../')
->exclude('../{'.implode(',', array_merge(MauticCoreExtension::DEFAULT_EXCLUDES, $excludes)).'}');
};

View File

@@ -0,0 +1,22 @@
<?php
declare(strict_types=1);
namespace Mautic\StatsBundle\DependencyInjection;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\Extension;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
class MauticStatsExtension extends Extension
{
/**
* @param mixed[] $configs
*/
public function load(array $configs, ContainerBuilder $container): void
{
$loader = new PhpFileLoader($container, new FileLocator(__DIR__.'/../Config'));
$loader->load('services.php');
}
}

View File

@@ -0,0 +1,104 @@
<?php
namespace Mautic\StatsBundle\Event;
use Mautic\StatsBundle\Aggregate\Collection\StatCollection;
use Mautic\StatsBundle\Event\Options\FetchOptions;
use Symfony\Contracts\EventDispatcher\Event;
class AggregateStatRequestEvent extends Event
{
private StatCollection $statCollection;
/**
* @param string $statName
*/
public function __construct(
private $statName,
private \DateTimeInterface $fromDateTime,
private \DateTimeInterface $toDateTime,
private FetchOptions $options,
) {
$this->statCollection = new StatCollection();
}
/**
* Note if the listener handled collecting these stats.
*/
public function statsCollected(): void
{
$this->stopPropagation();
}
/**
* @return string
*/
public function getStatName()
{
return $this->statName;
}
/**
* @return \DateTimeInterface
*/
public function getFromDateTime()
{
return $this->fromDateTime;
}
/**
* @return \DateTimeInterface
*/
public function getToDateTime()
{
return $this->toDateTime;
}
/**
* @return FetchOptions
*/
public function getOptions()
{
return $this->options;
}
/**
* @return StatCollection
*/
public function getStatCollection()
{
return $this->statCollection;
}
/**
* @param string $context
*/
public function checkContext($context): bool
{
return $this->statName === $context;
}
public function checkContexts(array $contexts): bool
{
return in_array($this->statName, $contexts, true);
}
/**
* @param string $prefix
*/
public function checkContextPrefix($prefix): bool
{
return str_starts_with($this->statName, $prefix);
}
public function checkContextPrefixes(array $prefixes): bool
{
foreach ($prefixes as $string) {
if (str_starts_with($this->statName, $string)) {
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,56 @@
<?php
namespace Mautic\StatsBundle\Event\Options;
class FetchOptions
{
private array $options = [];
/**
* @var int|null
*/
private $itemId;
/**
* @param int $value
*
* @return $this
*/
public function setItemId($value)
{
$this->itemId = $value;
return $this;
}
/**
* @return int|null
*/
public function getItemId()
{
return $this->itemId;
}
/**
* @param string $key
* @param mixed $value
*
* @return $this
*/
public function setOption($key, $value)
{
$this->options[$key] = $value;
return $this;
}
/**
* @param string $key
*
* @return mixed
*/
public function getOption($key, $default = null)
{
return $this->options[$key] ?? $default;
}
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Mautic\StatsBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class MauticStatsBundle extends Bundle
{
}

View File

@@ -0,0 +1,15 @@
<?php
namespace Mautic\StatsBundle;
final class StatEvents
{
/**
* The mautic.aggregate_stat_request event is dispatched when an aggregate stat is requested.
*
* The event listener receives a \Mautic\StatsBundle\Event\AggregateStatRequestEvent instance.
*
* @var string
*/
public const AGGREGATE_STAT_REQUEST = 'mautic.aggregate_stat_request';
}

View File

@@ -0,0 +1,620 @@
<?php
namespace Mautic\StatsBundle\Tests\Aggregate\Collection;
use Mautic\StatsBundle\Aggregate\Calculator;
use Mautic\StatsBundle\Aggregate\Collection\DAO\StatsDAO;
use PHPUnit\Framework\TestCase;
class CalculatorTest extends TestCase
{
public function testSumByYearReturnsExpectedCount(): void
{
$expected = [
2018 => 600,
2019 => 300,
];
$this->assertEquals($expected, $this->getCalculator()->getSumsByYear()->getStats());
}
public function testSumByMonthReturnsExpectedCount(): void
{
$expected = [
1 => 0,
2 => 0,
3 => 0,
4 => 0,
5 => 0,
6 => 0,
7 => 0,
8 => 0,
9 => 0,
10 => 0,
11 => 200,
12 => 700,
];
$this->assertEquals($expected, $this->getCalculator()->getSumsByMonth('n')->getStats());
$expected = [
'2018-12' => 600,
'2019-01' => 0,
'2019-02' => 0,
'2019-03' => 0,
'2019-04' => 0,
'2019-05' => 0,
'2019-06' => 0,
'2019-07' => 0,
'2019-08' => 0,
'2019-09' => 0,
'2019-10' => 0,
'2019-11' => 200,
'2019-12' => 100,
];
$this->assertEquals($expected, $this->getCalculator()->getSumsByMonth('Y-m')->getStats());
}
public function testSumByDayReturnsExpectedCount(): void
{
$expected = [
7 => 500,
8 => 400,
9 => 0,
10 => 0,
11 => 0,
12 => 0,
13 => 0,
14 => 0,
15 => 0,
16 => 0,
17 => 0,
18 => 0,
19 => 0,
20 => 0,
21 => 0,
22 => 0,
23 => 0,
24 => 0,
25 => 0,
26 => 0,
27 => 0,
28 => 0,
29 => 0,
30 => 0,
31 => 0,
1 => 0,
2 => 0,
3 => 0,
4 => 0,
5 => 0,
6 => 0,
];
$this->assertEquals($expected, $this->getCalculator()->getSumsByDay('j')->getStats());
$expected = [
'2018-12-07' => 300,
'2018-12-08' => 300,
'2018-12-09' => 0,
'2018-12-10' => 0,
'2018-12-11' => 0,
'2018-12-12' => 0,
'2018-12-13' => 0,
'2018-12-14' => 0,
'2018-12-15' => 0,
'2018-12-16' => 0,
'2018-12-17' => 0,
'2018-12-18' => 0,
'2018-12-19' => 0,
'2018-12-20' => 0,
'2018-12-21' => 0,
'2018-12-22' => 0,
'2018-12-23' => 0,
'2018-12-24' => 0,
'2018-12-25' => 0,
'2018-12-26' => 0,
'2018-12-27' => 0,
'2018-12-28' => 0,
'2018-12-29' => 0,
'2018-12-30' => 0,
'2018-12-31' => 0,
'2019-01-01' => 0,
'2019-01-02' => 0,
'2019-01-03' => 0,
'2019-01-04' => 0,
'2019-01-05' => 0,
'2019-01-06' => 0,
'2019-01-07' => 0,
'2019-01-08' => 0,
'2019-01-09' => 0,
'2019-01-10' => 0,
'2019-01-11' => 0,
'2019-01-12' => 0,
'2019-01-13' => 0,
'2019-01-14' => 0,
'2019-01-15' => 0,
'2019-01-16' => 0,
'2019-01-17' => 0,
'2019-01-18' => 0,
'2019-01-19' => 0,
'2019-01-20' => 0,
'2019-01-21' => 0,
'2019-01-22' => 0,
'2019-01-23' => 0,
'2019-01-24' => 0,
'2019-01-25' => 0,
'2019-01-26' => 0,
'2019-01-27' => 0,
'2019-01-28' => 0,
'2019-01-29' => 0,
'2019-01-30' => 0,
'2019-01-31' => 0,
'2019-02-01' => 0,
'2019-02-02' => 0,
'2019-02-03' => 0,
'2019-02-04' => 0,
'2019-02-05' => 0,
'2019-02-06' => 0,
'2019-02-07' => 0,
'2019-02-08' => 0,
'2019-02-09' => 0,
'2019-02-10' => 0,
'2019-02-11' => 0,
'2019-02-12' => 0,
'2019-02-13' => 0,
'2019-02-14' => 0,
'2019-02-15' => 0,
'2019-02-16' => 0,
'2019-02-17' => 0,
'2019-02-18' => 0,
'2019-02-19' => 0,
'2019-02-20' => 0,
'2019-02-21' => 0,
'2019-02-22' => 0,
'2019-02-23' => 0,
'2019-02-24' => 0,
'2019-02-25' => 0,
'2019-02-26' => 0,
'2019-02-27' => 0,
'2019-02-28' => 0,
'2019-03-01' => 0,
'2019-03-02' => 0,
'2019-03-03' => 0,
'2019-03-04' => 0,
'2019-03-05' => 0,
'2019-03-06' => 0,
'2019-03-07' => 0,
'2019-03-08' => 0,
'2019-03-09' => 0,
'2019-03-10' => 0,
'2019-03-11' => 0,
'2019-03-12' => 0,
'2019-03-13' => 0,
'2019-03-14' => 0,
'2019-03-15' => 0,
'2019-03-16' => 0,
'2019-03-17' => 0,
'2019-03-18' => 0,
'2019-03-19' => 0,
'2019-03-20' => 0,
'2019-03-21' => 0,
'2019-03-22' => 0,
'2019-03-23' => 0,
'2019-03-24' => 0,
'2019-03-25' => 0,
'2019-03-26' => 0,
'2019-03-27' => 0,
'2019-03-28' => 0,
'2019-03-29' => 0,
'2019-03-30' => 0,
'2019-03-31' => 0,
'2019-04-01' => 0,
'2019-04-02' => 0,
'2019-04-03' => 0,
'2019-04-04' => 0,
'2019-04-05' => 0,
'2019-04-06' => 0,
'2019-04-07' => 0,
'2019-04-08' => 0,
'2019-04-09' => 0,
'2019-04-10' => 0,
'2019-04-11' => 0,
'2019-04-12' => 0,
'2019-04-13' => 0,
'2019-04-14' => 0,
'2019-04-15' => 0,
'2019-04-16' => 0,
'2019-04-17' => 0,
'2019-04-18' => 0,
'2019-04-19' => 0,
'2019-04-20' => 0,
'2019-04-21' => 0,
'2019-04-22' => 0,
'2019-04-23' => 0,
'2019-04-24' => 0,
'2019-04-25' => 0,
'2019-04-26' => 0,
'2019-04-27' => 0,
'2019-04-28' => 0,
'2019-04-29' => 0,
'2019-04-30' => 0,
'2019-05-01' => 0,
'2019-05-02' => 0,
'2019-05-03' => 0,
'2019-05-04' => 0,
'2019-05-05' => 0,
'2019-05-06' => 0,
'2019-05-07' => 0,
'2019-05-08' => 0,
'2019-05-09' => 0,
'2019-05-10' => 0,
'2019-05-11' => 0,
'2019-05-12' => 0,
'2019-05-13' => 0,
'2019-05-14' => 0,
'2019-05-15' => 0,
'2019-05-16' => 0,
'2019-05-17' => 0,
'2019-05-18' => 0,
'2019-05-19' => 0,
'2019-05-20' => 0,
'2019-05-21' => 0,
'2019-05-22' => 0,
'2019-05-23' => 0,
'2019-05-24' => 0,
'2019-05-25' => 0,
'2019-05-26' => 0,
'2019-05-27' => 0,
'2019-05-28' => 0,
'2019-05-29' => 0,
'2019-05-30' => 0,
'2019-05-31' => 0,
'2019-06-01' => 0,
'2019-06-02' => 0,
'2019-06-03' => 0,
'2019-06-04' => 0,
'2019-06-05' => 0,
'2019-06-06' => 0,
'2019-06-07' => 0,
'2019-06-08' => 0,
'2019-06-09' => 0,
'2019-06-10' => 0,
'2019-06-11' => 0,
'2019-06-12' => 0,
'2019-06-13' => 0,
'2019-06-14' => 0,
'2019-06-15' => 0,
'2019-06-16' => 0,
'2019-06-17' => 0,
'2019-06-18' => 0,
'2019-06-19' => 0,
'2019-06-20' => 0,
'2019-06-21' => 0,
'2019-06-22' => 0,
'2019-06-23' => 0,
'2019-06-24' => 0,
'2019-06-25' => 0,
'2019-06-26' => 0,
'2019-06-27' => 0,
'2019-06-28' => 0,
'2019-06-29' => 0,
'2019-06-30' => 0,
'2019-07-01' => 0,
'2019-07-02' => 0,
'2019-07-03' => 0,
'2019-07-04' => 0,
'2019-07-05' => 0,
'2019-07-06' => 0,
'2019-07-07' => 0,
'2019-07-08' => 0,
'2019-07-09' => 0,
'2019-07-10' => 0,
'2019-07-11' => 0,
'2019-07-12' => 0,
'2019-07-13' => 0,
'2019-07-14' => 0,
'2019-07-15' => 0,
'2019-07-16' => 0,
'2019-07-17' => 0,
'2019-07-18' => 0,
'2019-07-19' => 0,
'2019-07-20' => 0,
'2019-07-21' => 0,
'2019-07-22' => 0,
'2019-07-23' => 0,
'2019-07-24' => 0,
'2019-07-25' => 0,
'2019-07-26' => 0,
'2019-07-27' => 0,
'2019-07-28' => 0,
'2019-07-29' => 0,
'2019-07-30' => 0,
'2019-07-31' => 0,
'2019-08-01' => 0,
'2019-08-02' => 0,
'2019-08-03' => 0,
'2019-08-04' => 0,
'2019-08-05' => 0,
'2019-08-06' => 0,
'2019-08-07' => 0,
'2019-08-08' => 0,
'2019-08-09' => 0,
'2019-08-10' => 0,
'2019-08-11' => 0,
'2019-08-12' => 0,
'2019-08-13' => 0,
'2019-08-14' => 0,
'2019-08-15' => 0,
'2019-08-16' => 0,
'2019-08-17' => 0,
'2019-08-18' => 0,
'2019-08-19' => 0,
'2019-08-20' => 0,
'2019-08-21' => 0,
'2019-08-22' => 0,
'2019-08-23' => 0,
'2019-08-24' => 0,
'2019-08-25' => 0,
'2019-08-26' => 0,
'2019-08-27' => 0,
'2019-08-28' => 0,
'2019-08-29' => 0,
'2019-08-30' => 0,
'2019-08-31' => 0,
'2019-09-01' => 0,
'2019-09-02' => 0,
'2019-09-03' => 0,
'2019-09-04' => 0,
'2019-09-05' => 0,
'2019-09-06' => 0,
'2019-09-07' => 0,
'2019-09-08' => 0,
'2019-09-09' => 0,
'2019-09-10' => 0,
'2019-09-11' => 0,
'2019-09-12' => 0,
'2019-09-13' => 0,
'2019-09-14' => 0,
'2019-09-15' => 0,
'2019-09-16' => 0,
'2019-09-17' => 0,
'2019-09-18' => 0,
'2019-09-19' => 0,
'2019-09-20' => 0,
'2019-09-21' => 0,
'2019-09-22' => 0,
'2019-09-23' => 0,
'2019-09-24' => 0,
'2019-09-25' => 0,
'2019-09-26' => 0,
'2019-09-27' => 0,
'2019-09-28' => 0,
'2019-09-29' => 0,
'2019-09-30' => 0,
'2019-10-01' => 0,
'2019-10-02' => 0,
'2019-10-03' => 0,
'2019-10-04' => 0,
'2019-10-05' => 0,
'2019-10-06' => 0,
'2019-10-07' => 0,
'2019-10-08' => 0,
'2019-10-09' => 0,
'2019-10-10' => 0,
'2019-10-11' => 0,
'2019-10-12' => 0,
'2019-10-13' => 0,
'2019-10-14' => 0,
'2019-10-15' => 0,
'2019-10-16' => 0,
'2019-10-17' => 0,
'2019-10-18' => 0,
'2019-10-19' => 0,
'2019-10-20' => 0,
'2019-10-21' => 0,
'2019-10-22' => 0,
'2019-10-23' => 0,
'2019-10-24' => 0,
'2019-10-25' => 0,
'2019-10-26' => 0,
'2019-10-27' => 0,
'2019-10-28' => 0,
'2019-10-29' => 0,
'2019-10-30' => 0,
'2019-10-31' => 0,
'2019-11-01' => 0,
'2019-11-02' => 0,
'2019-11-03' => 0,
'2019-11-04' => 0,
'2019-11-05' => 0,
'2019-11-06' => 0,
'2019-11-07' => 100,
'2019-11-08' => 100,
'2019-11-09' => 0,
'2019-11-10' => 0,
'2019-11-11' => 0,
'2019-11-12' => 0,
'2019-11-13' => 0,
'2019-11-14' => 0,
'2019-11-15' => 0,
'2019-11-16' => 0,
'2019-11-17' => 0,
'2019-11-18' => 0,
'2019-11-19' => 0,
'2019-11-20' => 0,
'2019-11-21' => 0,
'2019-11-22' => 0,
'2019-11-23' => 0,
'2019-11-24' => 0,
'2019-11-25' => 0,
'2019-11-26' => 0,
'2019-11-27' => 0,
'2019-11-28' => 0,
'2019-11-29' => 0,
'2019-11-30' => 0,
'2019-12-01' => 0,
'2019-12-02' => 0,
'2019-12-03' => 0,
'2019-12-04' => 0,
'2019-12-05' => 0,
'2019-12-06' => 0,
'2019-12-07' => 100,
];
$this->assertEquals($expected, $this->getCalculator()->getSumsByDay('Y-m-d')->getStats());
}
public function testSumByWeekReturnsExpectedCount(): void
{
$expected = [
'2018-49' => 600,
'2018-50' => 0,
'2018-51' => 0,
'2018-52' => 0,
'2018-01' => 0,
'2019-02' => 0,
'2019-03' => 0,
'2019-04' => 0,
'2019-05' => 0,
'2019-06' => 0,
'2019-07' => 0,
'2019-08' => 0,
'2019-09' => 0,
'2019-10' => 0,
'2019-11' => 0,
'2019-12' => 0,
'2019-13' => 0,
'2019-14' => 0,
'2019-15' => 0,
'2019-16' => 0,
'2019-17' => 0,
'2019-18' => 0,
'2019-19' => 0,
'2019-20' => 0,
'2019-21' => 0,
'2019-22' => 0,
'2019-23' => 0,
'2019-24' => 0,
'2019-25' => 0,
'2019-26' => 0,
'2019-27' => 0,
'2019-28' => 0,
'2019-29' => 0,
'2019-30' => 0,
'2019-31' => 0,
'2019-32' => 0,
'2019-33' => 0,
'2019-34' => 0,
'2019-35' => 0,
'2019-36' => 0,
'2019-37' => 0,
'2019-38' => 0,
'2019-39' => 0,
'2019-40' => 0,
'2019-41' => 0,
'2019-42' => 0,
'2019-43' => 0,
'2019-44' => 0,
'2019-45' => 200,
'2019-46' => 0,
'2019-47' => 0,
'2019-48' => 0,
'2019-49' => 100,
];
$this->assertEquals($expected, $this->getCalculator()->getSumsByWeek('Y-W')->getStats());
}
public function testSumByHoursReturnsExpectedCount(): void
{
$stats = new StatsDAO();
$stats->getYear(2021)
->getMonth(12)
->getDay(7)
->getHour(1)
->setCount(100);
$stats->getYear(2021)
->getMonth(12)
->getDay(7)
->getHour(3)
->setCount(200);
$stats->getYear(2021)
->getMonth(12)
->getDay(7)
->getHour(12)
->setCount(50);
$expected = [
'2021-12-07 01' => 100,
'2021-12-07 02' => 0,
'2021-12-07 03' => 200,
'2021-12-07 04' => 0,
'2021-12-07 05' => 0,
'2021-12-07 06' => 0,
'2021-12-07 07' => 0,
'2021-12-07 08' => 0,
'2021-12-07 09' => 0,
'2021-12-07 10' => 0,
'2021-12-07 11' => 0,
'2021-12-07 12' => 50,
];
$dateFrom = new \DateTime('2021-12-07');
$dateTo = new \DateTime('2021-12-07');
$calculatorObj = new Calculator($stats, $dateFrom, $dateTo);
$this->assertEquals($expected, $calculatorObj->getCountsByHour()->getStats());
}
/**
* @throws \Exception
*/
private function getCalculator(): Calculator
{
$stats = new StatsDAO();
$stats->getYear(2018)
->getMonth(12)
->getDay(7)
->getHour(12)
->setCount(100);
$stats->getYear(2018)
->getMonth(12)
->getDay(7)
->getHour(13)
->setCount(200);
$stats->getYear(2018)
->getMonth(12)
->getDay(8)
->getHour(14)
->setCount(300);
$stats->getYear(2019)
->getMonth(11)
->getDay(7)
->getHour(12)
->setCount(100);
$stats->getYear(2019)
->getMonth(11)
->getDay(8)
->getHour(12)
->setCount(100);
$stats->getYear(2019)
->getMonth(12)
->getDay(7)
->getHour(12)
->setCount(100);
$dateFrom = new \DateTime('2018-12-07');
$dateTo = new \DateTime('2019-12-07');
return new Calculator($stats, $dateFrom, $dateTo);
}
}

View File

@@ -0,0 +1,46 @@
<?php
namespace Mautic\StatsBundle\Tests\Aggregate\Collection;
use Mautic\StatsBundle\Aggregate\Collector;
use Mautic\StatsBundle\Event\AggregateStatRequestEvent;
use Mautic\StatsBundle\StatEvents;
use PHPUnit\Framework\TestCase;
use Symfony\Component\EventDispatcher\EventDispatcher;
class CollectorTest extends TestCase
{
private EventDispatcher $eventDispatcher;
protected function setUp(): void
{
$this->eventDispatcher = new EventDispatcher();
}
public function testEventIsDispatched(): void
{
$this->eventDispatcher->addListener(
StatEvents::AGGREGATE_STAT_REQUEST,
function (AggregateStatRequestEvent $event): void {
$statCollection = $event->getStatCollection();
$statCollection->addStat(2018, 12, 7, 1, 100);
$statCollection->addStat(2018, 12, 7, 2, 110);
}
);
$statCollection = $this->getCollector()->fetchStats('event-name', new \DateTime(), new \DateTime());
$stats = $statCollection->getStats();
$year = $stats->getYear(2018);
$this->assertEquals(210, $year->getSum());
}
/**
* @return Collector
*/
private function getCollector()
{
return new Collector($this->eventDispatcher);
}
}

View File

@@ -0,0 +1,135 @@
<?php
namespace Mautic\StatsBundle\Tests\Aggregate\Collection\DAO;
use Mautic\StatsBundle\Aggregate\Collection\DAO\StatsDAO;
use Mautic\StatsBundle\Aggregate\Collection\Stats\DayStat;
use Mautic\StatsBundle\Aggregate\Collection\Stats\MonthStat;
use Mautic\StatsBundle\Aggregate\Collection\Stats\WeekStat;
use Mautic\StatsBundle\Aggregate\Collection\Stats\YearStat;
use PHPUnit\Framework\TestCase;
class StatsDAOTest extends TestCase
{
public function testGetYearsReturnsYears(): void
{
$expected = [
2018,
2019,
];
$stats = $this->getStats()->getYears();
$this->assertEquals($expected, array_keys($stats));
array_walk($stats, function ($stat): void {
$this->assertInstanceOf(YearStat::class, $stat);
});
}
public function testGetMonthsReturnsFlattenedMonths(): void
{
$expected = [
'2018-12',
'2019-11',
'2019-12',
];
$stats = $this->getStats()->getMonths();
$this->assertEquals($expected, array_keys($stats));
array_walk($stats, function ($stat): void {
$this->assertInstanceOf(MonthStat::class, $stat);
});
}
public function testGetWeekReturnsFlattenedMonths(): void
{
$expected = [
'2018-49',
'2019-45',
'2019-49',
];
$stats = $this->getStats()->getWeeks();
$this->assertEquals($expected, array_keys($stats));
array_walk($stats, function ($stat): void {
$this->assertInstanceOf(WeekStat::class, $stat);
});
}
public function testGetDaysReturnsFlattenedDays(): void
{
$expected = [
'2018-12-07',
'2019-11-07',
'2019-11-08',
'2019-12-07',
];
$stats = $this->getStats()->getDays();
$this->assertEquals($expected, array_keys($stats));
array_walk($stats, function ($stat): void {
$this->assertInstanceOf(DayStat::class, $stat);
});
}
public function testGetHoursReturnsFlattenedHours(): void
{
$expected = [
'2018-12-07 12',
'2018-12-07 13',
'2018-12-07 14',
'2019-11-07 12',
'2019-11-08 12',
'2019-12-07 12',
];
$stats = $this->getStats()->getHours();
$this->assertEquals($expected, array_keys($stats));
}
private function getStats(): StatsDAO
{
$stats = new StatsDAO();
$stats->getYear(2019)
->getMonth(11)
->getDay(8)
->getHour(12)
->setCount(100);
$stats->getYear(2018)
->getMonth(12)
->getDay(7)
->getHour(12)
->setCount(100);
$stats->getYear(2018)
->getMonth(12)
->getDay(7)
->getHour(14)
->setCount(300);
$stats->getYear(2018)
->getMonth(12)
->getDay(7)
->getHour(13)
->setCount(200);
$stats->getYear(2019)
->getMonth(12)
->getDay(7)
->getHour(12)
->setCount(100);
$stats->getYear(2019)
->getMonth(11)
->getDay(7)
->getHour(12)
->setCount(100);
return $stats;
}
}

View File

@@ -0,0 +1,65 @@
<?php
namespace Mautic\StatsBundle\Tests\Aggregate\Collection\Stats;
use Mautic\StatsBundle\Aggregate\Collection\Stats\DayStat;
use Mautic\StatsBundle\Aggregate\Collection\Stats\HourStat;
use PHPUnit\Framework\TestCase;
class DayStatTest extends TestCase
{
private $day = '2019-11-07';
private $hour = 11;
private DayStat $dayStat;
private $hourStat;
protected function setUp(): void
{
$this->dayStat = new DayStat($this->day);
$this->hourStat = $this->dayStat->getHour($this->hour);
}
public function testGetHour(): void
{
$this->assertInstanceOf(HourStat::class, $this->hourStat);
$this->assertSame("$this->day $this->hour", $this->hourStat->getHour());
$this->assertSame(0, $this->hourStat->getCount());
$this->hourStat = $this->dayStat->getHour($this->hour);
$this->assertSame($this->hourStat, $this->dayStat->getHour($this->hour));
$this->assertSame("$this->day $this->hour", $this->hourStat->getHour());
$this->assertSame(0, $this->hourStat->getCount());
}
public function testGetStats(): void
{
$result = $this->dayStat->getStats();
$this->assertSame(["$this->day $this->hour" => $this->hourStat], $result);
}
public function testGetSum(): void
{
$this->dayStat = new DayStat($this->day);
$this->dayStat->getHour($this->hour);
$this->assertSame(1, $this->dayStat->getCount());
$this->dayStat->getHour($this->hour);
$this->assertSame(1, $this->dayStat->getCount());
$this->dayStat->getHour($this->hour + 1);
$this->assertSame(2, $this->dayStat->getCount());
}
public function testGetCount(): void
{
$this->dayStat = new DayStat($this->day);
$this->dayStat->getHour($this->hour);
$this->assertSame(1, $this->dayStat->getCount());
$this->dayStat->getHour($this->hour);
$this->assertSame(1, $this->dayStat->getCount());
$this->dayStat->getHour($this->hour + 1);
$this->assertSame(2, $this->dayStat->getCount());
}
}

View File

@@ -0,0 +1,25 @@
<?php
namespace Mautic\StatsBundle\Tests\Aggregate\Collection\Stats;
use Mautic\StatsBundle\Aggregate\Collection\Stats\HourStat;
use PHPUnit\Framework\TestCase;
class HourStatTest extends TestCase
{
public function testAll(): void
{
$hour = '2018-12-07 12';
$hourStat = new HourStat('2018-12-07 12');
$this->assertSame($hour, $hourStat->getHour());
// Counts
$this->assertSame(0, $hourStat->getCount());
$count = 1;
$hourStat->setCount($count);
$this->assertSame($count, $hourStat->getCount());
$count = 2;
$hourStat->setCount($count);
$this->assertSame($count, $hourStat->getCount());
}
}

View File

@@ -0,0 +1,65 @@
<?php
namespace Mautic\StatsBundle\Tests\Aggregate\Collection\Stats;
use Mautic\StatsBundle\Aggregate\Collection\Stats\DayStat;
use Mautic\StatsBundle\Aggregate\Collection\Stats\MonthStat;
use PHPUnit\Framework\TestCase;
class MonthStatTest extends TestCase
{
private $month = '2019-12';
private $day = 11;
private MonthStat $monthStat;
private $dayStat;
protected function setUp(): void
{
$this->monthStat = new MonthStat($this->month);
$this->dayStat = $this->monthStat->getDay($this->day);
}
public function testGetDay(): void
{
$this->assertInstanceOf(DayStat::class, $this->dayStat);
$day = $this->monthStat->getDay($this->day);
$this->assertInstanceOf(DayStat::class, $day);
$this->assertSame([], $day->getStats());
$this->assertSame(1, $this->monthStat->getCount());
$day = $this->monthStat->getDay($this->day + 1);
$this->assertSame([], $day->getStats());
$this->assertSame(2, $this->monthStat->getCount());
}
public function testGetStats(): void
{
$result = $this->monthStat->getStats();
$this->assertSame(["$this->month-$this->day" => $this->dayStat], $result);
}
public function testGetSum(): void
{
$this->monthStat = new MonthStat($this->month);
$this->monthStat->getDay($this->day);
$this->assertSame(1, $this->monthStat->getCount());
$this->monthStat->getDay($this->day);
$this->assertSame(1, $this->monthStat->getCount());
$this->monthStat->getDay($this->day + 1);
$this->assertSame(2, $this->monthStat->getCount());
}
public function testGetCount(): void
{
$this->monthStat = new MonthStat($this->month);
$this->monthStat->getDay($this->day);
$this->assertSame(1, $this->monthStat->getCount());
$this->monthStat->getDay($this->day);
$this->assertSame(1, $this->monthStat->getCount());
$this->monthStat->getDay($this->day + 1);
$this->assertSame(2, $this->monthStat->getCount());
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace Mautic\StatsBundle\Tests\Aggregate\Collection\Stats;
use Mautic\StatsBundle\Aggregate\Collection\Stats\WeekStat;
use PHPUnit\Framework\TestCase;
class WeekStatTest extends TestCase
{
public function testAll(): void
{
$weekStat = new WeekStat();
$this->assertSame(0, $weekStat->getCount());
$count = 1;
$weekStat->setCount($count);
$this->assertSame($count, $weekStat->getCount());
$weekStat->addToCount($count);
$this->assertSame($count * 2, $weekStat->getCount());
}
}

View File

@@ -0,0 +1,65 @@
<?php
namespace Mautic\StatsBundle\Tests\Aggregate\Collection\Stats;
use Mautic\StatsBundle\Aggregate\Collection\Stats\MonthStat;
use Mautic\StatsBundle\Aggregate\Collection\Stats\YearStat;
use PHPUnit\Framework\TestCase;
class YearStatTest extends TestCase
{
private $year = '2019';
private $month = 11;
private YearStat $yearStat;
private $monthStat;
protected function setUp(): void
{
$this->yearStat = new YearStat($this->year);
$this->monthStat = $this->yearStat->getMonth($this->month);
}
public function testGetMonth(): void
{
$this->assertInstanceOf(MonthStat::class, $this->monthStat);
$month = $this->yearStat->getMonth($this->month);
$this->assertInstanceOf(MonthStat::class, $month);
$this->assertSame([], $month->getStats());
$this->assertSame(1, $this->yearStat->getCount());
$month = $this->yearStat->getMonth($this->month + 1);
$this->assertSame([], $month->getStats());
$this->assertSame(2, $this->yearStat->getCount());
}
public function testGetStats(): void
{
$result = $this->yearStat->getStats();
$this->assertSame(["$this->year-$this->month" => $this->monthStat], $result);
}
public function testGetSum(): void
{
$this->yearStat = new YearStat($this->year);
$this->yearStat->getMonth($this->month);
$this->assertSame(1, $this->yearStat->getCount());
$this->yearStat->getMonth($this->month);
$this->assertSame(1, $this->yearStat->getCount());
$this->yearStat->getMonth($this->month + 1);
$this->assertSame(2, $this->yearStat->getCount());
}
public function testGetCount(): void
{
$this->yearStat = new YearStat($this->year);
$this->yearStat->getMonth($this->month);
$this->assertSame(1, $this->yearStat->getCount());
$this->yearStat->getMonth($this->month);
$this->assertSame(1, $this->yearStat->getCount());
$this->yearStat->getMonth($this->month + 1);
$this->assertSame(2, $this->yearStat->getCount());
}
}