Release 2.0.35 (#4302)

This commit is contained in:
Kevin Papst
2023-09-23 18:15:22 +02:00
committed by GitHub
parent de419350b2
commit 7a5b12762a
122 changed files with 1555 additions and 2054 deletions

View File

@@ -9,10 +9,12 @@
namespace App\Widget\Type;
use App\Repository\TimesheetRepository;
abstract class AbstractActiveUsers extends AbstractSimpleStatisticChart
abstract class AbstractActiveUsers extends AbstractWidgetType
{
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge([
@@ -20,14 +22,6 @@ abstract class AbstractActiveUsers extends AbstractSimpleStatisticChart
], parent::getOptions($options));
}
public function getData(array $options = []): mixed
{
$this->setQueryWithUser(false);
$this->setQuery(TimesheetRepository::STATS_QUERY_USER);
return parent::getData($options);
}
public function getTitle(): string
{
return 'stats.' . lcfirst($this->getId());

View File

@@ -29,6 +29,10 @@ abstract class AbstractAmountPeriod extends AbstractWidget
return 'widget/widget-counter-money.html.twig';
}
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge([
@@ -36,19 +40,12 @@ abstract class AbstractAmountPeriod extends AbstractWidget
], parent::getOptions($options));
}
protected function getRevenue(?string $begin, ?string $end, array $options = [])
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, float>
*/
protected function getRevenue(?\DateTimeInterface $begin, ?\DateTimeInterface $end, array $options = []): array
{
$user = $this->getUser();
$timezone = new \DateTimeZone($user->getTimezone());
if ($begin !== null) {
$begin = new \DateTime($begin, $timezone);
}
if ($end !== null) {
$end = new \DateTime($end, $timezone);
}
$data = $this->repository->getRevenue($begin, $end, null);
$event = new RevenueStatisticEvent($begin, $end);

View File

@@ -9,10 +9,12 @@
namespace App\Widget\Type;
use App\Repository\TimesheetRepository;
abstract class AbstractCounterDuration extends AbstractSimpleStatisticChart
abstract class AbstractCounterDuration extends AbstractWidgetType
{
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge([
@@ -20,13 +22,6 @@ abstract class AbstractCounterDuration extends AbstractSimpleStatisticChart
], parent::getOptions($options));
}
public function getData(array $options = []): mixed
{
$this->setQuery(TimesheetRepository::STATS_QUERY_DURATION);
return parent::getData($options);
}
public function getTitle(): string
{
return 'stats.' . lcfirst($this->getId());

View File

@@ -10,34 +10,39 @@
namespace App\Widget\Type;
use App\Configuration\SystemConfiguration;
use App\Repository\TimesheetRepository;
use App\Timesheet\DateTimeFactory;
abstract class AbstractCounterYear extends AbstractSimpleStatisticChart
abstract class AbstractCounterYear extends AbstractWidgetType
{
private bool $isFinancialYear = false;
public function __construct(TimesheetRepository $repository, private SystemConfiguration $systemConfiguration)
public function __construct(private SystemConfiguration $systemConfiguration)
{
parent::__construct($repository);
}
/**
* @param array<string, string|bool|int|null> $options
*/
public function getData(array $options = []): mixed
{
$this->setBegin('01 january this year 00:00:00');
$this->setEnd('31 december this year 23:59:59');
$begin = $this->createDate('01 january this year 00:00:00');
$end = $this->createDate('31 december this year 23:59:59');
if (null !== ($financialYear = $this->systemConfiguration->getFinancialYearStart())) {
$factory = new DateTimeFactory($this->getTimezone());
$begin = $factory->createStartOfFinancialYear($financialYear);
$this->setBegin($begin);
$this->setEnd($factory->createEndOfFinancialYear($begin));
$end = $factory->createEndOfFinancialYear($begin);
$this->isFinancialYear = true;
}
return parent::getData($options);
return $this->getYearData($begin, $end, $options);
}
/**
* @param array<string, string|bool|int|null> $options
*/
abstract protected function getYearData(\DateTimeInterface $begin, \DateTimeInterface $end, array $options = []): mixed;
abstract protected function getFinancialYearTitle(): string;
public function getTitle(): string

View File

@@ -1,139 +0,0 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Widget\Type;
use App\Repository\TimesheetRepository;
use App\Widget\WidgetException;
use App\Widget\WidgetInterface;
abstract class AbstractSimpleStatisticChart extends AbstractWidgetType
{
/**
* @var TimesheetRepository::STATS_QUERY_*
*/
private string $query;
/**
* @var string|\DateTime|null
*/
private $begin;
/**
* @var string|\DateTime|null
*/
private $end;
private bool $queryWithUser = false;
public function __construct(private TimesheetRepository $repository)
{
}
public function getWidth(): int
{
return WidgetInterface::WIDTH_SMALL;
}
public function getHeight(): int
{
return WidgetInterface::HEIGHT_SMALL;
}
/**
* @param TimesheetRepository::STATS_QUERY_* $query
* @return void
*/
public function setQuery(string $query): void
{
$this->query = $query;
}
public function setBegin(null|string|\DateTime $begin): self
{
$this->begin = $begin;
return $this;
}
public function getBegin(): ?\DateTime
{
if ($this->begin === null) {
return null;
}
if ($this->begin instanceof \DateTime) {
return $this->begin;
}
return new \DateTime($this->begin, $this->getTimezone());
}
public function setEnd(null|string|\DateTime $end): self
{
$this->end = $end;
return $this;
}
public function getEnd(): ?\DateTime
{
if ($this->end === null) {
return null;
}
if ($this->end instanceof \DateTime) {
return $this->end;
}
return new \DateTime($this->end, $this->getTimezone());
}
public function setQueryWithUser(bool $queryWithUser): self
{
$this->queryWithUser = $queryWithUser;
return $this;
}
public function getTimezone(): \DateTimeZone
{
$timezone = date_default_timezone_get();
if (null !== $this->getUser()) {
$timezone = $this->getUser()->getTimezone();
}
return new \DateTimeZone($timezone);
}
/**
* @param array $options
* @return mixed|null
* @throws WidgetException
*/
public function getData(array $options = []): mixed
{
try {
$user = null;
if (true === $this->queryWithUser) {
$user = $this->getUser();
}
return $this->repository->getStatistic($this->query, $this->getBegin(), $this->getEnd(), $user);
} catch (\Exception $ex) {
throw new WidgetException(
'Failed loading widget data: ' . $ex->getMessage()
);
}
}
public function getTemplateName(): string
{
$name = (new \ReflectionClass($this))->getShortName();
return sprintf('widget/widget-%s.html.twig', strtolower($name));
}
}

View File

@@ -34,6 +34,10 @@ abstract class AbstractUserRevenuePeriod extends AbstractWidget
return ['view_rate_own_timesheet'];
}
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge([
@@ -41,18 +45,13 @@ abstract class AbstractUserRevenuePeriod extends AbstractWidget
], parent::getOptions($options));
}
protected function getRevenue(?string $begin, ?string $end, array $options = [])
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, float>
*/
protected function getRevenue(?\DateTimeInterface $begin, ?\DateTimeInterface $end, array $options = []): array
{
$user = $this->getUser();
$timezone = new \DateTimeZone($user->getTimezone());
if ($begin !== null) {
$begin = new \DateTime($begin, $timezone);
}
if ($end !== null) {
$end = new \DateTime($end, $timezone);
}
$data = $this->repository->getRevenue($begin, $end, $user);

View File

@@ -67,6 +67,10 @@ abstract class AbstractWidget implements WidgetInterface
$this->options[$name] = $value;
}
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge($this->options, $options);
@@ -76,4 +80,56 @@ abstract class AbstractWidget implements WidgetInterface
{
return false;
}
protected function createDate(string $date): \DateTime
{
return new \DateTime($date, $this->getTimezone());
}
protected function createMonthStartDate(): \DateTime
{
return $this->createDate('first day of this month 00:00:00');
}
protected function createMonthEndDate(): \DateTime
{
return $this->createDate('last day of this month 23:59:59');
}
protected function createWeekStartDate(): \DateTime
{
return $this->createDate('monday this week 00:00:00');
}
protected function createWeekEndDate(): \DateTime
{
return $this->createDate('sunday this week 23:59:59');
}
protected function createTodayStartDate(): \DateTime
{
return $this->createDate('00:00:00');
}
protected function createTodayEndDate(): \DateTime
{
return $this->createDate('23:59:59');
}
public function getTimezone(): \DateTimeZone
{
$timezone = date_default_timezone_get();
if (null !== $this->user) {
$timezone = $this->user->getTimezone();
}
return new \DateTimeZone($timezone);
}
public function getTemplateName(): string
{
$name = (new \ReflectionClass($this))->getShortName();
return sprintf('widget/widget-%s.html.twig', strtolower($name));
}
}

