Release 2.0.13 (#3955)

- added missing escape to prevent HTML injection
- added missing color attribute
- upgrade theme
  - use dropdown submenu if title is set, otherwise dropdown tends to get too long
  - allow to use card-table instead of card-body
  - added `required` attribute to username and password field
- fix pagination back to page 1
- prevent tag name too long
- re-add missing user preferences link
This commit is contained in:
Kevin Papst
2023-03-30 01:08:15 +02:00
committed by GitHub
parent 7164ec126f
commit 01226a1243
23 changed files with 102 additions and 153 deletions

View File

@@ -17,11 +17,11 @@ class Constants
/**
* The current release version
*/
public const VERSION = '2.0.12';
public const VERSION = '2.0.13';
/**
* The current release: major * 10000 + minor * 100 + patch
*/
public const VERSION_ID = 20012;
public const VERSION_ID = 20013;
/**
* The software name
*/

View File

@@ -87,6 +87,7 @@ final class ReportUsersMonthController extends AbstractController
$values->setDate($dateTimeFactory->getStartOfMonth());
}
/** @var \DateTime $start */
$start = $values->getDate();
$start->modify('first day of 00:00:00');

View File

@@ -9,6 +9,7 @@
namespace App\Controller\Reporting;
use App\Entity\User;
use App\Model\DailyStatistic;
use App\Reporting\MonthByUser\MonthByUser;
use App\Reporting\MonthByUser\MonthByUserForm;
@@ -64,12 +65,14 @@ final class UserMonthController extends AbstractUserReportController
$values->setDate($dateTimeFactory->getStartOfMonth());
}
/** @var \DateTime $start */
$start = $values->getDate();
$start->modify('first day of 00:00:00');
$end = clone $start;
$end->modify('last day of 23:59:59');
/** @var User $selectedUser */
$selectedUser = $values->getUser();
$previousMonth = clone $start;

View File

