Release 1.30 (#3651)
* exclude all 403 and 404 from logs * bump version * cleanup tag handling * prevent mandatory user preferences turning null
This commit is contained in:
@@ -4,9 +4,7 @@ monolog:
|
|||||||
type: fingers_crossed
|
type: fingers_crossed
|
||||||
action_level: error
|
action_level: error
|
||||||
handler: nested
|
handler: nested
|
||||||
excluded_404s:
|
excluded_http_codes: [403, 404]
|
||||||
# regex: exclude all 404 errors from the logs
|
|
||||||
- ^/
|
|
||||||
nested:
|
nested:
|
||||||
type: stream
|
type: stream
|
||||||
level: info
|
level: info
|
||||||
|
|||||||
@@ -942,7 +942,7 @@ final class KimaiImporterCommand extends Command
|
|||||||
$user->addPreference($newPref);
|
$user->addPreference($newPref);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set default values if they were not set in the the user preferences
|
// set default values if they were not set in the user preferences
|
||||||
$defaults = ['language' => $language, 'timezone' => $timezone];
|
$defaults = ['language' => $language, 'timezone' => $timezone];
|
||||||
foreach ($defaults as $key => $default) {
|
foreach ($defaults as $key => $default) {
|
||||||
if (null === $user->getPreferenceValue($key)) {
|
if (null === $user->getPreferenceValue($key)) {
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ class Constants
|
|||||||
/**
|
/**
|
||||||
* The current release version
|
* The current release version
|
||||||
*/
|
*/
|
||||||
public const VERSION = '1.29.1';
|
public const VERSION = '1.30.0';
|
||||||
/**
|
/**
|
||||||
* The current release: major * 10000 + minor * 100 + patch
|
* The current release: major * 10000 + minor * 100 + patch
|
||||||
*/
|
*/
|
||||||
public const VERSION_ID = 12901;
|
public const VERSION_ID = 13000;
|
||||||
/**
|
/**
|
||||||
* The current release status, either "stable" or "dev"
|
* The current release status, either "stable" or "dev"
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ class HomepageController extends AbstractController
|
|||||||
{
|
{
|
||||||
/** @var User $user */
|
/** @var User $user */
|
||||||
$user = $this->getUser();
|
$user = $this->getUser();
|
||||||
$userRoute = $user->getPreferenceValue('login.initial_view', InitialViewType::DEFAULT_VIEW);
|
$userRoute = $user->getPreferenceValue('login.initial_view', InitialViewType::DEFAULT_VIEW, false);
|
||||||
$userLanguage = $user->getLanguage();
|
$userLanguage = $user->getLanguage();
|
||||||
$requestLanguage = $request->getLocale();
|
$requestLanguage = $request->getLocale();
|
||||||
|
|
||||||
|
|||||||
@@ -262,7 +262,7 @@ final class ProfileController extends AbstractController
|
|||||||
// switch locale ONLY if updated profile is the current user
|
// switch locale ONLY if updated profile is the current user
|
||||||
$locale = $request->getLocale();
|
$locale = $request->getLocale();
|
||||||
if ($this->getUser()->getId() === $profile->getId()) {
|
if ($this->getUser()->getId() === $profile->getId()) {
|
||||||
$locale = $profile->getPreferenceValue('language', $locale);
|
$locale = $profile->getPreferenceValue('language', $locale, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->redirectToRoute('user_profile_preferences', [
|
return $this->redirectToRoute('user_profile_preferences', [
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ final class ReportingController extends AbstractController
|
|||||||
$user = $this->getUser();
|
$user = $this->getUser();
|
||||||
$route = null;
|
$route = null;
|
||||||
|
|
||||||
$defaultReport = $user->getPreferenceValue('reporting.initial_view', ReportingService::DEFAULT_VIEW);
|
$defaultReport = $user->getPreferenceValue('reporting.initial_view', ReportingService::DEFAULT_VIEW, false);
|
||||||
$allReports = $reportingService->getAvailableReports($user);
|
$allReports = $reportingService->getAvailableReports($user);
|
||||||
|
|
||||||
foreach ($allReports as $report) {
|
foreach ($allReports as $report) {
|
||||||
@@ -43,7 +43,7 @@ final class ReportingController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
// fallback, if the configured report could not be found
|
// fallback, if the configured report could not be found
|
||||||
// eg. when it was deleted or replaced by an enhanced version with a new id
|
// e.g. when it was deleted or replaced by an enhanced version with a new id
|
||||||
if ($route === null && \count($allReports) > 0) {
|
if ($route === null && \count($allReports) > 0) {
|
||||||
$report = $allReports[array_keys($allReports)[0]];
|
$report = $allReports[array_keys($allReports)[0]];
|
||||||
$route = $report->getRoute();
|
$route = $report->getRoute();
|
||||||
|
|||||||
@@ -535,7 +535,7 @@ abstract class TimesheetAbstractController extends AbstractController
|
|||||||
|
|
||||||
protected function includeSummary(): bool
|
protected function includeSummary(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getUser()->getPreferenceValue('timesheet.daily_stats', false);
|
return (bool) $this->getUser()->getPreferenceValue('timesheet.daily_stats', false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function includeUserInForms(string $formName): bool
|
protected function includeUserInForms(string $formName): bool
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ class TimesheetTeamController extends TimesheetAbstractController
|
|||||||
$tags = [];
|
$tags = [];
|
||||||
/** @var Tag $tag */
|
/** @var Tag $tag */
|
||||||
foreach ($entry->getTags() as $tag) {
|
foreach ($entry->getTags() as $tag) {
|
||||||
$tag->removeTimesheet($entry);
|
$entry->addTag($tag);
|
||||||
$tags[] = $tag;
|
$tags[] = $tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ class TimesheetFixtures extends Fixture implements FixtureGroupInterface
|
|||||||
{
|
{
|
||||||
$start = $this->getRandomFirstDay();
|
$start = $this->getRandomFirstDay();
|
||||||
$start = $start->modify('- ' . (rand(1, 86400)) . ' seconds');
|
$start = $start->modify('- ' . (rand(1, 86400)) . ' seconds');
|
||||||
$start->setTimezone(new \DateTimeZone($user->getPreferenceValue(UserPreference::TIMEZONE, date_default_timezone_get())));
|
$start->setTimezone(new \DateTimeZone($user->getTimezone()));
|
||||||
|
|
||||||
$entry = new Timesheet();
|
$entry = new Timesheet();
|
||||||
$entry
|
$entry
|
||||||
|
|||||||
@@ -545,7 +545,6 @@ class Timesheet implements EntityWithMetaFields, ExportItemInterface
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
$this->tags->add($tag);
|
$this->tags->add($tag);
|
||||||
$tag->addTimesheet($this);
|
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@@ -559,7 +558,6 @@ class Timesheet implements EntityWithMetaFields, ExportItemInterface
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$this->tags->removeElement($tag);
|
$this->tags->removeElement($tag);
|
||||||
$tag->removeTimesheet($this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -481,17 +481,17 @@ class User implements UserInterface, EquatableInterface, \Serializable
|
|||||||
|
|
||||||
public function is24Hour(): bool
|
public function is24Hour(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getPreferenceValue(UserPreference::HOUR_24, true);
|
return (bool) $this->getPreferenceValue(UserPreference::HOUR_24, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getLocale(): string
|
public function getLocale(): string
|
||||||
{
|
{
|
||||||
return $this->getPreferenceValue(UserPreference::LOCALE, User::DEFAULT_LANGUAGE);
|
return $this->getPreferenceValue(UserPreference::LOCALE, User::DEFAULT_LANGUAGE, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTimezone(): string
|
public function getTimezone(): string
|
||||||
{
|
{
|
||||||
return $this->getPreferenceValue(UserPreference::TIMEZONE, date_default_timezone_get());
|
return $this->getPreferenceValue(UserPreference::TIMEZONE, date_default_timezone_get(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getLanguage(): string
|
public function getLanguage(): string
|
||||||
@@ -514,17 +514,17 @@ class User implements UserInterface, EquatableInterface, \Serializable
|
|||||||
|
|
||||||
public function getFirstDayOfWeek(): string
|
public function getFirstDayOfWeek(): string
|
||||||
{
|
{
|
||||||
return $this->getPreferenceValue(UserPreference::FIRST_WEEKDAY, User::DEFAULT_FIRST_WEEKDAY);
|
return $this->getPreferenceValue(UserPreference::FIRST_WEEKDAY, User::DEFAULT_FIRST_WEEKDAY, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isSmallLayout(): bool
|
public function isSmallLayout(): bool
|
||||||
{
|
{
|
||||||
return $this->getPreferenceValue('theme.layout', 'fixed') === 'boxed';
|
return $this->getPreferenceValue('theme.layout', 'fixed', false) === 'boxed';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isExportDecimal(): bool
|
public function isExportDecimal(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getPreferenceValue('timesheet.export_decimal', false);
|
return (bool) $this->getPreferenceValue('timesheet.export_decimal', false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setTimezone(?string $timezone)
|
public function setTimezone(?string $timezone)
|
||||||
@@ -538,16 +538,19 @@ class User implements UserInterface, EquatableInterface, \Serializable
|
|||||||
/**
|
/**
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @param mixed $default
|
* @param mixed $default
|
||||||
|
* @param bool $allowNull
|
||||||
* @return bool|int|string|null
|
* @return bool|int|string|null
|
||||||
*/
|
*/
|
||||||
public function getPreferenceValue(string $name, $default = null)
|
public function getPreferenceValue(string $name, $default = null, bool $allowNull = true)
|
||||||
{
|
{
|
||||||
$preference = $this->getPreference($name);
|
$preference = $this->getPreference($name);
|
||||||
if (null === $preference) {
|
if (null === $preference) {
|
||||||
return $default;
|
return $default;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $preference->getValue();
|
$value = $preference->getValue();
|
||||||
|
|
||||||
|
return $allowNull ? $value : ($value ?? $default);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ final class RateService implements RateServiceInterface
|
|||||||
|
|
||||||
if (null !== $fixedRate) {
|
if (null !== $fixedRate) {
|
||||||
if (null === $fixedInternalRate) {
|
if (null === $fixedInternalRate) {
|
||||||
$fixedInternalRate = (float) $record->getUser()->getPreferenceValue(UserPreference::INTERNAL_RATE, $fixedRate);
|
$fixedInternalRate = (float) $record->getUser()->getPreferenceValue(UserPreference::INTERNAL_RATE, $fixedRate, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Rate($fixedRate, $fixedInternalRate, null, $fixedRate);
|
return new Rate($fixedRate, $fixedInternalRate, null, $fixedRate);
|
||||||
@@ -73,16 +73,11 @@ final class RateService implements RateServiceInterface
|
|||||||
|
|
||||||
// user preferences => fallback if nothing else was configured
|
// user preferences => fallback if nothing else was configured
|
||||||
if (null === $hourlyRate) {
|
if (null === $hourlyRate) {
|
||||||
$hourlyRate = (float) $record->getUser()->getPreferenceValue(UserPreference::HOURLY_RATE, 0.00);
|
$hourlyRate = (float) $record->getUser()->getPreferenceValue(UserPreference::HOURLY_RATE, 0.00, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null === $internalRate) {
|
if (null === $internalRate) {
|
||||||
$internalRate = $record->getUser()->getPreferenceValue(UserPreference::INTERNAL_RATE, 0.00);
|
$internalRate = (float) $record->getUser()->getPreferenceValue(UserPreference::INTERNAL_RATE, $hourlyRate, false);
|
||||||
if (null === $internalRate) {
|
|
||||||
$internalRate = $hourlyRate;
|
|
||||||
} else {
|
|
||||||
$internalRate = (float) $internalRate;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$factor = 1.00;
|
$factor = 1.00;
|
||||||
|
|||||||
@@ -312,7 +312,6 @@ class TimesheetControllerTest extends APIControllerBaseTest
|
|||||||
$timesheet = new Timesheet();
|
$timesheet = new Timesheet();
|
||||||
$timesheet
|
$timesheet
|
||||||
->setHourlyRate(137.21)
|
->setHourlyRate(137.21)
|
||||||
->setInternalRate(64.96)
|
|
||||||
->setBegin($startDate)
|
->setBegin($startDate)
|
||||||
->setEnd($endDate)
|
->setEnd($endDate)
|
||||||
->setExported(true)
|
->setExported(true)
|
||||||
@@ -348,11 +347,11 @@ class TimesheetControllerTest extends APIControllerBaseTest
|
|||||||
'metaFields' => [],
|
'metaFields' => [],
|
||||||
'hourlyRate' => 137.21,
|
'hourlyRate' => 137.21,
|
||||||
'rate' => 1772.2958,
|
'rate' => 1772.2958,
|
||||||
'internalRate' => 0.0,
|
'internalRate' => 1772.2958,
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach ($expected as $key => $value) {
|
foreach ($expected as $key => $value) {
|
||||||
self::assertEquals($value, $result[$key]);
|
self::assertEquals($value, $result[$key], sprintf('Field %s has invalid value', $key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
namespace App\Tests\Entity;
|
namespace App\Tests\Entity;
|
||||||
|
|
||||||
use App\Entity\Tag;
|
use App\Entity\Tag;
|
||||||
use App\Entity\Timesheet;
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -40,20 +39,4 @@ class TagTest extends TestCase
|
|||||||
$sut->setColor('#fffccc');
|
$sut->setColor('#fffccc');
|
||||||
$this->assertEquals('#fffccc', $sut->getColor());
|
$this->assertEquals('#fffccc', $sut->getColor());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testWithTimesheet()
|
|
||||||
{
|
|
||||||
$sut = new Tag();
|
|
||||||
$timesheet = new Timesheet();
|
|
||||||
|
|
||||||
$this->assertEmpty($timesheet->getTags());
|
|
||||||
|
|
||||||
$sut->setName('bar');
|
|
||||||
$sut->addTimesheet($timesheet);
|
|
||||||
|
|
||||||
$this->assertSame($sut, $timesheet->getTags()[0]);
|
|
||||||
|
|
||||||
$sut->removeTimesheet($timesheet);
|
|
||||||
$this->assertEmpty($timesheet->getTags());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user