View File

@@ -9,48 +9,18 @@
namespace App\Widget\Type;
use App\Widget\WidgetInterface;
abstract class AbstractWidgetType extends AbstractWidget
{
private ?string $id = null;
private string $title = '';
private int $height = WidgetInterface::HEIGHT_SMALL;
private int $width = WidgetInterface::WIDTH_SMALL;
/**
* @var array<string>
*/
private array $permissions = [];
public function getHeight(): int
{
return $this->height;
}
public function setHeight(int $height): AbstractWidgetType
{
$this->height = $height;
return $this;
}
public function getWidth(): int
{
return $this->width;
}
public function setWidth(int $width): AbstractWidgetType
{
$this->width = $width;
return $this;
}
public function setId(string $id): self
public function setId(string $id): void
{
$this->id = $id;
return $this;
}
public function getId(): string
@@ -62,11 +32,9 @@ abstract class AbstractWidgetType extends AbstractWidget
return (new \ReflectionClass($this))->getShortName();
}
public function setTitle(string $title): self
public function setTitle(string $title): void
{
$this->title = $title;
return $this;
}
public function getTitle(): string
@@ -74,13 +42,11 @@ abstract class AbstractWidgetType extends AbstractWidget
return $this->title;
}
public function setOptions(array $options): self
public function setOptions(array $options): void
{
foreach ($options as $key => $value) {
$this->setOption($key, $value);
}
return $this;
}
public function getPermissions(): array
@@ -88,10 +54,8 @@ abstract class AbstractWidgetType extends AbstractWidget
return $this->permissions;
}
public function setPermissions(array $permissions): AbstractWidgetType
public function setPermissions(array $permissions): void
{
$this->permissions = $permissions;
return $this;
}
}

View File

@@ -10,10 +10,19 @@
namespace App\Widget\Type;
use App\Repository\TimesheetRepository;
use App\Widget\WidgetException;
use App\Widget\WidgetInterface;
final class ActiveTimesheets extends AbstractSimpleStatisticChart
final class ActiveTimesheets extends AbstractWidgetType
{
public function __construct(private TimesheetRepository $repository)
{
}
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge(['color' => WidgetInterface::COLOR_TOTAL, 'icon' => 'duration'], parent::getOptions($options));
@@ -34,12 +43,18 @@ final class ActiveTimesheets extends AbstractSimpleStatisticChart
return 'stats.activeRecordings';
}
/**
* @param array<string, string|bool|int|null> $options
*/
public function getData(array $options = []): mixed
{
$this->setQueryWithUser(false);
$this->setQuery(TimesheetRepository::STATS_QUERY_ACTIVE);
return parent::getData($options);
try {
return $this->repository->countActiveEntries();
} catch (\Exception $ex) {
throw new WidgetException(
'Failed loading widget data: ' . $ex->getMessage()
);
}
}
public function getTemplateName(): string

