fix php 8.1 deprecations (#3648)
* show session maxlifetime in doctor * rephrase compatibility in release notes * bump version
This commit is contained in:
@@ -17,11 +17,11 @@ class Constants
|
||||
/**
|
||||
* The current release version
|
||||
*/
|
||||
public const VERSION = '1.29.0';
|
||||
public const VERSION = '1.29.1';
|
||||
/**
|
||||
* The current release: major * 10000 + minor * 100 + patch
|
||||
*/
|
||||
public const VERSION_ID = 12900;
|
||||
public const VERSION_ID = 12901;
|
||||
/**
|
||||
* The current release status, either "stable" or "dev"
|
||||
*/
|
||||
|
||||
@@ -268,6 +268,7 @@ class DoctorController extends AbstractController
|
||||
'post_max_size',
|
||||
'sys_temp_dir',
|
||||
'date.timezone',
|
||||
'session.gc_maxlifetime',
|
||||
];
|
||||
|
||||
$settings = [];
|
||||
|
||||
@@ -35,7 +35,12 @@ final class InvoiceDocument
|
||||
|
||||
public function getFilename(): string
|
||||
{
|
||||
return $this->file->getRealPath();
|
||||
$path = $this->file->getRealPath();
|
||||
if ($path === false) {
|
||||
throw new \Exception('Invoice template got deleted from filesystem');
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
public function getFileExtension(): string
|
||||
@@ -45,6 +50,11 @@ final class InvoiceDocument
|
||||
|
||||
public function getLastChange(): int
|
||||
{
|
||||
return $this->file->getMTime();
|
||||
$modified = $this->file->getMTime();
|
||||
if ($modified === false) {
|
||||
throw new \Exception('Invoice template got deleted from filesystem');
|
||||
}
|
||||
|
||||
return $modified;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,8 @@ class RedirectToLocaleSubscriber implements EventSubscriberInterface
|
||||
|
||||
// Ignore requests from referrers with the same HTTP host in order to prevent
|
||||
// changing language for users who possibly already selected it for this application.
|
||||
if (0 === stripos($request->headers->get('referer'), $request->getSchemeAndHttpHost())) {
|
||||
$referer = $request->headers->get('referer');
|
||||
if ($referer !== null && 0 === stripos($referer, $request->getSchemeAndHttpHost())) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,9 @@ abstract class AbstractSpreadsheetRenderer extends AbstractRenderer
|
||||
foreach ($row->getCellIterator() as $cell) {
|
||||
$value = $cell->getValue();
|
||||
$replacer = null;
|
||||
if ($value === null) {
|
||||
continue;
|
||||
}
|
||||
$firstReplacerPos = stripos($value, '${');
|
||||
if ($firstReplacerPos === false) {
|
||||
continue;
|
||||
@@ -134,7 +137,7 @@ abstract class AbstractSpreadsheetRenderer extends AbstractRenderer
|
||||
$cellCounter = 0;
|
||||
foreach ($row->getCellIterator() as $cell) {
|
||||
$value = $cell->getValue();
|
||||
if (stripos($value, '${entry.') !== false) {
|
||||
if ($value !== null && stripos($value, '${entry.') !== false) {
|
||||
$startRow = $row->getRowIndex();
|
||||
$worksheet->insertNewRowBefore($startRow + 1, $invoiceItemCount - 1);
|
||||
break 2;
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace App\Invoice;
|
||||
|
||||
use App\Configuration\LanguageFormattings;
|
||||
use App\Constants;
|
||||
use App\Entity\Customer;
|
||||
use App\Entity\Invoice;
|
||||
use App\Entity\InvoiceDocument;
|
||||
use App\Event\InvoiceCreatedEvent;
|
||||
@@ -580,7 +581,22 @@ final class ServiceInvoice
|
||||
}
|
||||
|
||||
uasort($customerEntries, function ($a, $b) {
|
||||
return strcmp($a['customer']->getName(), $b['customer']->getName());
|
||||
$customerA = $a['customer'] ?? null;
|
||||
$customerB = $b['customer'] ?? null;
|
||||
$nameA = ($customerA instanceof Customer) ? $customerA->getName() : null;
|
||||
$nameB = ($customerB instanceof Customer) ? $customerB->getName() : null;
|
||||
|
||||
if ($nameA === null && $nameB === null) {
|
||||
$result = 0;
|
||||
} elseif ($nameA === null && $nameB !== null) {
|
||||
$result = 1;
|
||||
} elseif ($nameA !== null && $nameB === null) {
|
||||
$result = -1;
|
||||
} else {
|
||||
$result = strcmp($nameA, $nameB);
|
||||
}
|
||||
|
||||
return $result;
|
||||
});
|
||||
|
||||
foreach ($customerEntries as $id => $settings) {
|
||||
|
||||
@@ -296,6 +296,7 @@ class TimesheetCountedStatistic implements \JsonSerializable
|
||||
$this->recordRateExported = $recordRate;
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return [
|
||||
|
||||
@@ -45,33 +45,45 @@ final class LocaleHelper
|
||||
/**
|
||||
* Transforms seconds into a decimal formatted duration string.
|
||||
*
|
||||
* @param int $seconds
|
||||
* @param int|null $seconds
|
||||
* @return string
|
||||
*/
|
||||
public function durationDecimal(int $seconds)
|
||||
public function durationDecimal(?int $seconds): string
|
||||
{
|
||||
if ($seconds === null) {
|
||||
$seconds = 0;
|
||||
}
|
||||
|
||||
$value = round($seconds / 3600, 2);
|
||||
|
||||
return $this->getDurationFormatter()->format((float) $value);
|
||||
return $this->getDurationFormatter()->format($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Only used in twig filter |amount and invoice templates
|
||||
*
|
||||
* @param string|float $amount
|
||||
* @param string|float|null $amount
|
||||
* @return bool|false|string
|
||||
*/
|
||||
public function amount($amount)
|
||||
{
|
||||
if ($amount === null) {
|
||||
$amount = 0.00;
|
||||
}
|
||||
|
||||
return $this->getNumberFormatter()->format($amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $currency
|
||||
* @param string|null $currency
|
||||
* @return string
|
||||
*/
|
||||
public function currency($currency)
|
||||
public function currency(?string $currency)
|
||||
{
|
||||
if ($currency === null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
try {
|
||||
return Currencies::getSymbol(strtoupper($currency), $this->locale);
|
||||
} catch (\Exception $ex) {
|
||||
@@ -109,7 +121,7 @@ final class LocaleHelper
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|float $amount
|
||||
* @param int|float|null $amount
|
||||
* @param string|null $currency
|
||||
* @param bool $withCurrency
|
||||
* @return string
|
||||
@@ -120,6 +132,10 @@ final class LocaleHelper
|
||||
$withCurrency = false;
|
||||
}
|
||||
|
||||
if ($amount === null) {
|
||||
$amount = 0;
|
||||
}
|
||||
|
||||
if (false === $withCurrency) {
|
||||
return $this->getMoneyFormatter($withCurrency)->format($amount, NumberFormatter::TYPE_DEFAULT);
|
||||
}
|
||||
|
||||
@@ -25,12 +25,20 @@ class DateTimeFormatValidator extends ConstraintValidator
|
||||
throw new UnexpectedTypeException($constraint, __NAMESPACE__ . '\DateTimeFormat');
|
||||
}
|
||||
|
||||
if ($value === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$valid = true;
|
||||
|
||||
try {
|
||||
$test = new \DateTime($value);
|
||||
} catch (\Exception $ex) {
|
||||
if (!\is_string($value)) {
|
||||
$valid = false;
|
||||
} else {
|
||||
try {
|
||||
$test = new \DateTime($value);
|
||||
} catch (\Exception $ex) {
|
||||
$valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (false === $valid) {
|
||||
|
||||
Reference in New Issue
Block a user