@@ -55,12 +55,12 @@ final class TagFixtures extends Fixture
$tagName = $faker->text(rand(5, 10));
}
if (\in_array($tagName, $existing)) {
if (\in_array(mb_strtolower($tagName), $existing, true)) {
continue;
}
$existing[] = $tagName;
$tag->setName($tagName);
$existing[] = mb_strtolower($tagName);
$tag->setName(mb_substr($tagName, 0, 100));
$manager->persist($tag);

View File

@@ -10,7 +10,6 @@
namespace App\DataFixtures;
use App\Entity\Activity;
use App\Entity\Customer;
use App\Entity\Project;
use App\Entity\Tag;
use App\Entity\Timesheet;
@@ -58,12 +57,8 @@ final class TimesheetFixtures extends Fixture implements FixtureGroupInterface
public function load(ObjectManager $manager): void
{
$results = $this->findRandom($manager, Customer::class, 50);
$allUser = $this->getAllUsers($manager);
$faker = Factory::create();
$all = 0;
foreach ($allUser as $user) {

View File

@@ -47,6 +47,10 @@ final class UserSubscriber extends AbstractActionsSubscriber
$event->addActionToSubmenu('edit', $id, $action);
}
if ($this->isGranted('preferences', $user)) {
$event->addConfig($this->path('user_profile_preferences', ['username' => $user->getUserIdentifier()]));
}
if (($event->getUser()->getId() === $user->getId() && $this->isGranted('report:user')) || $this->isGranted('report:other')) {
$event->addActionToSubmenu('report', 'weekly', ['url' => $this->path('report_user_week', ['user' => $user->getId()]), 'translation_domain' => 'reporting', 'title' => 'report_user_week']);
$event->addActionToSubmenu('report', 'monthly', ['url' => $this->path('report_user_month', ['user' => $user->getId()]), 'translation_domain' => 'reporting', 'title' => 'report_user_month']);

View File

@@ -60,7 +60,7 @@ final class TagArrayToStringTransformer implements DataTransformerInterface
foreach ($newNames as $name) {
$tag = new Tag();
$tag->setName($name);
$tag->setName(mb_substr($name, 0, 100));
$tags[] = $tag;
// new tags persist automatically thanks to the cascade={"persist"}

View File

@@ -11,6 +11,7 @@ namespace App\Form\Type;
use App\Configuration\SystemConfiguration;
use App\Constants;
use App\Utils\Color;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
@@ -39,6 +40,13 @@ final class ColorChoiceType extends AbstractType implements DataTransformerInter
],
'label' => 'color',
'empty_data' => null,
'choice_attr' => function ($color, $name) {
if ($color === null) {
$color = (new Color())->getRandom($name);
}
return ['data-color' => $color];
},
];
$choices = [];

View File

@@ -80,7 +80,7 @@ final class TagsSelectType extends AbstractType
$newNames = array_diff($newNames, $foundTagNames);
foreach ($newNames as $name) {
$tag = new Tag();
$tag->setName($name);
$tag->setName(mb_substr($name, 0, 100));
$this->tagRepository->saveTag($tag);
$newData[] = $tag->getId();
}

View File

@@ -11,7 +11,6 @@ namespace App\Model;
use App\Entity\User;
use App\Model\Statistic\StatisticDate;
use DateTime;
use DateTimeInterface;
final class DailyStatistic implements DateStatisticInterface
@@ -19,16 +18,14 @@ final class DailyStatistic implements DateStatisticInterface
/**
* @var array<string, StatisticDate>
*/
private $days = [];
private $begin;
private $end;
private $user;
private array $days = [];
private DateTimeInterface $begin;
private DateTimeInterface $end;
public function __construct(DateTime $begin, DateTime $end, User $user)
public function __construct(DateTimeInterface $begin, DateTimeInterface $end, private User $user)
{
$this->begin = clone $begin;
$this->end = clone $end;
$this->user = $user;
}
public function getUser(): User
@@ -42,7 +39,7 @@ final class DailyStatistic implements DateStatisticInterface
return;
}
$tmp = clone $this->begin;
$tmp = \DateTime::createFromInterface($this->begin);
$tmp->setTime(0, 0, 0);
while ($tmp < $this->end) {
$id = $tmp->format('Y-m-d');

View File

@@ -116,7 +116,7 @@ final class LocaleFormatExtensions extends AbstractExtension implements LocaleAw
return $this->locale;
}
public function isWeekend(DateTime|string|null $dateTime): bool
public function isWeekend(\DateTimeInterface|string|null $dateTime): bool
{
if (!$dateTime instanceof \DateTime) {
return false;
@@ -141,7 +141,7 @@ final class LocaleFormatExtensions extends AbstractExtension implements LocaleAw
return ($day === 0 || $day === 6);
}
public function dateShort(DateTime|string|null $date): string
public function dateShort(\DateTimeInterface|string|null $date): string
{
return (string) $this->getFormatter()->dateShort($date);
}
@@ -158,17 +158,17 @@ final class LocaleFormatExtensions extends AbstractExtension implements LocaleAw
return new DateTime($date, new \DateTimeZone($timezone));
}
public function dateFormat(DateTime|string|null $date, string $format): string
public function dateFormat(\DateTimeInterface|string|null $date, string $format): string
{
return (string) $this->getFormatter()->dateFormat($date, $format);
}
public function dateWeekday(DateTime $date): string
public function dateWeekday(\DateTimeInterface $date): string
{
return $this->dayName($date, true) . ' ' . $this->getFormatter()->dateFormat($date, 'd');
}
public function time(DateTime|string|null $date): string
public function time(\DateTimeInterface|string|null $date): string
{
return (string) $this->getFormatter()->time($date);
}
@@ -192,12 +192,12 @@ final class LocaleFormatExtensions extends AbstractExtension implements LocaleAw
return $months;
}
public function monthName(\DateTime $dateTime, bool $withYear = false): string
public function monthName(\DateTimeInterface $dateTime, bool $withYear = false): string
{
return $this->getFormatter()->monthName($dateTime, $withYear);
}
public function dayName(\DateTime $dateTime, bool $short = false): string
public function dayName(\DateTimeInterface $dateTime, bool $short = false): string
{
return $this->getFormatter()->dayName($dateTime, $short);
}

View File

@@ -283,7 +283,7 @@ final class LocaleFormatter
/**
* @see https://unicode-org.github.io/icu/userguide/format_parse/datetime/
*/
private function formatIntl(\DateTime $dateTime, string $format): string
private function formatIntl(\DateTimeInterface $dateTime, string $format): string
{
$formatter = new IntlDateFormatter(
$this->locale,
@@ -303,12 +303,12 @@ final class LocaleFormatter
return (string) $formatted;
}
public function monthName(\DateTime $dateTime, bool $withYear = false): string
public function monthName(\DateTimeInterface $dateTime, bool $withYear = false): string
{
return $this->formatIntl($dateTime, ($withYear ? 'LLLL yyyy' : 'LLLL'));
}
public function dayName(\DateTime $dateTime, bool $short = false): string
public function dayName(\DateTimeInterface $dateTime, bool $short = false): string
{
return $this->formatIntl($dateTime, ($short ? 'EE' : 'EEEE'));
}