View File

@@ -9,10 +9,20 @@
namespace App\Widget\Type;
use App\Repository\TimesheetRepository;
use App\Widget\WidgetException;
use App\Widget\WidgetInterface;
final class ActiveUsersMonth extends AbstractActiveUsers
{
public function __construct(private TimesheetRepository $repository)
{
}
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge(['color' => WidgetInterface::COLOR_MONTH], parent::getOptions($options));
@@ -23,11 +33,17 @@ final class ActiveUsersMonth extends AbstractActiveUsers
return 'activeUsersMonth';
}
/**
* @param array<string, string|bool|int|null> $options
*/
public function getData(array $options = []): mixed
{
$this->setBegin('first day of this month 00:00:00');
$this->setEnd('last day of this month 23:59:59');
return parent::getData($options);
try {
return $this->repository->countActiveUsers($this->createMonthStartDate(), $this->createMonthEndDate(), null);
} catch (\Exception $ex) {
throw new WidgetException(
'Failed loading widget data: ' . $ex->getMessage()
);
}
}
}

View File

@@ -9,10 +9,20 @@
namespace App\Widget\Type;
use App\Repository\TimesheetRepository;
use App\Widget\WidgetException;
use App\Widget\WidgetInterface;
final class ActiveUsersToday extends AbstractActiveUsers
{
public function __construct(private TimesheetRepository $repository)
{
}
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge(['color' => WidgetInterface::COLOR_TODAY], parent::getOptions($options));
@@ -23,11 +33,17 @@ final class ActiveUsersToday extends AbstractActiveUsers
return 'activeUsersToday';
}
/**
* @param array<string, string|bool|int|null> $options
*/
public function getData(array $options = []): mixed
{
$this->setBegin('00:00:00');
$this->setEnd('23:59:59');
return parent::getData($options);
try {
return $this->repository->countActiveUsers($this->createTodayStartDate(), $this->createTodayEndDate(), null);
} catch (\Exception $ex) {
throw new WidgetException(
'Failed loading widget data: ' . $ex->getMessage()
);
}
}
}

View File

@@ -9,10 +9,20 @@
namespace App\Widget\Type;
use App\Repository\TimesheetRepository;
use App\Widget\WidgetException;
use App\Widget\WidgetInterface;
final class ActiveUsersTotal extends AbstractActiveUsers
{
public function __construct(private TimesheetRepository $repository)
{
}
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge(['color' => WidgetInterface::COLOR_TOTAL], parent::getOptions($options));
@@ -23,8 +33,17 @@ final class ActiveUsersTotal extends AbstractActiveUsers
return 'activeUsersTotal';
}
/**
* @param array<string, string|bool|int|null> $options
*/
public function getData(array $options = []): mixed
{
return parent::getData($options);
try {
return $this->repository->countActiveUsers(null, null, null);
} catch (\Exception $ex) {
throw new WidgetException(
'Failed loading widget data: ' . $ex->getMessage()
);
}
}
}

View File

@@ -9,10 +9,20 @@
namespace App\Widget\Type;
use App\Repository\TimesheetRepository;
use App\Widget\WidgetException;
use App\Widget\WidgetInterface;
final class ActiveUsersWeek extends AbstractActiveUsers
{
public function __construct(private TimesheetRepository $repository)
{
}
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge(['color' => WidgetInterface::COLOR_WEEK], parent::getOptions($options));
@@ -23,11 +33,17 @@ final class ActiveUsersWeek extends AbstractActiveUsers
return 'activeUsersWeek';
}
/**
* @param array<string, string|bool|int|null> $options
*/
public function getData(array $options = []): mixed
{
$this->setBegin('monday this week 00:00:00');
$this->setEnd('sunday this week 23:59:59');
return parent::getData($options);
try {
return $this->repository->countActiveUsers($this->createWeekStartDate(), $this->createWeekEndDate(), null);
} catch (\Exception $ex) {
throw new WidgetException(
'Failed loading widget data: ' . $ex->getMessage()
);
}
}
}

View File

@@ -9,11 +9,22 @@
namespace App\Widget\Type;
use App\Configuration\SystemConfiguration;
use App\Repository\TimesheetRepository;
use App\Widget\WidgetException;
use App\Widget\WidgetInterface;
final class ActiveUsersYear extends AbstractCounterYear
{
public function __construct(private TimesheetRepository $repository, SystemConfiguration $systemConfiguration)
{
parent::__construct($systemConfiguration);
}
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge([
@@ -22,12 +33,18 @@ final class ActiveUsersYear extends AbstractCounterYear
], parent::getOptions($options));
}
public function getData(array $options = []): mixed
/**
* @param array<string, string|bool|int|null> $options
*/
protected function getYearData(\DateTimeInterface $begin, \DateTimeInterface $end, array $options = []): mixed
{
$this->setQuery(TimesheetRepository::STATS_QUERY_USER);
$this->setQueryWithUser(false);
return parent::getData($options);
try {
return $this->repository->countActiveUsers($begin, $end, null);
} catch (\Exception $ex) {
throw new WidgetException(
'Failed loading widget data: ' . $ex->getMessage()
);
}
}
protected function getFinancialYearTitle(): string

View File

@@ -13,6 +13,10 @@ use App\Widget\WidgetInterface;
final class AmountMonth extends AbstractAmountPeriod
{
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge(['color' => WidgetInterface::COLOR_MONTH], parent::getOptions($options));
@@ -23,9 +27,12 @@ final class AmountMonth extends AbstractAmountPeriod
return 'AmountMonth';
}
/**
* @param array<string, string|bool|int|null> $options
*/
public function getData(array $options = []): mixed
{
return $this->getRevenue('first day of this month 00:00:00', 'last day of this month 23:59:59', $options);
return $this->getRevenue($this->createMonthStartDate(), $this->createMonthEndDate(), $options);
}
public function getPermissions(): array

