Added PDF for pregenerated PDF

This commit is contained in:
Torsten Schulz
2023-12-27 18:19:27 +01:00
parent 547e4bbb6f
commit 82a68012ae
746 changed files with 139205 additions and 3620 deletions

View File

@@ -42,14 +42,15 @@
"require": {
"php": "^7.1.8 || ^8.0",
"ext-json": "*",
"carbonphp/carbon-doctrine-types": "*",
"psr/clock": "^1.0",
"symfony/polyfill-mbstring": "^1.0",
"symfony/polyfill-php80": "^1.16",
"symfony/translation": "^3.4 || ^4.0 || ^5.0 || ^6.0"
},
"require-dev": {
"doctrine/dbal": "^2.0 || ^3.1.4",
"doctrine/orm": "^2.7",
"doctrine/dbal": "^2.0 || ^3.1.4 || ^4.0",
"doctrine/orm": "^2.7 || ^3.0",
"friendsofphp/php-cs-fixer": "^3.0",
"kylekatarnls/multi-tester": "^2.0",
"ondrejmirtes/better-reflection": "*",

View File

@@ -120,24 +120,37 @@ This project exists thanks to all the people who contribute.
Support this project by becoming a sponsor. Your logo will show up here with a link to your website.
<a href="https://tidelift.com/subscription/pkg/packagist-nesbot-carbon?utm_source=packagist-nesbot-carbon&utm_medium=referral&utm_campaign=readme" target="_blank"><img src="https://carbon.nesbot.com/tidelift-brand.png" width="256" height="64"></a><!-- <open-collective-sponsors> -->
<a title="#1 Guide To Online Gambling In Canada" href="https://casinohex.org/canada/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank" rel="sponsored"><img alt="CasinoHex Canada" src="https://opencollective-production.s3.us-west-1.amazonaws.com/79fdbcc0-a997-11eb-abbc-25e48b63c6dc.jpg" width="85" height="64"></a>
<a title="Casino-portugal.pt" href="https://casino-portugal.pt/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank" rel="sponsored"><img alt="Casino-portugal.pt" src="https://logo.clearbit.com/casino-portugal.pt" width="64" height="64"></a>
<a title="Slots City® ➢ Лучшее лицензионно казино онлайн и оффлайн на гривны в Украине. 【 Более1500 игровых автоматов и слотов】✅ Официально и Безопасно" href="https://slotscity.ua/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank" rel="sponsored"><img alt="Slots City" src="https://opencollective-production.s3.us-west-1.amazonaws.com/d7e298c0-7abe-11ed-8553-230872f5e54d.png" width="90" height="64"></a>
<a title="Znajdź najlepsze zakłady bukmacherskie w Polsce w 2023 roku. Probukmacher.pl to Twoje kompendium wiedzy na temat bukmacherów!" href="https://www.probukmacher.pl?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank" rel="sponsored"><img alt="Probukmacher" src="https://opencollective-production.s3.us-west-1.amazonaws.com/account-avatar/caf50271-4560-4ffe-a434-ea15239168db/Screenshot_1.png" width="89" height="64"></a>
<a title="Gives a fun for our users" href="https://slotoking.ua/games/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank" rel="sponsored"><img alt="Игровые автоматы" src="https://opencollective-production.s3.us-west-1.amazonaws.com/account-avatar/94601d07-3205-4c60-9c2d-9b8194dbefb7/skg-blue.png" width="64" height="64"></a>
<a title="inkedin" href="https://inkedin.com?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank" rel="sponsored"><img alt="inkedin" src="https://logo.clearbit.com/inkedin.com" width="64" height="64"></a>
<a title="Актуальний та повносправний рейтинг онлайн казино України, ґрунтований на відгуках реальних гравців." href="https://uk.onlinecasino.kyiv.ua/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank" rel="sponsored"><img alt="Онлайн казино України" src="https://opencollective-production.s3.us-west-1.amazonaws.com/c0b4b090-eef8-11ec-9cb7-0527a205b226.png" width="64" height="64"></a>
<a title="Chudovo - international software development company with representative offices in Kyiv, Cologne, New York, Tallinn and London. It has been working on the market since 2006. Company has domain expertise in video security, logistics, medicine, finance and" href="https://chudovo.com/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank" rel="sponsored"><img alt="Chudovo" src="https://opencollective-production.s3.us-west-1.amazonaws.com/326c19a0-2e87-11eb-a13a-c99a2a201d11.png" width="424" height="64"></a>
<a title="A self-hosted web radio management suite, including turnkey installer tools and an easy-to-use web app to manage your stations. " href="https://azuracast.com?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank" rel="sponsored"><img alt="AzuraCast" src="https://opencollective-production.s3.us-west-1.amazonaws.com/3c12ea10-cdfb-11eb-9cf4-3760b386b76d.png" width="64" height="64"></a>
<a title="Triplebyte is the first software engineering job platform that is on the developer&#039;s side. Take our coding quiz!" href="https://triplebyte.com/os/opencollective?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank" rel="sponsored"><img alt="Triplebyte" src="https://opencollective-production.s3.us-west-1.amazonaws.com/43e4f9d0-30cd-11ea-9c6b-e1142996e8b2.png" width="64" height="64"></a>
<a title="Connect your Collective to GitHub Sponsors: https://docs.opencollective.com/help/collectives/github-sponsors" href="https://github.com/sponsors/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank" rel="sponsored"><img alt="GitHub Sponsors" src="https://opencollective-production.s3.us-west-1.amazonaws.com/87b1d240-f617-11ea-9960-fd7e8ab20fe4.png" width="73" height="64"></a>
<a title="Salesforce" href="https://engineering.salesforce.com?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank" rel="sponsored"><img alt="Salesforce" src="https://opencollective-production.s3.us-west-1.amazonaws.com/24d34880-df8d-11e9-949c-6bc2037b6bd5.png" width="64" height="64"></a>
<a title="#1 Guide To Online Gambling In Canada" href="https://casinohex.org/canada/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="CasinoHex Canada" src="https://opencollective-production.s3.us-west-1.amazonaws.com/79fdbcc0-a997-11eb-abbc-25e48b63c6dc.jpg" width="85" height="64"></a>
<a title="Casino-portugal.pt" href="https://casino-portugal.pt/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Casino-portugal.pt" src="https://logo.clearbit.com/casino-portugal.pt" width="64" height="64"></a>
<a title="Znajdź najlepsze zakłady bukmacherskie w Polsce w 2023 roku. Probukmacher.pl to Twoje kompendium wiedzy na temat bukmacherów!" href="https://www.probukmacher.pl?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Probukmacher" src="https://opencollective-production.s3.us-west-1.amazonaws.com/account-avatar/caf50271-4560-4ffe-a434-ea15239168db/Screenshot_1.png" width="89" height="64"></a>
<a title="Gives a fun for our users" href="https://slotoking.ua/games/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Игровые автоматы" src="https://opencollective-production.s3.us-west-1.amazonaws.com/account-avatar/94601d07-3205-4c60-9c2d-9b8194dbefb7/skg-blue.png" width="64" height="64"></a>
<a title="Онлайн казино 777 Україна" href="https://777.ua/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Онлайн казино" src="https://opencollective-production.s3.us-west-1.amazonaws.com/account-avatar/7e572d50-1ce8-4d69-ae12-86cc80371373/ok-ua-777.png" width="64" height="64"></a>
<a title="Slots City® ➢ Лучшее лицензионно казино онлайн и оффлайн на гривны в Украине. 【 Более1500 игровых автоматов и слотов】✅ Официально и Безопасно" href="https://slotscity.ua/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Slots City" src="https://opencollective-production.s3.us-west-1.amazonaws.com/d7e298c0-7abe-11ed-8553-230872f5e54d.png" width="90" height="64"></a>
<a title="inkedin" href="https://inkedin.com?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="inkedin" src="https://logo.clearbit.com/inkedin.com" width="64" height="64"></a>
<a title="Актуальний та повносправний рейтинг онлайн казино України, ґрунтований на відгуках реальних гравців." href="https://uk.onlinecasino.in.ua/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Онлайн казино України" src="https://opencollective-production.s3.us-west-1.amazonaws.com/c0b4b090-eef8-11ec-9cb7-0527a205b226.png" width="64" height="64"></a>
<a title="OnlineCasinosSpelen" href="https://onlinecasinosspelen.com?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="OnlineCasinosSpelen" src="https://logo.clearbit.com/onlinecasinosspelen.com" width="64" height="64"></a>
<a title="Best non Gamstop sites in the UK" href="https://nongamstopcasinos.net/gb/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Best non Gamstop sites in the UK" src="https://opencollective-production.s3.us-west-1.amazonaws.com/account-avatar/34e340b8-e1de-4932-8a76-1b3ce2ec7ee8/logo_white%20bg%20(8).png" width="64" height="64"></a>
<a title="Real Money Pokies" href="https://www.nzfirst.org.nz/real-money-pokies/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Real Money Pokies" src="https://opencollective-production.s3.us-west-1.amazonaws.com/account-avatar/30d38232-a9d6-4e95-a48c-641fdc4d96fd/NZ_logo%20(6)%20(1)%20(1).jpg" width="64" height="64"></a>
<a title="Non GamStop Bookies UK" href="https://nongamstopbookies.com/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Non GamStop Bookies UK" src="https://opencollective-production.s3.us-west-1.amazonaws.com/account-avatar/43c5561c-8907-4ef7-a4ee-c6da054788b8/logo-site%20(3).jpg" width="64" height="64"></a>
<a title="Entertainment" href="https://www.nongamstopbets.com/casinos-not-on-gamstop/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Non-GamStop Bets UK" src="https://logo.clearbit.com/nongamstopbets.com" width="64" height="64"></a>
<a title="Chudovo - international software development company with representative offices in Kyiv, Cologne, New York, Tallinn and London. It has been working on the market since 2006. Company has domain expertise in video security, logistics, medicine, finance and" href="https://chudovo.com/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Chudovo" src="https://opencollective-production.s3.us-west-1.amazonaws.com/326c19a0-2e87-11eb-a13a-c99a2a201d11.png" width="84" height="42"></a>
<a title="Entertainment" href="https://casinogap.org/uk/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="UK Casino Gap" src="https://opencollective-production.s3.us-west-1.amazonaws.com/account-avatar/143f9301-beec-4118-89d5-9a07a01345f3/casinogap-uk.png" width="42" height="42"></a>
<a title="NZ Gaming Portal" href="https://casinodeps.co.nz?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="NZ Casino Deps" src="https://logo.clearbit.com/casinodeps.co.nz" width="42" height="42"></a>
<a title="NonStop Sites" href="https://uk.nonstopcasino.org/non-gamstop-casinos/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="NonStopCasino.org" src="https://opencollective-production.s3.us-west-1.amazonaws.com/account-avatar/fd7ad905-8752-468f-ad20-582a24cca9d9/non-stop-casino.png" width="42" height="42"></a>
<a title="Siti Non AAMS" href="https://www.outlookindia.com/outlook-spotlight/migliori-siti-non-aams-siti-scommesse-senza-licenza-sicuri-news-294715?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Migliori Siti Non AAMS" src="https://opencollective-production.s3.us-west-1.amazonaws.com/account-avatar/392810da-6cb6-4938-a3cb-38bd0e1eb7de/migliori-siti-non-aams.png" width="42" height="42"></a>
<a title="List of trusted non GamStop casino reviews" href="https://nongamstopcasinos.org?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="UK NonGamStopCasinos" src="https://opencollective-production.s3.us-west-1.amazonaws.com/account-avatar/cbda0ee1-26ea-4252-9580-f1f9b317b1f7/nongamstopcasinos-uk.png" width="42" height="42"></a>
<a title="Online TikTok Video Download Tool" href="https://snaptik.pro?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="SnapTik" src="https://opencollective-production.s3.us-west-1.amazonaws.com/account-avatar/546bcd53-6615-457d-ab21-1db1c52b3af5/logo.jpg" width="42" height="42"></a>
<a title="A self-hosted web radio management suite, including turnkey installer tools and an easy-to-use web app to manage your stations. " href="https://azuracast.com?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="AzuraCast" src="https://opencollective-production.s3.us-west-1.amazonaws.com/3c12ea10-cdfb-11eb-9cf4-3760b386b76d.png" width="42" height="42"></a>
<a title="Triplebyte is the first software engineering job platform that is on the developer&#039;s side. Take our coding quiz!" href="https://triplebyte.com/os/opencollective?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Triplebyte" src="https://opencollective-production.s3.us-west-1.amazonaws.com/43e4f9d0-30cd-11ea-9c6b-e1142996e8b2.png" width="42" height="42"></a>
<a title="Connect your Collective to GitHub Sponsors: https://docs.opencollective.com/help/collectives/github-sponsors" href="https://github.com/sponsors/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="GitHub Sponsors" src="https://opencollective-production.s3.us-west-1.amazonaws.com/87b1d240-f617-11ea-9960-fd7e8ab20fe4.png" width="48" height="42"></a>
<a title="Salesforce" href="https://engineering.salesforce.com?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img alt="Salesforce" src="https://opencollective-production.s3.us-west-1.amazonaws.com/24d34880-df8d-11e9-949c-6bc2037b6bd5.png" width="42" height="42"></a>
<!-- </open-collective-sponsors> -->
[[Become a sponsor via OpenCollective](https://opencollective.com/Carbon#sponsor)]
<a href="https://github.com/taylorotwell" target="_blank"><img src="https://avatars.githubusercontent.com/u/463230?s=128&v=4" width="64" height="64"></a>
<a href="https://github.com/usefathom" target="_blank"><img src="https://avatars.githubusercontent.com/u/38684088?s=128&v=4" width="64" height="64"></a>
<a href="https://github.com/codecov" target="_blank"><img src="https://avatars.githubusercontent.com/u/8226205?s=128&v=4" width="64" height="64"></a>
<a href="https://github.com/getsentry" target="_blank"><img src="https://avatars.githubusercontent.com/u/1396951?s=128&v=4" width="64" height="64"></a>
[[Become a sponsor via GitHub](https://github.com/sponsors/kylekatarnls)]

View File

@@ -13,19 +13,44 @@ use Carbon\CarbonImmutable;
require_once __DIR__.'/vendor/autoload.php';
function getMaxHistoryMonthsByAmount($amount): int
{
if ($amount >= 50) {
return 6;
}
if ($amount >= 20) {
return 4;
}
return 2;
}
function getOpenCollectiveSponsors(): string
{
$members = json_decode(file_get_contents('https://opencollective.com/carbon/members/all.json'), true);
$sixMonthsAgo = CarbonImmutable::parse('now - 6 months')->format('Y-m-d h:i');
$customSponsorImages = [
// For consistency and equity among sponsors, as of now, we kindly ask our sponsors
// to provide an image having a width/height ratio between 1/1 and 2/1.
// By default, we'll show the member picture from OpenCollective, and will resize it if bigger
// int(OpenCollective.MemberId) => ImageURL
];
$list = array_filter($members, static function ($member) use ($sixMonthsAgo) {
$members = json_decode(file_get_contents('https://opencollective.com/carbon/members/all.json'), true);
$list = array_filter($members, static function ($member): bool {
return ($member['lastTransactionAmount'] > 3 || $member['isActive']) &&
$member['role'] === 'BACKER' &&
$member['type'] !== 'USER' &&
($member['totalAmountDonated'] > 100 || $member['lastTransactionAt'] > $sixMonthsAgo || $member['isActive'] && $member['lastTransactionAmount'] >= 30);
(
$member['totalAmountDonated'] > 100 ||
$member['lastTransactionAt'] > CarbonImmutable::now()
->subMonthsNoOverflow(getMaxHistoryMonthsByAmount($member['lastTransactionAmount']))
->format('Y-m-d h:i') ||
$member['isActive'] && $member['lastTransactionAmount'] >= 30
);
});
$list = array_map(static function (array $member) {
$list = array_map(static function (array $member): array {
$createdAt = CarbonImmutable::parse($member['createdAt']);
$lastTransactionAt = CarbonImmutable::parse($member['lastTransactionAt']);
@@ -49,7 +74,7 @@ function getOpenCollectiveSponsors(): string
if ($monthlyContribution > 29) {
$status = 'sponsor';
} elseif ($monthlyContribution > 3 || $yearlyContribution > 20) {
} elseif ($monthlyContribution > 4.5 || $yearlyContribution > 29) {
$status = 'backer';
} elseif ($member['totalAmountDonated'] > 0) {
$status = 'helper';
@@ -63,24 +88,24 @@ function getOpenCollectiveSponsors(): string
]);
}, $list);
usort($list, static function (array $a, array $b) {
usort($list, static function (array $a, array $b): int {
return ($b['monthlyContribution'] <=> $a['monthlyContribution'])
?: ($b['totalAmountDonated'] <=> $a['totalAmountDonated']);
});
return implode('', array_map(static function (array $member) {
return implode('', array_map(static function (array $member) use ($customSponsorImages): string {
$href = htmlspecialchars($member['website'] ?? $member['profile']);
$src = $member['image'] ?? (strtr($member['profile'], ['https://opencollective.com/' => 'https://images.opencollective.com/']).'/avatar/256.png');
$src = $customSponsorImages[$member['MemberId'] ?? ''] ?? $member['image'] ?? (strtr($member['profile'], ['https://opencollective.com/' => 'https://images.opencollective.com/']).'/avatar/256.png');
[$x, $y] = @getimagesize($src) ?: [0, 0];
$validImage = ($x && $y);
$src = $validImage ? htmlspecialchars($src) : 'https://opencollective.com/static/images/default-guest-logo.svg';
$height = 64;
$width = $validImage ? round($x * $height / $y) : $height;
$height = $member['status'] === 'sponsor' ? 64 : 42;
$width = min($height * 2, $validImage ? round($x * $height / $y) : $height);
$href .= (strpos($href, '?') === false ? '?' : '&amp;').'utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon';
$title = htmlspecialchars(($member['description'] ?? null) ?: $member['name']);
$alt = htmlspecialchars($member['name']);
return "\n".'<a title="'.$title.'" href="'.$href.'" target="_blank" rel="sponsored">'.
return "\n".'<a title="'.$title.'" href="'.$href.'" target="_blank">'.
'<img alt="'.$alt.'" src="'.$src.'" width="'.$width.'" height="'.$height.'">'.
'</a>';
}, $list))."\n";
@@ -88,7 +113,7 @@ function getOpenCollectiveSponsors(): string
file_put_contents('readme.md', preg_replace_callback(
'/(<!-- <open-collective-sponsors> -->)[\s\S]+(<!-- <\/open-collective-sponsors> -->)/',
static function (array $match) {
static function (array $match): string {
return $match[1].getOpenCollectiveSponsors().$match[2];
},
file_get_contents('readme.md')

View File

@@ -5125,8 +5125,7 @@ interface CarbonInterface extends DateTimeInterface, JsonSerializable
* @param DateTimeInterface|Closure|static|string|false|null $testNow real or mock Carbon instance
* @param Closure(): T $callback
*
* @return mixed
* @phpstan-return T
* @return T
*/
public static function withTestNow($testNow, $callback);

View File

@@ -238,6 +238,13 @@ class CarbonPeriod implements Iterator, Countable, JsonSerializable
*/
public const END_MAX_ATTEMPTS = 10000;
/**
* Default date class of iteration items.
*
* @var string
*/
protected const DEFAULT_DATE_CLASS = Carbon::class;
/**
* The registered macros.
*
@@ -497,15 +504,16 @@ class CarbonPeriod implements Iterator, Countable, JsonSerializable
$interval = null;
$start = null;
$end = null;
$dateClass = static::DEFAULT_DATE_CLASS;
foreach (explode('/', $iso) as $key => $part) {
if ($key === 0 && preg_match('/^R(\d*|INF)$/', $part, $match)) {
$parsed = \strlen($match[1]) ? (($match[1] !== 'INF') ? (int) $match[1] : INF) : null;
} elseif ($interval === null && $parsed = CarbonInterval::make($part)) {
$interval = $part;
} elseif ($start === null && $parsed = Carbon::make($part)) {
} elseif ($start === null && $parsed = $dateClass::make($part)) {
$start = $part;
} elseif ($end === null && $parsed = Carbon::make(static::addMissingParts($start ?? '', $part))) {
} elseif ($end === null && $parsed = $dateClass::make(static::addMissingParts($start ?? '', $part))) {
$end = $part;
} else {
throw new InvalidPeriodParameterException("Invalid ISO 8601 specification: $iso.");
@@ -701,7 +709,8 @@ class CarbonPeriod implements Iterator, Countable, JsonSerializable
}
if ($this->startDate === null) {
$this->setStartDate(Carbon::now());
$dateClass = $this->dateClass;
$this->setStartDate($dateClass::now());
}
if ($this->dateInterval === null) {
@@ -1826,7 +1835,9 @@ class CarbonPeriod implements Iterator, Countable, JsonSerializable
)(...$parameters));
}
if ($this->localStrictModeEnabled ?? Carbon::isStrictModeEnabled()) {
$dateClass = $this->dateClass;
if ($this->localStrictModeEnabled ?? $dateClass::isStrictModeEnabled()) {
throw new UnknownMethodException($method);
}
@@ -2685,7 +2696,9 @@ class CarbonPeriod implements Iterator, Countable, JsonSerializable
!preg_match('/^R\d/', $value) &&
preg_match('/[a-z\d]/i', $value)
) {
return Carbon::parse($value, $this->tzName);
$dateClass = $this->dateClass;
return $dateClass::parse($value, $this->tzName);
}
}

View File

@@ -13,6 +13,13 @@ namespace Carbon;
class CarbonPeriodImmutable extends CarbonPeriod
{
/**
* Default date class of iteration items.
*
* @var string
*/
protected const DEFAULT_DATE_CLASS = CarbonImmutable::class;
/**
* Date class of iteration items.
*

View File

@@ -1,23 +0,0 @@
<?php
/**
* This file is part of the Carbon package.
*
* (c) Brian Nesbitt <brian@nesbot.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Carbon\Doctrine;
use Doctrine\DBAL\Platforms\AbstractPlatform;
interface CarbonDoctrineType
{
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform);
public function convertToPHPValue($value, AbstractPlatform $platform);
public function convertToDatabaseValue($value, AbstractPlatform $platform);
}

View File

@@ -1,37 +0,0 @@
<?php
/**
* This file is part of the Carbon package.
*
* (c) Brian Nesbitt <brian@nesbot.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Carbon\Doctrine;
use Doctrine\DBAL\Platforms\AbstractPlatform;
class CarbonImmutableType extends DateTimeImmutableType implements CarbonDoctrineType
{
/**
* {@inheritdoc}
*
* @return string
*/
public function getName()
{
return 'carbon_immutable';
}
/**
* {@inheritdoc}
*
* @return bool
*/
public function requiresSQLCommentHint(AbstractPlatform $platform)
{
return true;
}
}

View File

@@ -1,37 +0,0 @@
<?php
/**
* This file is part of the Carbon package.
*
* (c) Brian Nesbitt <brian@nesbot.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Carbon\Doctrine;
use Doctrine\DBAL\Platforms\AbstractPlatform;
class CarbonType extends DateTimeType implements CarbonDoctrineType
{
/**
* {@inheritdoc}
*
* @return string
*/
public function getName()
{
return 'carbon';
}
/**
* {@inheritdoc}
*
* @return bool
*/
public function requiresSQLCommentHint(AbstractPlatform $platform)
{
return true;
}
}

View File

@@ -1,123 +0,0 @@
<?php
/**
* This file is part of the Carbon package.
*
* (c) Brian Nesbitt <brian@nesbot.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Carbon\Doctrine;
use Carbon\Carbon;
use Carbon\CarbonInterface;
use DateTimeInterface;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\ConversionException;
use Exception;
/**
* @template T of CarbonInterface
*/
trait CarbonTypeConverter
{
/**
* @return class-string<T>
*/
protected function getCarbonClassName(): string
{
return Carbon::class;
}
/**
* @return string
*/
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
{
$precision = $fieldDeclaration['precision'] ?: 10;
if ($fieldDeclaration['secondPrecision'] ?? false) {
$precision = 0;
}
if ($precision === 10) {
$precision = DateTimeDefaultPrecision::get();
}
$type = parent::getSQLDeclaration($fieldDeclaration, $platform);
if (!$precision) {
return $type;
}
if (str_contains($type, '(')) {
return preg_replace('/\(\d+\)/', "($precision)", $type);
}
[$before, $after] = explode(' ', "$type ");
return trim("$before($precision) $after");
}
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*
* @return T|null
*/
public function convertToPHPValue($value, AbstractPlatform $platform)
{
$class = $this->getCarbonClassName();
if ($value === null || is_a($value, $class)) {
return $value;
}
if ($value instanceof DateTimeInterface) {
return $class::instance($value);
}
$date = null;
$error = null;
try {
$date = $class::parse($value);
} catch (Exception $exception) {
$error = $exception;
}
if (!$date) {
throw ConversionException::conversionFailedFormat(
$value,
$this->getName(),
'Y-m-d H:i:s.u or any format supported by '.$class.'::parse()',
$error
);
}
return $date;
}
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*
* @return string|null
*/
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
if ($value === null) {
return $value;
}
if ($value instanceof DateTimeInterface) {
return $value->format('Y-m-d H:i:s.u');
}
throw ConversionException::conversionFailedInvalidType(
$value,
$this->getName(),
['null', 'DateTime', 'Carbon']
);
}
}

View File

@@ -1,37 +0,0 @@
<?php
/**
* This file is part of the Carbon package.
*
* (c) Brian Nesbitt <brian@nesbot.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Carbon\Doctrine;
class DateTimeDefaultPrecision
{
private static $precision = 6;
/**
* Change the default Doctrine datetime and datetime_immutable precision.
*
* @param int $precision
*/
public static function set(int $precision): void
{
self::$precision = $precision;
}
/**
* Get the default Doctrine datetime and datetime_immutable precision.
*
* @return int
*/
public static function get(): int
{
return self::$precision;
}
}

View File

@@ -1,24 +0,0 @@
<?php
/**
* Thanks to https://github.com/flaushi for his suggestion:
* https://github.com/doctrine/dbal/issues/2873#issuecomment-534956358
*/
namespace Carbon\Doctrine;
use Carbon\CarbonImmutable;
use Doctrine\DBAL\Types\VarDateTimeImmutableType;
class DateTimeImmutableType extends VarDateTimeImmutableType implements CarbonDoctrineType
{
/** @use CarbonTypeConverter<CarbonImmutable> */
use CarbonTypeConverter;
/**
* @return class-string<CarbonImmutable>
*/
protected function getCarbonClassName(): string
{
return CarbonImmutable::class;
}
}

View File

@@ -1,16 +0,0 @@
<?php
/**
* Thanks to https://github.com/flaushi for his suggestion:
* https://github.com/doctrine/dbal/issues/2873#issuecomment-534956358
*/
namespace Carbon\Doctrine;
use Carbon\Carbon;
use Doctrine\DBAL\Types\VarDateTimeType;
class DateTimeType extends VarDateTimeType implements CarbonDoctrineType
{
/** @use CarbonTypeConverter<Carbon> */
use CarbonTypeConverter;
}

View File

@@ -33,33 +33,87 @@
* - Marek Adamický
* - AlterwebStudio
*/
use Carbon\CarbonInterface;
$fromNow = function ($time) {
return 'o '.strtr($time, [
'hodina' => 'hodinu',
'minúta' => 'minútu',
'sekunda' => 'sekundu',
]);
};
$ago = function ($time) {
$replacements = [
'/\bhodina\b/' => 'hodinou',
'/\bminúta\b/' => 'minútou',
'/\bsekunda\b/' => 'sekundou',
'/\bdeň\b/u' => 'dňom',
'/\btýždeň\b/u' => 'týždňom',
'/\bmesiac\b/' => 'mesiacom',
'/\brok\b/' => 'rokom',
];
$replacementsPlural = [
'/\bhodiny\b/' => 'hodinami',
'/\bminúty\b/' => 'minútami',
'/\bsekundy\b/' => 'sekundami',
'/\bdni\b/' => 'dňami',
'/\btýždne\b/' => 'týždňami',
'/\bmesiace\b/' => 'mesiacmi',
'/\broky\b/' => 'rokmi',
];
foreach ($replacements + $replacementsPlural as $pattern => $replacement) {
$time = preg_replace($pattern, $replacement, $time);
}
return "pred $time";
};
return [
'year' => 'rok|:count roky|:count rokov',
'year' => ':count rok|:count roky|:count rokov',
'a_year' => 'rok|:count roky|:count rokov',
'y' => ':count r',
'month' => 'mesiac|:count mesiace|:count mesiacov',
'month' => ':count mesiac|:count mesiace|:count mesiacov',
'a_month' => 'mesiac|:count mesiace|:count mesiacov',
'm' => ':count m',
'week' => 'týždeň|:count týždne|:count týždňov',
'week' => ':count týždeň|:count týždne|:count týždňov',
'a_week' => 'týždeň|:count týždne|:count týždňov',
'w' => ':count t',
'day' => 'deň|:count dni|:count dní',
'day' => ':count deň|:count dni|:count dní',
'a_day' => 'deň|:count dni|:count dní',
'd' => ':count d',
'hour' => 'hodinu|:count hodiny|:count hodín',
'hour' => ':count hodina|:count hodiny|:count hodín',
'a_hour' => 'hodina|:count hodiny|:count hodín',
'h' => ':count h',
'minute' => 'minútu|:count minúty|:count minút',
'minute' => ':count minúta|:count minúty|:count minút',
'a_minute' => 'minúta|:count minúty|:count minút',
'min' => ':count min',
'second' => 'sekundu|:count sekundy|:count sekúnd',
'a_second' => 'pár sekúnd|:count sekundy|:count sekúnd',
'second' => ':count sekunda|:count sekundy|:count sekúnd',
'a_second' => 'sekunda|:count sekundy|:count sekúnd',
's' => ':count s',
'ago' => 'pred :time',
'from_now' => 'o :time',
'after' => ':time po',
'millisecond' => ':count milisekunda|:count milisekundy|:count milisekúnd',
'a_millisecond' => 'milisekunda|:count milisekundy|:count milisekúnd',
'ms' => ':count ms',
'microsecond' => ':count mikrosekunda|:count mikrosekundy|:count mikrosekúnd',
'a_microsecond' => 'mikrosekunda|:count mikrosekundy|:count mikrosekúnd',
'µs' => ':count µs',
'ago' => $ago,
'from_now' => $fromNow,
'before' => ':time pred',
'year_ago' => 'rokom|:count rokmi|:count rokmi',
'month_ago' => 'mesiacom|:count mesiacmi|:count mesiacmi',
'week_ago' => 'týždňom|:count týždňami|:count týždňami',
'day_ago' => 'dňom|:count dňami|:count dňami',
'hour_ago' => 'hodinou|:count hodinami|:count hodinami',
'minute_ago' => 'minútou|:count minútami|:count minútami',
'second_ago' => 'sekundou|:count sekundami|:count sekundami',
'after' => ':time po',
'hour_after' => ':count hodinu|:count hodiny|:count hodín',
'minute_after' => ':count minútu|:count minúty|:count minút',
'second_after' => ':count sekundu|:count sekundy|:count sekúnd',
'hour_before' => ':count hodinu|:count hodiny|:count hodín',
'minute_before' => ':count minútu|:count minúty|:count minút',
'second_before' => ':count sekundu|:count sekundy|:count sekúnd',
'first_day_of_week' => 1,
'day_of_first_week_of_year' => 4,
'list' => [', ', ' a '],
@@ -74,6 +128,24 @@ return [
'LLL' => 'D. M. HH:mm',
'LLLL' => 'dddd D. MMMM YYYY HH:mm',
],
'calendar' => [
'sameDay' => '[dnes o] LT',
'nextDay' => '[zajtra o] LT',
'lastDay' => '[včera o] LT',
'nextWeek' => 'dddd [o] LT',
'lastWeek' => static function (CarbonInterface $date) {
switch ($date->dayOfWeek) {
case 1:
case 2:
case 4:
case 5:
return '[minulý] dddd [o] LT'; //pondelok/utorok/štvrtok/piatok
default:
return '[minulá] dddd [o] LT';
}
},
'sameElse' => 'L',
],
'weekdays' => ['nedeľa', 'pondelok', 'utorok', 'streda', 'štvrtok', 'piatok', 'sobota'],
'weekdays_short' => ['ned', 'pod', 'uto', 'str', 'štv', 'pia', 'sob'],
'weekdays_min' => ['ne', 'po', 'ut', 'st', 'št', 'pi', 'so'],

View File

@@ -70,11 +70,9 @@ abstract class AbstractMacro implements BuiltinMethodReflection
/**
* Macro constructor.
*
* @param string $className
* @phpstan-param class-string $className
*
* @param string $methodName
* @param callable $macro
* @param class-string $className
* @param string $methodName
* @param callable $macro
*/
public function __construct(string $className, string $methodName, $macro)
{

View File

@@ -36,10 +36,8 @@ final class MacroScanner
/**
* Return true if the given pair class-method is a Carbon macro.
*
* @param string $className
* @phpstan-param class-string $className
*
* @param string $methodName
* @param class-string $className
* @param string $methodName
*
* @return bool
*/
@@ -61,10 +59,8 @@ final class MacroScanner
/**
* Return the Macro for a given pair class-method.
*
* @param string $className
* @phpstan-param class-string $className
*
* @param string $methodName
* @param class-string $className
* @param string $methodName
*
* @throws ReflectionException
*

View File

@@ -57,7 +57,6 @@ trait Rounding
'microsecond' => [0, 999999],
]);
$factor = 1;
$initialMonth = $this->month;
if ($normalizedUnit === 'week') {
$normalizedUnit = 'day';
@@ -130,16 +129,13 @@ trait Rounding
$normalizedValue = floor($function(($value - $minimum) / $precision) * $precision + $minimum);
/** @var CarbonInterface $result */
$result = $this->$normalizedUnit($normalizedValue);
$result = $this;
foreach ($changes as $unit => $value) {
$result = $result->$unit($value);
}
return $normalizedUnit === 'month' && $precision <= 1 && abs($result->month - $initialMonth) === 2
// Re-run the change in case an overflow occurred
? $result->$normalizedUnit($normalizedValue)
: $result;
return $result->$normalizedUnit($normalizedValue);
}
/**

View File

@@ -124,8 +124,7 @@ trait Test
* @param DateTimeInterface|Closure|static|string|false|null $testNow real or mock Carbon instance
* @param Closure(): T $callback
*
* @return mixed
* @phpstan-return T
* @return T
*/
public static function withTestNow($testNow, $callback)
{

View File

@@ -66,7 +66,7 @@ class TranslatorImmutable extends Translator
/**
* @codeCoverageIgnore
*/
public function setConfigCacheFactory(ConfigCacheFactoryInterface $configCacheFactory)
public function setConfigCacheFactory(ConfigCacheFactoryInterface $configCacheFactory): void
{
$this->disallowMutation(__METHOD__);