View File

@@ -13,6 +13,10 @@ use App\Widget\WidgetInterface;
final class AmountToday extends AbstractAmountPeriod
{
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge(['color' => WidgetInterface::COLOR_TODAY], parent::getOptions($options));
@@ -23,9 +27,12 @@ final class AmountToday extends AbstractAmountPeriod
return 'AmountToday';
}
/**
* @param array<string, string|bool|int|null> $options
*/
public function getData(array $options = []): mixed
{
return $this->getRevenue('00:00:00', '23:59:59', $options);
return $this->getRevenue($this->createTodayStartDate(), $this->createTodayEndDate(), $options);
}
public function getPermissions(): array

View File

@@ -13,6 +13,10 @@ use App\Widget\WidgetInterface;
final class AmountTotal extends AbstractAmountPeriod
{
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge(['color' => WidgetInterface::COLOR_TOTAL], parent::getOptions($options));
@@ -28,6 +32,9 @@ final class AmountTotal extends AbstractAmountPeriod
return ['view_all_data'];
}
/**
* @param array<string, string|bool|int|null> $options
*/
public function getData(array $options = []): mixed
{
return $this->getRevenue(null, null, $options);

View File

@@ -13,6 +13,10 @@ use App\Widget\WidgetInterface;
final class AmountWeek extends AbstractAmountPeriod
{
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge(['color' => WidgetInterface::COLOR_WEEK], parent::getOptions($options));
@@ -23,9 +27,12 @@ final class AmountWeek extends AbstractAmountPeriod
return 'AmountWeek';
}
/**
* @param array<string, string|bool|int|null> $options
*/
public function getData(array $options = []): mixed
{
return $this->getRevenue('monday this week 00:00:00', 'sunday this week 23:59:59', $options);
return $this->getRevenue($this->createWeekStartDate(), $this->createWeekEndDate(), $options);
}
public function getPermissions(): array

View File

@@ -13,16 +13,21 @@ use App\Configuration\SystemConfiguration;
use App\Event\RevenueStatisticEvent;
use App\Model\Revenue;
use App\Repository\TimesheetRepository;
use App\Widget\WidgetException;
use App\Widget\WidgetInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
final class AmountYear extends AbstractCounterYear
{
public function __construct(TimesheetRepository $repository, SystemConfiguration $systemConfiguration, private EventDispatcherInterface $dispatcher)
public function __construct(private TimesheetRepository $repository, SystemConfiguration $systemConfiguration, private EventDispatcherInterface $dispatcher)
{
parent::__construct($repository, $systemConfiguration);
parent::__construct($systemConfiguration);
}
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge([
@@ -31,21 +36,27 @@ final class AmountYear extends AbstractCounterYear
], parent::getOptions($options));
}
public function getData(array $options = []): mixed
/**
* @param array<string, string|bool|int|null> $options
*/
protected function getYearData(\DateTimeInterface $begin, \DateTimeInterface $end, array $options = []): mixed
{
$this->setQuery(TimesheetRepository::STATS_QUERY_RATE);
$this->setQueryWithUser(false);
try {
/** @var array<Revenue> $data */
$data = $this->repository->getRevenue($begin, $end, null);
/** @var array<Revenue> $data */
$data = parent::getData($options);
$event = new RevenueStatisticEvent($begin, $end);
foreach ($data as $row) {
$event->addRevenue($row->getCurrency(), $row->getAmount());
}
$this->dispatcher->dispatch($event);
$event = new RevenueStatisticEvent($this->getBegin(), $this->getEnd());
foreach ($data as $row) {
$event->addRevenue($row->getCurrency(), $row->getAmount());
return $event->getRevenue();
} catch (\Exception $ex) {
throw new WidgetException(
'Failed loading widget data: ' . $ex->getMessage()
);
}
$this->dispatcher->dispatch($event);
return $event->getRevenue();
}
public function getId(): string

View File

@@ -1,18 +0,0 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Widget\Type;
final class Counter extends AbstractSimpleStatisticChart
{
public function getTemplateName(): string
{
return 'widget/widget-counter.html.twig';
}
}

View File

@@ -45,6 +45,10 @@ final class DailyWorkingTimeChart extends AbstractWidget
return true;
}
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge([
@@ -56,30 +60,30 @@ final class DailyWorkingTimeChart extends AbstractWidget
], parent::getOptions($options));
}
/**
* @param array<string, string|bool|int|null> $options
*/
public function getData(array $options = []): mixed
{
$user = $this->getUser();
$dateTimeFactory = DateTimeFactory::createByUser($user);
if ($options['begin'] === null) {
$options['begin'] = $dateTimeFactory->getStartOfWeek();
$begin = $options['begin'];
if (!($begin instanceof \DateTimeInterface)) {
if (\is_string($begin)) {
$begin = new DateTime($begin, new \DateTimeZone($user->getTimezone()));
} else {
$begin = $dateTimeFactory->getStartOfWeek();
}
}
if ($options['begin'] instanceof \DateTimeInterface) {
$begin = $options['begin'];
} else {
$begin = new DateTime($options['begin'], new \DateTimeZone($user->getTimezone()));
}
if ($options['end'] === null) {
$options['end'] = $dateTimeFactory->getEndOfWeek($begin);
}
if ($options['end'] instanceof \DateTimeInterface) {
$end = $options['end'];
} else {
$end = new DateTime($options['end'], new \DateTimeZone($user->getTimezone()));
$end = $options['end'];
if (!($end instanceof \DateTimeInterface)) {
if (\is_string($end)) {
$end = new DateTime($end, new \DateTimeZone($user->getTimezone()));
} else {
$end = $dateTimeFactory->getEndOfWeek($begin);
}
}
$activities = [];

View File

@@ -9,10 +9,20 @@
namespace App\Widget\Type;
use App\Repository\TimesheetRepository;
use App\Widget\WidgetException;
use App\Widget\WidgetInterface;
final class DurationMonth extends AbstractCounterDuration
{
public function __construct(private TimesheetRepository $repository)
{
}
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge(['color' => WidgetInterface::COLOR_MONTH], parent::getOptions($options));
@@ -33,12 +43,17 @@ final class DurationMonth extends AbstractCounterDuration
return 'stats.durationMonth';
}
/**
* @param array<string, string|bool|int|null> $options
*/
public function getData(array $options = []): mixed
{
$this->setQueryWithUser(false);
$this->setBegin('first day of this month 00:00:00');
$this->setEnd('last day of this month 23:59:59');
return parent::getData($options);
try {
return $this->repository->getDurationForTimeRange($this->createMonthStartDate(), $this->createMonthEndDate(), null);
} catch (\Exception $ex) {
throw new WidgetException(
'Failed loading widget data: ' . $ex->getMessage()
);
}
}
}

View File

@@ -9,10 +9,20 @@
namespace App\Widget\Type;
use App\Repository\TimesheetRepository;
use App\Widget\WidgetException;
use App\Widget\WidgetInterface;
final class DurationToday extends AbstractCounterDuration
{
public function __construct(private TimesheetRepository $repository)
{
}
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge(['color' => WidgetInterface::COLOR_TODAY], parent::getOptions($options));
@@ -33,12 +43,17 @@ final class DurationToday extends AbstractCounterDuration
return 'stats.durationToday';
}
/**
* @param array<string, string|bool|int|null> $options
*/
public function getData(array $options = []): mixed
{
$this->setQueryWithUser(false);
$this->setBegin('00:00:00');
$this->setEnd('23:59:59');
return parent::getData($options);
try {
return $this->repository->getDurationForTimeRange($this->createTodayStartDate(), $this->createTodayEndDate(), null);
} catch (\Exception $ex) {
throw new WidgetException(
'Failed loading widget data: ' . $ex->getMessage()
);
}
}
}

View File

@@ -9,10 +9,20 @@
namespace App\Widget\Type;
use App\Repository\TimesheetRepository;
use App\Widget\WidgetException;
use App\Widget\WidgetInterface;
final class DurationTotal extends AbstractCounterDuration
{
public function __construct(private TimesheetRepository $repository)
{
}
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge(['color' => WidgetInterface::COLOR_TOTAL], parent::getOptions($options));
@@ -33,10 +43,17 @@ final class DurationTotal extends AbstractCounterDuration
return 'stats.durationTotal';
}
/**
* @param array<string, string|bool|int|null> $options
*/
public function getData(array $options = []): mixed
{
$this->setQueryWithUser(false);
return parent::getData($options);
try {
return $this->repository->getDurationForTimeRange(null, null, null);
} catch (\Exception $ex) {
throw new WidgetException(
'Failed loading widget data: ' . $ex->getMessage()
);
}
}
}

View File

@@ -9,10 +9,20 @@
namespace App\Widget\Type;
use App\Repository\TimesheetRepository;
use App\Widget\WidgetException;
use App\Widget\WidgetInterface;
final class DurationWeek extends AbstractCounterDuration
{
public function __construct(private TimesheetRepository $repository)
{
}
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge(['color' => WidgetInterface::COLOR_WEEK], parent::getOptions($options));
@@ -33,12 +43,17 @@ final class DurationWeek extends AbstractCounterDuration
return 'stats.durationWeek';
}
/**
* @param array<string, string|bool|int|null> $options
*/
public function getData(array $options = []): mixed
{
$this->setQueryWithUser(false);
$this->setBegin('monday this week 00:00:00');
$this->setEnd('sunday this week 23:59:59');
return parent::getData($options);
try {
return $this->repository->getDurationForTimeRange($this->createWeekStartDate(), $this->createWeekEndDate(), null);
} catch (\Exception $ex) {
throw new WidgetException(
'Failed loading widget data: ' . $ex->getMessage()
);
}
}
}

View File

@@ -9,11 +9,22 @@
namespace App\Widget\Type;
use App\Configuration\SystemConfiguration;
use App\Repository\TimesheetRepository;
use App\Widget\WidgetException;
use App\Widget\WidgetInterface;
final class DurationYear extends AbstractCounterYear
{
public function __construct(private TimesheetRepository $repository, SystemConfiguration $systemConfiguration)
{
parent::__construct($systemConfiguration);
}
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge([
@@ -22,12 +33,18 @@ final class DurationYear extends AbstractCounterYear
], parent::getOptions($options));
}
public function getData(array $options = []): mixed
/**
* @param array<string, string|bool|int|null> $options
*/
protected function getYearData(\DateTimeInterface $begin, \DateTimeInterface $end, array $options = []): mixed
{
$this->setQuery(TimesheetRepository::STATS_QUERY_DURATION);
$this->setQueryWithUser(false);
return parent::getData($options);
try {
return $this->repository->getDurationForTimeRange($begin, $end, null);
} catch (\Exception $ex) {
throw new WidgetException(
'Failed loading widget data: ' . $ex->getMessage()
);
}
}
public function getPermissions(): array

View File

@@ -1,36 +0,0 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Widget\Type;
class More extends AbstractWidgetType
{
private mixed $data = null;
public function setData($data): self
{
$this->data = $data;
return $this;
}
/**
* @param array $options
* @return mixed|null
*/
public function getData(array $options = []): mixed
{
return $this->data;
}
public function getTemplateName(): string
{
return 'widget/widget-more.html.twig';
}
}

View File

@@ -12,6 +12,7 @@ namespace App\Widget\Type;
use App\Configuration\SystemConfiguration;
use App\Repository\TimesheetRepository;
use App\Timesheet\DateTimeFactory;
use App\Widget\WidgetException;
use App\Widget\WidgetInterface;
use DateTime;
@@ -46,6 +47,10 @@ final class PaginatedWorkingTimeChart extends AbstractWidget
return 'widget/widget-paginatedworkingtimechart.html.twig';
}
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
$options = parent::getOptions($options);
@@ -81,6 +86,9 @@ final class PaginatedWorkingTimeChart extends AbstractWidget
return $lastWeekInYear->format('W') === '53' ? 53 : 52;
}
/**
* @param array<string, string|bool|int|null> $options
*/
public function getData(array $options = []): mixed
{
$user = $this->getUser();
@@ -88,7 +96,18 @@ final class PaginatedWorkingTimeChart extends AbstractWidget
$dateTimeFactory = DateTimeFactory::createByUser($user);
$year = $options['year'];
if (\is_string($year)) {
$year = (int) $year;
} elseif (!\is_int($year)) {
throw new WidgetException('Invalid year given');
}
$week = $options['week'];
if (\is_string($week)) {
$week = (int) $week;
} elseif (!\is_int($week)) {
throw new WidgetException('Invalid week given');
}
$weekBegin = ($dateTimeFactory->createDateTime())->setISODate($year, $week, 1)->setTime(0, 0, 0);
@@ -99,7 +118,7 @@ final class PaginatedWorkingTimeChart extends AbstractWidget
$lastWeekInLastYear = $this->getLastWeekInYear($year - 1);
$thisMonth = clone $weekBegin;
if ((int) $week === 1) {
if ($week === 1) {
$thisMonth = ($dateTimeFactory->createDateTime())->setISODate($year, $week, 1)->setTime(0, 0, 0);
}
@@ -111,7 +130,7 @@ final class PaginatedWorkingTimeChart extends AbstractWidget
$yearBegin = $dateTimeFactory->createDateTime(sprintf('01 january %s 00:00:00', $year));
$yearEnd = $dateTimeFactory->createDateTime(sprintf('31 december %s 23:59:59', $year));
$yearData = $this->repository->getStatistic(TimesheetRepository::STATS_QUERY_DURATION, $yearBegin, $yearEnd, $user);
$yearData = $this->repository->getDurationForTimeRange($yearBegin, $yearEnd, $user);
$financialYearData = null;
$financialYearBegin = null;
@@ -119,7 +138,7 @@ final class PaginatedWorkingTimeChart extends AbstractWidget
if (null !== ($financialYear = $this->systemConfiguration->getFinancialYearStart())) {
$financialYearBegin = $dateTimeFactory->createStartOfFinancialYear($financialYear);
$financialYearEnd = $dateTimeFactory->createEndOfFinancialYear($financialYearBegin);
$financialYearData = $this->repository->getStatistic(TimesheetRepository::STATS_QUERY_DURATION, $financialYearBegin, $financialYearEnd, $user);
$financialYearData = $this->repository->getDurationForTimeRange($financialYearBegin, $financialYearEnd, $user);
}
return [
@@ -128,9 +147,9 @@ final class PaginatedWorkingTimeChart extends AbstractWidget
'thisMonth' => $thisMonth,
'lastWeekInYear' => $lastWeekInYear,
'lastWeekInLastYear' => $lastWeekInLastYear,
'day' => $this->repository->getStatistic(TimesheetRepository::STATS_QUERY_DURATION, $dayBegin, $dayEnd, $user),
'week' => $this->repository->getStatistic(TimesheetRepository::STATS_QUERY_DURATION, $weekBegin, $weekEnd, $user),
'month' => $this->repository->getStatistic(TimesheetRepository::STATS_QUERY_DURATION, $monthBegin, $monthEnd, $user),
'day' => $this->repository->getDurationForTimeRange($dayBegin, $dayEnd, $user),
'week' => $this->repository->getDurationForTimeRange($weekBegin, $weekEnd, $user),
'month' => $this->repository->getDurationForTimeRange($monthBegin, $monthEnd, $user),
'year' => $yearData,
'financial' => $financialYearData,
'financialBegin' => $financialYearBegin,

View File

@@ -24,6 +24,10 @@ final class TotalsActivity extends AbstractWidget
return 'stats.activityTotal';
}
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge([
@@ -33,6 +37,9 @@ final class TotalsActivity extends AbstractWidget
], parent::getOptions($options));
}
/**
* @param array<string, string|bool|int|null> $options
*/
public function getData(array $options = []): mixed
{
$user = $this->getUser();

View File

@@ -24,6 +24,10 @@ final class TotalsCustomer extends AbstractWidget
return 'stats.customerTotal';
}
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge([
@@ -33,6 +37,9 @@ final class TotalsCustomer extends AbstractWidget
], parent::getOptions($options));
}
/**
* @param array<string, string|bool|int|null> $options
*/
public function getData(array $options = []): mixed
{
$user = $this->getUser();

View File

@@ -24,6 +24,10 @@ final class TotalsProject extends AbstractWidget
return 'stats.projectTotal';
}
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge([
@@ -33,6 +37,9 @@ final class TotalsProject extends AbstractWidget
], parent::getOptions($options));
}
/**
* @param array<string, string|bool|int|null> $options
*/
public function getData(array $options = []): mixed
{
$user = $this->getUser();

View File

@@ -19,6 +19,10 @@ final class TotalsUser extends AbstractWidget
{
}
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge([
@@ -28,6 +32,9 @@ final class TotalsUser extends AbstractWidget
], parent::getOptions($options));
}
/**
* @param array<string, string|bool|int|null> $options
*/
public function getData(array $options = []): mixed
{
$user = $this->getUser();

View File

@@ -13,6 +13,10 @@ use App\Widget\WidgetInterface;
final class UserAmountMonth extends AbstractUserRevenuePeriod
{
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge(['color' => WidgetInterface::COLOR_MONTH], parent::getOptions($options));
@@ -23,8 +27,11 @@ final class UserAmountMonth extends AbstractUserRevenuePeriod
return 'UserAmountMonth';
}
/**
* @param array<string, string|bool|int|null> $options
*/
public function getData(array $options = []): mixed
{
return $this->getRevenue('first day of this month 00:00:00', 'last day of this month 23:59:59', $options);
return $this->getRevenue($this->createMonthStartDate(), $this->createMonthEndDate(), $options);
}
}

View File

@@ -13,6 +13,10 @@ use App\Widget\WidgetInterface;
final class UserAmountToday extends AbstractUserRevenuePeriod
{
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge(['color' => WidgetInterface::COLOR_TODAY], parent::getOptions($options));
@@ -23,8 +27,11 @@ final class UserAmountToday extends AbstractUserRevenuePeriod
return 'UserAmountToday';
}
/**
* @param array<string, string|bool|int|null> $options
*/
public function getData(array $options = []): mixed
{
return $this->getRevenue('00:00:00', '23:59:59', $options);
return $this->getRevenue($this->createTodayStartDate(), $this->createTodayEndDate(), $options);
}
}

View File

@@ -13,6 +13,10 @@ use App\Widget\WidgetInterface;
final class UserAmountTotal extends AbstractUserRevenuePeriod
{
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge(['color' => WidgetInterface::COLOR_TOTAL], parent::getOptions($options));
@@ -23,6 +27,9 @@ final class UserAmountTotal extends AbstractUserRevenuePeriod
return 'UserAmountTotal';
}
/**
* @param array<string, string|bool|int|null> $options
*/
public function getData(array $options = []): mixed
{
return $this->getRevenue(null, null, $options);

View File

@@ -13,6 +13,10 @@ use App\Widget\WidgetInterface;
final class UserAmountWeek extends AbstractUserRevenuePeriod
{
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge(['color' => WidgetInterface::COLOR_WEEK], parent::getOptions($options));
@@ -23,8 +27,11 @@ final class UserAmountWeek extends AbstractUserRevenuePeriod
return 'UserAmountWeek';
}
/**
* @param array<string, string|bool|int|null> $options
*/
public function getData(array $options = []): mixed
{
return $this->getRevenue('monday this week 00:00:00', 'sunday this week 23:59:59', $options);
return $this->getRevenue($this->createWeekStartDate(), $this->createWeekEndDate(), $options);
}
}

View File

@@ -13,14 +13,15 @@ use App\Configuration\SystemConfiguration;
use App\Event\UserRevenueStatisticEvent;
use App\Model\Revenue;
use App\Repository\TimesheetRepository;
use App\Widget\WidgetException;
use App\Widget\WidgetInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
final class UserAmountYear extends AbstractCounterYear
{
public function __construct(TimesheetRepository $repository, SystemConfiguration $systemConfiguration, private EventDispatcherInterface $dispatcher)
public function __construct(private TimesheetRepository $repository, SystemConfiguration $systemConfiguration, private EventDispatcherInterface $dispatcher)
{
parent::__construct($repository, $systemConfiguration);
parent::__construct($systemConfiguration);
}
public function getTemplateName(): string
@@ -43,6 +44,10 @@ final class UserAmountYear extends AbstractCounterYear
return 'UserAmountYear';
}
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge([
@@ -51,20 +56,26 @@ final class UserAmountYear extends AbstractCounterYear
], parent::getOptions($options));
}
public function getData(array $options = []): mixed
/**
* @param array<string, string|bool|int|null> $options
*/
protected function getYearData(\DateTimeInterface $begin, \DateTimeInterface $end, array $options = []): mixed
{
$this->setQuery(TimesheetRepository::STATS_QUERY_RATE);
$this->setQueryWithUser(true);
try {
/** @var array<Revenue> $data */
$data = $this->repository->getRevenue($begin, $end, $this->getUser());
/** @var array<Revenue> $data */
$data = parent::getData($options);
$event = new UserRevenueStatisticEvent($this->getUser(), $begin, $end);
foreach ($data as $row) {
$event->addRevenue($row->getCurrency(), $row->getAmount());
}
$this->dispatcher->dispatch($event);
$event = new UserRevenueStatisticEvent($this->getUser(), $this->getBegin(), $this->getEnd());
foreach ($data as $row) {
$event->addRevenue($row->getCurrency(), $row->getAmount());
return $event->getRevenue();
} catch (\Exception $ex) {
throw new WidgetException(
'Failed loading widget data: ' . $ex->getMessage()
);
}
$this->dispatcher->dispatch($event);
return $event->getRevenue();
}
}

View File

@@ -9,10 +9,20 @@
namespace App\Widget\Type;
use App\Repository\TimesheetRepository;
use App\Widget\WidgetException;
use App\Widget\WidgetInterface;
final class UserDurationMonth extends AbstractCounterDuration
{
public function __construct(private TimesheetRepository $repository)
{
}
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge(['color' => WidgetInterface::COLOR_MONTH], parent::getOptions($options));
@@ -28,12 +38,17 @@ final class UserDurationMonth extends AbstractCounterDuration
return 'userDurationMonth';
}
/**
* @param array<string, string|bool|int|null> $options
*/
public function getData(array $options = []): mixed
{
$this->setQueryWithUser(true);
$this->setBegin('first day of this month 00:00:00');
$this->setEnd('last day of this month 23:59:59');
return parent::getData($options);
try {
return $this->repository->getDurationForTimeRange($this->createMonthStartDate(), $this->createMonthEndDate(), $this->getUser());
} catch (\Exception $ex) {
throw new WidgetException(
'Failed loading widget data: ' . $ex->getMessage()
);
}
}
}

View File

@@ -9,10 +9,20 @@
namespace App\Widget\Type;
use App\Repository\TimesheetRepository;
use App\Widget\WidgetException;
use App\Widget\WidgetInterface;
final class UserDurationToday extends AbstractCounterDuration
{
public function __construct(private TimesheetRepository $repository)
{
}
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge(['color' => WidgetInterface::COLOR_TODAY], parent::getOptions($options));
@@ -28,12 +38,17 @@ final class UserDurationToday extends AbstractCounterDuration
return 'userDurationToday';
}
/**
* @param array<string, string|bool|int|null> $options
*/
public function getData(array $options = []): mixed
{
$this->setQueryWithUser(true);
$this->setBegin('00:00:00');
$this->setEnd('23:59:59');
return parent::getData($options);
try {
return $this->repository->getDurationForTimeRange($this->createTodayStartDate(), $this->createTodayEndDate(), $this->getUser());
} catch (\Exception $ex) {
throw new WidgetException(
'Failed loading widget data: ' . $ex->getMessage()
);
}
}
}

View File

@@ -9,10 +9,20 @@
namespace App\Widget\Type;
use App\Repository\TimesheetRepository;
use App\Widget\WidgetException;
use App\Widget\WidgetInterface;
final class UserDurationTotal extends AbstractCounterDuration
{
public function __construct(private TimesheetRepository $repository)
{
}
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge(['color' => WidgetInterface::COLOR_TOTAL], parent::getOptions($options));
@@ -28,10 +38,17 @@ final class UserDurationTotal extends AbstractCounterDuration
return 'userDurationTotal';
}
/**
* @param array<string, string|bool|int|null> $options
*/
public function getData(array $options = []): mixed
{
$this->setQueryWithUser(true);
return parent::getData($options);
try {
return $this->repository->getDurationForTimeRange(null, null, $this->getUser());
} catch (\Exception $ex) {
throw new WidgetException(
'Failed loading widget data: ' . $ex->getMessage()
);
}
}
}

View File

@@ -9,10 +9,20 @@
namespace App\Widget\Type;
use App\Repository\TimesheetRepository;
use App\Widget\WidgetException;
use App\Widget\WidgetInterface;
final class UserDurationWeek extends AbstractCounterDuration
{
public function __construct(private TimesheetRepository $repository)
{
}
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge(['color' => WidgetInterface::COLOR_WEEK], parent::getOptions($options));
@@ -28,12 +38,17 @@ final class UserDurationWeek extends AbstractCounterDuration
return 'userDurationWeek';
}
/**
* @param array<string, string|bool|int|null> $options
*/
public function getData(array $options = []): mixed
{
$this->setQueryWithUser(true);
$this->setBegin('monday this week 00:00:00');
$this->setEnd('sunday this week 23:59:59');
return parent::getData($options);
try {
return $this->repository->getDurationForTimeRange($this->createWeekStartDate(), $this->createWeekEndDate(), $this->getUser());
} catch (\Exception $ex) {
throw new WidgetException(
'Failed loading widget data: ' . $ex->getMessage()
);
}
}
}

View File

@@ -9,11 +9,18 @@
namespace App\Widget\Type;
use App\Configuration\SystemConfiguration;
use App\Repository\TimesheetRepository;
use App\Widget\WidgetException;
use App\Widget\WidgetInterface;
final class UserDurationYear extends AbstractCounterYear
{
public function __construct(private TimesheetRepository $repository, SystemConfiguration $systemConfiguration)
{
parent::__construct($systemConfiguration);
}
public function getId(): string
{
return 'userDurationYear';
@@ -24,6 +31,10 @@ final class UserDurationYear extends AbstractCounterYear
return 'widget/widget-counter-duration.html.twig';
}
/**
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array
{
return array_merge([
@@ -32,12 +43,18 @@ final class UserDurationYear extends AbstractCounterYear
], parent::getOptions($options));
}
public function getData(array $options = []): mixed
/**
* @param array<string, string|bool|int|null> $options
*/
protected function getYearData(\DateTimeInterface $begin, \DateTimeInterface $end, array $options = []): mixed
{
$this->setQuery(TimesheetRepository::STATS_QUERY_DURATION);
$this->setQueryWithUser(true);
return parent::getData($options);
try {
return $this->repository->getDurationForTimeRange($begin, $end, $this->getUser());
} catch (\Exception $ex) {
throw new WidgetException(
'Failed loading widget data: ' . $ex->getMessage()
);
}
}
protected function getFinancialYearTitle(): string

View File

@@ -59,6 +59,9 @@ final class UserTeamProjects extends AbstractWidget
return 'UserTeamProjects';
}
/**
* @param array<string, string|bool|int|null> $options
*/
public function getData(array $options = []): mixed
{
$user = $this->getUser();

View File

@@ -52,6 +52,9 @@ final class UserTeams extends AbstractWidget
return 'UserTeams';
}
/**
* @param array<string, string|bool|int|null> $options
*/
public function getData(array $options = []): mixed
{
$user = $this->getUser();

View File

@@ -71,10 +71,10 @@ interface WidgetInterface
* make sure that the given $options will overwrite the internal option for
* this one call.
*
* @param array $options
* @param array<string, string|bool|int|null> $options
* @return mixed|null
*/
public function getData(array $options = []);
public function getData(array $options = []): mixed;
/**
* Returns all widget options to be used in the frontend.
@@ -86,7 +86,7 @@ interface WidgetInterface
* return array_merge($this->options, $options);
*
* @param array<string, string|bool|int|null> $options
* @return array<string, string|bool|int|null|null>
* @return array<string, string|bool|int|null>
*/
public function getOptions(array $options = []): array;