Merge pull request #476 from doctrine/php-8

Base update to PHP 8.2
This commit is contained in:
Grégoire Paris
2023-08-23 22:40:04 +02:00
committed by GitHub
178 changed files with 2783 additions and 3600 deletions

View File

@@ -4,7 +4,7 @@ on: ["push", "pull_request"]
env:
doctrine_website_github_http_token: "${{ github.token }}"
PHP_VERSION: "7.4"
PHP_VERSION: "8.2"
doctrine_website_mysql_password: "${{ secrets.doctrine_website_mysql_password }}"
doctrine_website_algolia_admin_api_key: "no-key-needed"
@@ -32,7 +32,7 @@ jobs:
coverage: "none"
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v1"
uses: "ramsey/composer-install@v2"
with:
composer-options: "--prefer-dist --no-progress --no-suggest"

View File

@@ -46,10 +46,10 @@ jobs:
- name: "Setup PHP Action"
uses: "shivammathur/setup-php@v2"
with:
php-version: "7.4"
php-version: "8.2"
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v1"
uses: "ramsey/composer-install@v2"
with:
composer-options: "--no-progress --no-suggest --no-dev"

19
.gitignore vendored
View File

@@ -1,14 +1,15 @@
/.phpcs-cache
/.phpunit.result.cache
/.webpack-build
/build-*
/config/local.yml
/vendor
/docs
/node_modules
/projects
/source/api
/source/projects/doctrine-*
/source/projects/doctrine1
/source/api
/tests/Docs/resources/projects
/tests/Docs/resources/docs
/tests/Docs/resources/projects
/tests/Docs/resources/source
/docs
/.phpcs-cache
/build-*
/projects
/node_modules
/.webpack-build
/vendor

View File

@@ -11,50 +11,52 @@
}
],
"require": {
"php": "^7.4",
"algolia/algoliasearch-client-php": "^1.27",
"doctrine/inflector": "^1.4",
"doctrine/migrations": "^2.2",
"doctrine/orm": "^2.7",
"doctrine/rst-parser": "^0.1",
"doctrine/skeleton-mapper": "^1.0",
"doctrine/static-website-generator": "^1.0",
"php": "^8.2",
"algolia/algoliasearch-client-php": "^3.3",
"doctrine/inflector": "^2.0",
"doctrine/migrations": "^3.5",
"doctrine/orm": "^2.14",
"doctrine/rst-parser": "^0.5",
"doctrine/skeleton-mapper": "^2.0",
"doctrine/static-website-generator": "^2.0",
"erusev/parsedown": "^1.7",
"knplabs/github-api": "^2.14",
"pelago/emogrifier": "^3.1",
"php-http/guzzle6-adapter": "^1.1",
"scrivo/highlight.php": "^9.14",
"sendgrid/sendgrid": "^7.3",
"stripe/stripe-php": "^6.34",
"symfony/config": "^4.4",
"symfony/cache": "^5.4",
"symfony/console": "^4.4",
"symfony/dependency-injection": "^4.4",
"symfony/filesystem": "^4.4",
"symfony/finder": "^4.4",
"symfony/process": "^4.4",
"symfony/yaml": "^4.4",
"twig/twig": "^2.5"
"knplabs/github-api": "^3.9",
"pelago/emogrifier": "^7.0",
"php-http/guzzle7-adapter": "^1.0",
"scrivo/highlight.php": "^9.18",
"sendgrid/sendgrid": "^8.0",
"stripe/stripe-php": "^10.4",
"symfony/config": "^6.3",
"symfony/cache": "^6.3",
"symfony/console": "^6.3",
"symfony/dependency-injection": "^6.3",
"symfony/filesystem": "^6.3",
"symfony/finder": "^6.3",
"symfony/process": "^6.3",
"symfony/yaml": "^6.3",
"twig/twig": "^3.7"
},
"require-dev": {
"doctrine/coding-standard": "^12.0",
"mikey179/vfsstream": "^1.6",
"nunomaduro/mock-final-classes": "^1.1",
"phpstan/phpstan": "^1.10",
"phpstan/phpstan-deprecation-rules": "^1.1",
"phpstan/phpstan-phpunit": "^1.2",
"phpstan/phpstan-strict-rules": "^1.4",
"phpunit/phpunit": "^9.5",
"symfony/css-selector": "^4.4",
"symfony/dom-crawler": "^4.4",
"symfony/error-handler": "^4.4",
"symfony/var-dumper": "^4.4"
"symfony/css-selector": "^6.3",
"symfony/dom-crawler": "^6.3",
"symfony/error-handler": "^6.3",
"symfony/var-dumper": "^6.3"
},
"config": {
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true
"dealerdirect/phpcodesniffer-composer-installer": true,
"php-http/discovery": true
},
"platform": {
"php": "7.4.33"
"php": "8.2.8"
},
"sort-packages": true
},

3297
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -3,6 +3,11 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd">
<imports>
<import resource="services/static-website-generator.xml"/>
<import resource="services/rst-parser.xml"/>
</imports>
<parameters>
<parameter key="doctrine.website.mysql.user">root</parameter>
<parameter key="doctrine.website.mysql.host">localhost</parameter>
@@ -19,51 +24,13 @@
<bind key="$sourceDir">%doctrine.website.source_dir%</bind>
<bind key="$projectsData">%doctrine.website.projects_data%</bind>
<bind key="$webpackBuildDir">%doctrine.website.webpack_build_dir%</bind>
<bind key="$templatesDir">%doctrine.website.templates_dir%</bind>
<bind key="$projectIntegrationTypes">%doctrine.website.project_integration.types%</bind>
<bind key="$routes">%doctrine.website.routes%</bind>
<bind key="$stripePublishableKey">%doctrine.website.stripe.publishable_key%</bind>
</defaults>
<prototype namespace="Doctrine\Website\" resource="../lib/*" />
<prototype namespace="Doctrine\StaticWebsiteGenerator\" resource="../vendor/doctrine/static-website-generator/lib/*" />
<service id="Doctrine\StaticWebsiteGenerator\SourceFile\Converters\MarkdownConverter">
<argument type="service" id="Parsedown" />
</service>
<service id="Doctrine\StaticWebsiteGenerator\SourceFile\Converters\ReStructuredTextConverter">
<argument type="service" id="Doctrine\RST\Parser" />
</service>
<service id="Doctrine\StaticWebsiteGenerator\SourceFile\SourceFileBuilder">
<argument type="service" id="Doctrine\StaticWebsiteGenerator\SourceFile\SourceFileRenderer" />
<argument type="service" id="Symfony\Component\Filesystem\Filesystem" />
<argument type="collection">
<argument type="service" id="Doctrine\StaticWebsiteGenerator\SourceFile\Converters\MarkdownConverter" />
<argument type="service" id="Doctrine\StaticWebsiteGenerator\SourceFile\Converters\ReStructuredTextConverter" />
</argument>
<argument type="collection">
<argument>/\/api\//</argument>
</argument>
</service>
<service id="Doctrine\StaticWebsiteGenerator\Twig\StringTwigRenderer" autowire="false">
<argument>%doctrine.website.templates_dir%</argument>
<argument type="collection">
<argument type="service" id="Doctrine\Website\Twig\MainExtension" />
<argument type="service" id="Doctrine\Website\Twig\ProjectExtension" />
<argument type="service" id="Doctrine\StaticWebsiteGenerator\Twig\RoutingExtension" />
</argument>
</service>
<service id="Pelago\Emogrifier">
<call method="disableStyleBlocksParsing" />
</service>
<service id="Doctrine\Website\Email\RenderEmail" autowire="false">
<argument type="service" id="Pelago\Emogrifier" />
<argument>%doctrine.website.templates_dir%</argument>
<argument type="collection">
<argument type="service" id="Doctrine\Website\Twig\MainExtension" />
@@ -72,47 +39,12 @@
</argument>
</service>
<service id="Doctrine\StaticWebsiteGenerator\Twig\TwigRenderer" alias="Doctrine\StaticWebsiteGenerator\Twig\StringTwigRenderer" />
<service id="Doctrine\Website\Github\GithubProjectContributors" alias="Doctrine\Website\Github\ProdGithubProjectContributors" />
<service id="Doctrine\Website\Application" autowire="true" public="true" />
<service id="Doctrine\Website\Projects\ProjectDataRepository" autowire="true" />
<service id="Doctrine\RST\Configuration">
<call method="abortOnError">
<argument>false</argument>
</call>
<call method="setIgnoreInvalidReferences">
<argument>true</argument>
</call>
<call method="setUseCachedMetas">
<argument>false</argument>
</call>
<call method="setFileExtension">
<argument>html</argument>
</call>
<call method="setEventManager">
<argument type="service" id="Doctrine\Common\EventManager" />
</call>
</service>
<service id="Doctrine\RST\Builder">
<argument type="service" id="Doctrine\RST\Kernel" />
</service>
<service id="Doctrine\RST\Parser">
<argument type="service" id="Doctrine\RST\Kernel" />
</service>
<service id="Doctrine\StaticWebsiteGenerator\SourceFile\SourceFileRepository">
<argument type="collection">
<argument type="service" id="Doctrine\StaticWebsiteGenerator\SourceFile\SourceFileFilesystemReader" />
<argument type="service" id="Doctrine\StaticWebsiteGenerator\SourceFile\SourceFileRouteReader" />
</argument>
</service>
<service id="Doctrine\Website\Github\GithubClientProvider">
<argument type="service">
<service class="Github\Client" />
@@ -143,33 +75,8 @@
<argument>%doctrine.website.send_grid.api_key%</argument>
</service>
<service id="Doctrine\StaticWebsiteGenerator\Controller\ControllerProvider">
<argument type="collection">
<argument type="service" id="Doctrine\Website\Controllers\AtomController" />
<argument type="service" id="Doctrine\Website\Controllers\BlogController" />
<argument type="service" id="Doctrine\Website\Controllers\ConsultingController" />
<argument type="service" id="Doctrine\Website\Controllers\DocumentationController" />
<argument type="service" id="Doctrine\Website\Controllers\EventsController" />
<argument type="service" id="Doctrine\Website\Controllers\HomepageController" />
<argument type="service" id="Doctrine\Website\Controllers\PartnersController" />
<argument type="service" id="Doctrine\Website\Controllers\ProjectController" />
<argument type="service" id="Doctrine\Website\Controllers\SponsorshipController" />
<argument type="service" id="Doctrine\Website\Controllers\SitemapController" />
<argument type="service" id="Doctrine\Website\Controllers\TeamController" />
</argument>
</service>
<service id="Doctrine\StaticWebsiteGenerator\Request\RequestCollectionProvider">
<argument type="collection">
<argument type="service" id="Doctrine\Website\Requests\ContributorRequests" />
<argument type="service" id="Doctrine\Website\Requests\EventRequests" />
<argument type="service" id="Doctrine\Website\Requests\PartnerRequests" />
<argument type="service" id="Doctrine\Website\Requests\ProjectRequests" />
<argument type="service" id="Doctrine\Website\Requests\ProjectVersionRequests" />
</argument>
</service>
<service id="AlgoliaSearch\Client">
<service id="Algolia\AlgoliaSearch\SearchClient" autowire="false">
<factory method="create"/>
<argument>%doctrine.website.algolia.app_id%</argument>
<argument>%doctrine.website.algolia.admin_api_key%</argument>
</service>
@@ -185,40 +92,6 @@
<argument>%doctrine.website.assets_url%</argument>
</service>
<service id="Doctrine\StaticWebsiteGenerator\Site" alias="Doctrine\Website\Site" />
<service id="Doctrine\RST\Kernel">
<argument type="service" id="Doctrine\RST\Configuration" />
<argument type="collection">
<argument type="service" id="Doctrine\Website\RST\Directive\CautionDirective" />
<argument type="service" id="Doctrine\Website\RST\Directive\CodeBlockDirective" />
<argument type="service" id="Doctrine\Website\RST\Directive\ConfigurationBlockDirective" />
<argument type="service" id="Doctrine\Website\RST\Directive\HintDirective" />
<argument type="service" id="Doctrine\Website\RST\Directive\IndexDirective" />
<argument type="service" id="Doctrine\Website\RST\Directive\NoteDirective" />
<argument type="service" id="Doctrine\Website\RST\Directive\NoticeDirective" />
<argument type="service" id="Doctrine\Website\RST\Directive\RoleDirective" />
<argument type="service" id="Doctrine\Website\RST\Directive\SectionAuthorDirective" />
<argument type="service" id="Doctrine\Website\RST\Directive\SeeAlsoDirective" />
<argument type="service" id="Doctrine\Website\RST\Directive\SidebarDirective" />
<argument type="service" id="Doctrine\Website\RST\Directive\TipDirective" />
<argument type="service" id="Doctrine\Website\RST\Directive\TocDirective" />
<argument type="service" id="Doctrine\Website\RST\Directive\TocHeaderDirective" />
<argument type="service" id="Doctrine\Website\RST\Directive\VersionAddedDirective" />
<argument type="service" id="Doctrine\Website\RST\Directive\WarningDirective" />
</argument>
</service>
<service id="Doctrine\Website\Event\NodeValue" autowire="false" />
<service id="Doctrine\Common\EventManager" autowire="false">
<call method="addEventListener">
<argument type="constant">Doctrine\RST\Event\PreNodeRenderEvent::PRE_NODE_RENDER</argument>
<argument type="service" id="Doctrine\Website\Event\NodeValue" />
</call>
</service>
<service id="Doctrine\SkeletonMapper\Mapping\ClassMetadataInstantiator" autowire="false" />
<service id="Doctrine\SkeletonMapper\Mapping\ClassMetadataFactory" autowire="false">
<argument type="service" id="Doctrine\SkeletonMapper\Mapping\ClassMetadataInstantiator" />
@@ -228,7 +101,6 @@
<argument type="service" id="Doctrine\SkeletonMapper\ObjectRepository\ObjectRepositoryFactory" />
<argument type="service" id="Doctrine\SkeletonMapper\Mapping\ClassMetadataFactory" />
</service>
<service id="Doctrine\SkeletonMapper\ObjectManager" autowire="false" />
<service id="Doctrine\SkeletonMapper\Persister\ObjectPersisterFactory" autowire="false" />
<service id="Doctrine\Website\Repositories\BlogPostRepository" autowire="false">
@@ -504,7 +376,7 @@
</service>
<service id="Doctrine\ORM\Configuration">
<factory class="Doctrine\ORM\Tools\Setup" method="createAnnotationMetadataConfiguration" />
<factory class="Doctrine\ORM\ORMSetup" method="createAttributeMetadataConfiguration" />
<argument type="collection">
<argument>%doctrine.website.root_dir%/lib/Model/Entity</argument>
</argument>
@@ -535,16 +407,11 @@
</service>
<service id="Doctrine\Migrations\Configuration\Configuration">
<call method="setName">
<argument>Doctrine Website Migrations</argument>
</call>
<call method="setMigrationsNamespace">
<argument>Doctrine\Website\Migrations</argument>
</call>
<call method="setAllOrNothing">
<argument>true</argument>
</call>
<call method="setMigrationsDirectory">
<call method="addMigrationsDirectory">
<argument>Doctrine\Website\Migrations</argument>
<argument>%doctrine.website.root_dir%/lib/Migrations</argument>
</call>
</service>

View File

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="Doctrine\RST\Configuration">
<call method="abortOnError">
<argument>false</argument>
</call>
<call method="setIgnoreInvalidReferences">
<argument>true</argument>
</call>
<call method="setUseCachedMetas">
<argument>false</argument>
</call>
<call method="setFileExtension">
<argument>html</argument>
</call>
<call method="setEventManager">
<argument type="service" id="Doctrine\Common\EventManager" />
</call>
</service>
<service id="Doctrine\RST\Kernel">
<argument type="service" id="Doctrine\RST\Configuration" />
<argument type="collection">
<argument type="service" id="Doctrine\Website\RST\Directive\CautionDirective" />
<argument type="service" id="Doctrine\Website\RST\Directive\CodeBlockDirective" />
<argument type="service" id="Doctrine\Website\RST\Directive\ConfigurationBlockDirective" />
<argument type="service" id="Doctrine\Website\RST\Directive\HintDirective" />
<argument type="service" id="Doctrine\Website\RST\Directive\IndexDirective" />
<argument type="service" id="Doctrine\Website\RST\Directive\NoteDirective" />
<argument type="service" id="Doctrine\Website\RST\Directive\NoticeDirective" />
<argument type="service" id="Doctrine\Website\RST\Directive\RoleDirective" />
<argument type="service" id="Doctrine\Website\RST\Directive\SectionAuthorDirective" />
<argument type="service" id="Doctrine\Website\RST\Directive\SeeAlsoDirective" />
<argument type="service" id="Doctrine\Website\RST\Directive\SidebarDirective" />
<argument type="service" id="Doctrine\Website\RST\Directive\TipDirective" />
<argument type="service" id="Doctrine\Website\RST\Directive\TocDirective" />
<argument type="service" id="Doctrine\Website\RST\Directive\TocHeaderDirective" />
<argument type="service" id="Doctrine\Website\RST\Directive\VersionAddedDirective" />
<argument type="service" id="Doctrine\Website\RST\Directive\WarningDirective" />
</argument>
</service>
<service id="Doctrine\RST\Builder">
<argument type="service" id="Doctrine\RST\Kernel" />
</service>
<service id="Doctrine\RST\Parser">
<argument type="service" id="Doctrine\RST\Kernel" />
</service>
<service id="Doctrine\Website\Event\NodeValue" autowire="false" />
<service id="Doctrine\Website\Event\TableIncompatibility" autowire="false" />
<service id="Doctrine\Common\EventManager" autowire="false">
<call method="addEventListener">
<argument type="constant">Doctrine\RST\Event\PreNodeRenderEvent::PRE_NODE_RENDER</argument>
<argument type="service" id="Doctrine\Website\Event\NodeValue" />
</call>
<call method="addEventListener">
<argument type="constant">Doctrine\RST\Event\PreParseDocumentEvent::PRE_PARSE_DOCUMENT</argument>
<argument type="service" id="Doctrine\Website\Event\TableIncompatibility" />
</call>
</service>
</services>
</container>

View File

@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<defaults autowire="true" autoconfigure="true" public="false">
<bind key="$sourceDir">%doctrine.website.source_dir%</bind>
<bind key="$templatesDir">%doctrine.website.templates_dir%</bind>
<bind key="$routes">%doctrine.website.routes%</bind>
</defaults>
<prototype namespace="Doctrine\StaticWebsiteGenerator\" resource="../vendor/doctrine/static-website-generator/lib/*" />
<service id="Doctrine\StaticWebsiteGenerator\SourceFile\Converters\MarkdownConverter">
<argument type="service" id="Parsedown" />
</service>
<service id="Doctrine\StaticWebsiteGenerator\SourceFile\Converters\ReStructuredTextConverter">
<argument type="service" id="Doctrine\RST\Parser" />
</service>
<service id="Doctrine\StaticWebsiteGenerator\SourceFile\SourceFileBuilder">
<argument type="service" id="Doctrine\StaticWebsiteGenerator\SourceFile\SourceFileRenderer" />
<argument type="service" id="Symfony\Component\Filesystem\Filesystem" />
<argument type="collection">
<argument type="service" id="Doctrine\StaticWebsiteGenerator\SourceFile\Converters\MarkdownConverter" />
<argument type="service" id="Doctrine\StaticWebsiteGenerator\SourceFile\Converters\ReStructuredTextConverter" />
</argument>
<argument type="collection">
<argument>/\/api\//</argument>
</argument>
</service>
<service id="Doctrine\StaticWebsiteGenerator\Twig\StringTwigRenderer" autowire="false">
<argument>%doctrine.website.templates_dir%</argument>
<argument type="collection">
<argument type="service" id="Doctrine\Website\Twig\MainExtension" />
<argument type="service" id="Doctrine\Website\Twig\ProjectExtension" />
<argument type="service" id="Doctrine\StaticWebsiteGenerator\Twig\RoutingExtension" />
</argument>
</service>
<service id="Doctrine\StaticWebsiteGenerator\Twig\TwigRenderer" alias="Doctrine\StaticWebsiteGenerator\Twig\StringTwigRenderer" />
<service id="Doctrine\StaticWebsiteGenerator\SourceFile\SourceFileRepository">
<argument type="collection">
<argument type="service" id="Doctrine\StaticWebsiteGenerator\SourceFile\SourceFileFilesystemReader" />
<argument type="service" id="Doctrine\StaticWebsiteGenerator\SourceFile\SourceFileRouteReader" />
</argument>
</service>
<service id="Doctrine\StaticWebsiteGenerator\Controller\ControllerProvider">
<argument type="collection">
<argument type="service" id="Doctrine\Website\Controllers\AtomController" />
<argument type="service" id="Doctrine\Website\Controllers\BlogController" />
<argument type="service" id="Doctrine\Website\Controllers\ConsultingController" />
<argument type="service" id="Doctrine\Website\Controllers\DocumentationController" />
<argument type="service" id="Doctrine\Website\Controllers\EventsController" />
<argument type="service" id="Doctrine\Website\Controllers\HomepageController" />
<argument type="service" id="Doctrine\Website\Controllers\PartnersController" />
<argument type="service" id="Doctrine\Website\Controllers\ProjectController" />
<argument type="service" id="Doctrine\Website\Controllers\SponsorshipController" />
<argument type="service" id="Doctrine\Website\Controllers\SitemapController" />
<argument type="service" id="Doctrine\Website\Controllers\TeamController" />
</argument>
</service>
<service id="Doctrine\StaticWebsiteGenerator\Request\RequestCollectionProvider">
<argument type="collection">
<argument type="service" id="Doctrine\Website\Requests\ContributorRequests" />
<argument type="service" id="Doctrine\Website\Requests\EventRequests" />
<argument type="service" id="Doctrine\Website\Requests\PartnerRequests" />
<argument type="service" id="Doctrine\Website\Requests\ProjectRequests" />
<argument type="service" id="Doctrine\Website\Requests\ProjectVersionRequests" />
</argument>
</service>
<service id="Doctrine\StaticWebsiteGenerator\Site" alias="Doctrine\Website\Site" />
</services>
</container>

View File

@@ -6,10 +6,8 @@ namespace Doctrine\Website;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Tools\Console\Command as DBALCommand;
use Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper;
use Doctrine\Migrations\Configuration\Configuration as MigrationsConfiguration;
use Doctrine\DBAL\Tools\Console\ConnectionProvider\SingleConnectionProvider;
use Doctrine\Migrations\Tools\Console\Command as MigrationsCommand;
use Doctrine\Migrations\Tools\Console\Helper\ConfigurationHelper;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Tools\Console\Command as ORMCommand;
use Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper;
@@ -44,24 +42,18 @@ class Application
public const ENV_PROD = 'prod';
public const ENV_STAGING = 'staging';
/** @var BaseApplication */
private $application;
public function __construct(
BaseApplication $application,
private BaseApplication $application,
EntityManager $em,
Connection $connection,
MigrationsConfiguration $migrationsConfiguration,
BuildAllCommand $buildAllCommand,
BuildDocsCommand $buildDocsCommand,
BuildWebsiteCommand $buildWebsiteCommand,
BuildWebsiteDataCommand $buildWebsiteDataCommand,
ClearBuildCacheCommand $clearBuildCacheCommand,
SyncRepositoriesCommand $syncRepositoriesCommand,
EventParticipantsCommand $eventParticipantsCommand
EventParticipantsCommand $eventParticipantsCommand,
) {
$this->application = $application;
$this->application->add($buildAllCommand);
$this->application->add($buildDocsCommand);
$this->application->add($buildWebsiteCommand);
@@ -72,15 +64,17 @@ class Application
$this->application->setHelperSet(new HelperSet([
'question' => new QuestionHelper(),
'db' => new ConnectionHelper($connection),
//'db' => new ConnectionHelper($connection),
'em' => new EntityManagerHelper($em),
'configuration' => new ConfigurationHelper($connection, $migrationsConfiguration),
//'configuration' => new ConfigurationHelper($connection, $migrationsConfiguration),
]));
$connectionProvider = new SingleConnectionProvider($connection);
$this->application->addCommands([
// DBAL Commands
new DBALCommand\ReservedWordsCommand(),
new DBALCommand\RunSqlCommand(),
new DBALCommand\ReservedWordsCommand($connectionProvider),
new DBALCommand\RunSqlCommand($connectionProvider),
// ORM Commands
new ORMCommand\ClearCache\CollectionRegionCommand(),

View File

@@ -12,22 +12,14 @@ use function realpath;
class AssetIntegrityGenerator
{
/** @var string */
private $sourceDir;
/** @var string */
private $webpackBuildDir;
/** @var string[] */
private $cache = [];
private array $cache = [];
public function __construct(string $sourceDir, string $webpackBuildDir)
public function __construct(private string $sourceDir, private string $webpackBuildDir)
{
$this->sourceDir = $sourceDir;
$this->webpackBuildDir = $webpackBuildDir;
}
public function getAssetIntegrity(string $path, ?string $rootPath = null): string
public function getAssetIntegrity(string $path, string|null $rootPath = null): string
{
if (! isset($this->cache[$path])) {
$contents = $this->getFileContents($path, $rootPath ?? $this->sourceDir);

View File

@@ -12,18 +12,10 @@ use function sprintf;
class CacheClearer
{
/** @var Filesystem */
private $filesystem;
/** @var string */
private $rootDir;
public function __construct(
Filesystem $filesystem,
string $rootDir
private Filesystem $filesystem,
private string $rootDir,
) {
$this->filesystem = $filesystem;
$this->rootDir = $rootDir;
}
/** @return string[] */

View File

@@ -22,28 +22,17 @@ use function sprintf;
class BuildAllCommand extends Command
{
/** @var string|null */
protected static $defaultName = 'build-all';
/** @var string */
private $rootDir;
/** @var string */
private $env;
public function __construct(
string $rootDir,
string $env
private string $rootDir,
private string $env,
) {
$this->rootDir = $rootDir;
$this->env = $env;
parent::__construct();
}
protected function configure(): void
{
$this
->setName('build-all')
->setDescription('Build all website components.')
->addArgument(
'build-dir',

View File

@@ -16,22 +16,15 @@ use function is_string;
class BuildDocsCommand extends Command
{
/** @var string|null */
protected static $defaultName = 'build-docs';
/** @var BuildDocs */
private $buildDocs;
public function __construct(BuildDocs $buildDocs)
public function __construct(private BuildDocs $buildDocs)
{
$this->buildDocs = $buildDocs;
parent::__construct();
}
protected function configure(): void
{
$this
->setName('build-docs')
->setDescription('Build the RST docs.')
->addOption(
'project',

View File

@@ -28,9 +28,6 @@ use function time;
class BuildWebsiteCommand extends Command
{
/** @var string|null */
protected static $defaultName = 'build-website';
private const WATCH_DIRS = [
'config',
'data',
@@ -39,30 +36,18 @@ class BuildWebsiteCommand extends Command
'templates',
];
/** @var WebsiteBuilder */
private $websiteBuilder;
/** @var string */
private $rootDir;
/** @var string */
private $env;
public function __construct(
WebsiteBuilder $websiteBuilder,
string $rootDir,
string $env
private WebsiteBuilder $websiteBuilder,
private string $rootDir,
private string $env,
) {
$this->websiteBuilder = $websiteBuilder;
$this->rootDir = $rootDir;
$this->env = $env;
parent::__construct();
}
protected function configure(): void
{
$this
->setName('build-website')
->setDescription('Build the Doctrine website.')
->addArgument(
'build-dir',

View File

@@ -17,43 +17,20 @@ use function sprintf;
class BuildWebsiteDataCommand extends Command
{
/** @var string|null */
protected static $defaultName = 'build-website-data';
/** @var ProjectDataBuilder */
private $projectDataBuilder;
/** @var ProjectContributorDataBuilder */
private $projectContributorDataBuilder;
/** @var ContributorDataBuilder */
private $contributorDataBuilder;
/** @var BlogPostDataBuilder */
private $blogPostDataBuilder;
/** @var WebsiteDataWriter */
private $dataWriter;
public function __construct(
ProjectDataBuilder $projectDataBuilder,
ProjectContributorDataBuilder $projectContributorDataBuilder,
ContributorDataBuilder $contributorDataBuilder,
BlogPostDataBuilder $blogPostDataBuilder,
WebsiteDataWriter $dataWriter
private ProjectDataBuilder $projectDataBuilder,
private ProjectContributorDataBuilder $projectContributorDataBuilder,
private ContributorDataBuilder $contributorDataBuilder,
private BlogPostDataBuilder $blogPostDataBuilder,
private WebsiteDataWriter $dataWriter,
) {
$this->projectDataBuilder = $projectDataBuilder;
$this->projectContributorDataBuilder = $projectContributorDataBuilder;
$this->contributorDataBuilder = $contributorDataBuilder;
$this->blogPostDataBuilder = $blogPostDataBuilder;
$this->dataWriter = $dataWriter;
parent::__construct();
}
protected function configure(): void
{
$this
->setName('build-website-data')
->setDescription('Build the Doctrine website data.');
}

View File

@@ -16,30 +16,15 @@ use function sprintf;
class ClearBuildCacheCommand extends Command
{
/** @var string|null */
protected static $defaultName = 'clear-build-cache';
/** @var CacheClearer */
private $cacheClearer;
/** @var string */
private $rootDir;
/** @var string */
private $env;
public function __construct(CacheClearer $cacheClearer, string $rootDir, string $env)
public function __construct(private CacheClearer $cacheClearer, private string $rootDir, private string $env)
{
$this->cacheClearer = $cacheClearer;
$this->rootDir = $rootDir;
$this->env = $env;
parent::__construct();
}
protected function configure(): void
{
$this
->setName('clear-build-cache')
->setDescription('Clear the build cache.')
->addArgument(
'build-dir',

View File

@@ -27,43 +27,24 @@ use function sprintf;
class EventParticipantsCommand extends Command
{
/** @var string|null */
protected static $defaultName = 'event-participants';
/** @var EventRepository */
private $eventRepository;
/** @var EventParticipantRepository */
private $eventParticipantRepository;
/** @var GetStripeEventParticipants */
private $getStripeEventParticipants;
/** @var EmailParticipants */
private $emailParticipants;
/** @var EntityManager */
private $entityManager;
/**
* @param EventRepository<Event> $eventRepository
* @param EventParticipantRepository<EventParticipant> $eventParticipantRepository
*/
public function __construct(
EventRepository $eventRepository,
EventParticipantRepository $eventParticipantRepository,
GetStripeEventParticipants $getStripeEventParticipants,
EmailParticipants $emailParticipants,
EntityManager $entityManager
private EventRepository $eventRepository,
private EventParticipantRepository $eventParticipantRepository,
private GetStripeEventParticipants $getStripeEventParticipants,
private EmailParticipants $emailParticipants,
private EntityManager $entityManager,
) {
$this->eventRepository = $eventRepository;
$this->eventParticipantRepository = $eventParticipantRepository;
$this->getStripeEventParticipants = $getStripeEventParticipants;
$this->emailParticipants = $emailParticipants;
$this->entityManager = $entityManager;
parent::__construct();
}
protected function configure(): void
{
$this
->setName('event-participants')
->setDescription('Command to check for event participants using the Stripe API.')
->addOption(
'save',
@@ -133,7 +114,7 @@ class EventParticipantsCommand extends Command
*/
private function createEventParticipantsTableRows(
array $eventParticipants,
array $newEventParticipants
array $newEventParticipants,
): array {
return array_map(
static function (EventParticipant $participant) use ($newEventParticipants): array {
@@ -172,7 +153,7 @@ class EventParticipantsCommand extends Command
private function emailEventParticipants(
SymfonyStyle $io,
Event $event,
array $eventParticipants
array $eventParticipants,
): void {
$this->emailParticipants->__invoke($event, $eventParticipants);

View File

@@ -14,28 +14,17 @@ use function sprintf;
class SyncRepositoriesCommand extends Command
{
/** @var string|null */
protected static $defaultName = 'sync-repositories';
/** @var ProjectDataRepository */
private $projectDataRepository;
/** @var ProjectGitSyncer */
private $projectGitSyncer;
public function __construct(
ProjectDataRepository $projectDataRepository,
ProjectGitSyncer $projectGitSyncer
private ProjectDataRepository $projectDataRepository,
private ProjectGitSyncer $projectGitSyncer,
) {
$this->projectDataRepository = $projectDataRepository;
$this->projectGitSyncer = $projectGitSyncer;
parent::__construct();
}
protected function configure(): void
{
$this
->setName('sync-repositories')
->setDescription('Initialize or update all project repositories.');
}

View File

@@ -5,16 +5,14 @@ declare(strict_types=1);
namespace Doctrine\Website\Controllers;
use Doctrine\StaticWebsiteGenerator\Controller\Response;
use Doctrine\Website\Model\BlogPost;
use Doctrine\Website\Repositories\BlogPostRepository;
class AtomController
{
/** @var BlogPostRepository */
private $blogPostRepository;
public function __construct(BlogPostRepository $blogPostRepository)
/** @param BlogPostRepository<BlogPost> $blogPostRepository */
public function __construct(private BlogPostRepository $blogPostRepository)
{
$this->blogPostRepository = $blogPostRepository;
}
public function index(): Response

View File

@@ -5,16 +5,14 @@ declare(strict_types=1);
namespace Doctrine\Website\Controllers;
use Doctrine\StaticWebsiteGenerator\Controller\Response;
use Doctrine\Website\Model\BlogPost;
use Doctrine\Website\Repositories\BlogPostRepository;
class BlogController
{
/** @var BlogPostRepository */
private $blogPostRepository;
public function __construct(BlogPostRepository $blogPostRepository)
/** @param BlogPostRepository<BlogPost> $blogPostRepository */
public function __construct(private BlogPostRepository $blogPostRepository)
{
$this->blogPostRepository = $blogPostRepository;
}
public function index(): Response

View File

@@ -11,12 +11,9 @@ use Doctrine\Website\Repositories\TeamMemberRepository;
class ConsultingController
{
/** @var TeamMemberRepository */
private $teamMemberRepository;
public function __construct(TeamMemberRepository $teamMemberRepository)
/** @param TeamMemberRepository<TeamMember> $teamMemberRepository */
public function __construct(private TeamMemberRepository $teamMemberRepository)
{
$this->teamMemberRepository = $teamMemberRepository;
}
public function index(): Response

View File

@@ -5,16 +5,14 @@ declare(strict_types=1);
namespace Doctrine\Website\Controllers;
use Doctrine\StaticWebsiteGenerator\Controller\Response;
use Doctrine\Website\Model\Project;
use Doctrine\Website\Repositories\ProjectRepository;
class DocumentationController
{
/** @var ProjectRepository */
private $projectRepository;
public function __construct(ProjectRepository $projectRepository)
/** @param ProjectRepository<Project> $projectRepository */
public function __construct(private ProjectRepository $projectRepository)
{
$this->projectRepository = $projectRepository;
}
public function view(string $docsSlug, string $docsVersion): Response

View File

@@ -5,16 +5,14 @@ declare(strict_types=1);
namespace Doctrine\Website\Controllers;
use Doctrine\StaticWebsiteGenerator\Controller\Response;
use Doctrine\Website\Model\Event;
use Doctrine\Website\Repositories\EventRepository;
final class EventsController
{
/** @var EventRepository */
private $eventRepository;
public function __construct(EventRepository $eventRepository)
/** @param EventRepository<Event> $eventRepository */
public function __construct(private EventRepository $eventRepository)
{
$this->eventRepository = $eventRepository;
}
public function index(): Response

View File

@@ -5,6 +5,10 @@ declare(strict_types=1);
namespace Doctrine\Website\Controllers;
use Doctrine\StaticWebsiteGenerator\Controller\Response;
use Doctrine\Website\Model\BlogPost;
use Doctrine\Website\Model\DoctrineUser;
use Doctrine\Website\Model\Partner;
use Doctrine\Website\Model\Project;
use Doctrine\Website\Projects\GetTotalDownloads;
use Doctrine\Website\Repositories\BlogPostRepository;
use Doctrine\Website\Repositories\DoctrineUserRepository;
@@ -13,33 +17,19 @@ use Doctrine\Website\Repositories\ProjectRepository;
class HomepageController
{
/** @var BlogPostRepository */
private $blogPostRepository;
/** @var ProjectRepository */
private $projectRepository;
/** @var DoctrineUserRepository */
private $doctrineUserRepository;
/** @var PartnerRepository */
private $partnerRepository;
/** @var GetTotalDownloads */
private $getTotalDownloads;
/**
* @param BlogPostRepository<BlogPost> $blogPostRepository
* @param ProjectRepository<Project> $projectRepository
* @param DoctrineUserRepository<DoctrineUser> $doctrineUserRepository
* @param PartnerRepository<Partner> $partnerRepository
*/
public function __construct(
BlogPostRepository $blogPostRepository,
ProjectRepository $projectRepository,
DoctrineUserRepository $doctrineUserRepository,
PartnerRepository $partnerRepository,
GetTotalDownloads $getTotalDownloads
private BlogPostRepository $blogPostRepository,
private ProjectRepository $projectRepository,
private DoctrineUserRepository $doctrineUserRepository,
private PartnerRepository $partnerRepository,
private GetTotalDownloads $getTotalDownloads,
) {
$this->blogPostRepository = $blogPostRepository;
$this->projectRepository = $projectRepository;
$this->doctrineUserRepository = $doctrineUserRepository;
$this->partnerRepository = $partnerRepository;
$this->getTotalDownloads = $getTotalDownloads;
}
public function index(): Response

View File

@@ -5,16 +5,14 @@ declare(strict_types=1);
namespace Doctrine\Website\Controllers;
use Doctrine\StaticWebsiteGenerator\Controller\Response;
use Doctrine\Website\Model\Partner;
use Doctrine\Website\Repositories\PartnerRepository;
final class PartnersController
{
/** @var PartnerRepository */
private $partnerRepository;
public function __construct(PartnerRepository $partnerRepository)
/** @param PartnerRepository<Partner> $partnerRepository */
public function __construct(private PartnerRepository $partnerRepository)
{
$this->partnerRepository = $partnerRepository;
}
public function index(): Response

View File

@@ -5,23 +5,21 @@ declare(strict_types=1);
namespace Doctrine\Website\Controllers;
use Doctrine\StaticWebsiteGenerator\Controller\Response;
use Doctrine\Website\Model\Project;
use Doctrine\Website\Model\ProjectContributor;
use Doctrine\Website\Repositories\ProjectContributorRepository;
use Doctrine\Website\Repositories\ProjectRepository;
class ProjectController
{
/** @var ProjectRepository */
private $projectRepository;
/** @var ProjectContributorRepository */
private $projectContributorRepository;
/**
* @param ProjectRepository<Project> $projectRepository
* @param ProjectContributorRepository<ProjectContributor> $projectContributorRepository
*/
public function __construct(
ProjectRepository $projectRepository,
ProjectContributorRepository $projectContributorRepository
private ProjectRepository $projectRepository,
private ProjectContributorRepository $projectContributorRepository,
) {
$this->projectRepository = $projectRepository;
$this->projectContributorRepository = $projectContributorRepository;
}
public function index(): Response

View File

@@ -5,16 +5,14 @@ declare(strict_types=1);
namespace Doctrine\Website\Controllers;
use Doctrine\StaticWebsiteGenerator\Controller\Response;
use Doctrine\Website\Model\SitemapPage;
use Doctrine\Website\Repositories\SitemapPageRepository;
class SitemapController
{
/** @var SitemapPageRepository */
private $sitemapPageRepository;
public function __construct(SitemapPageRepository $sitemapPageRepository)
/** @param SitemapPageRepository<SitemapPage> $sitemapPageRepository */
public function __construct(private SitemapPageRepository $sitemapPageRepository)
{
$this->sitemapPageRepository = $sitemapPageRepository;
}
public function index(): Response

View File

@@ -5,16 +5,14 @@ declare(strict_types=1);
namespace Doctrine\Website\Controllers;
use Doctrine\StaticWebsiteGenerator\Controller\Response;
use Doctrine\Website\Model\Sponsor;
use Doctrine\Website\Repositories\SponsorRepository;
class SponsorshipController
{
/** @var SponsorRepository */
private $sponsorRepository;
public function __construct(SponsorRepository $sponsorRepository)
/** @param SponsorRepository<Sponsor> $sponsorRepository */
public function __construct(private SponsorRepository $sponsorRepository)
{
$this->sponsorRepository = $sponsorRepository;
}
public function index(): Response

View File

@@ -5,16 +5,14 @@ declare(strict_types=1);
namespace Doctrine\Website\Controllers;
use Doctrine\StaticWebsiteGenerator\Controller\Response;
use Doctrine\Website\Model\Contributor;
use Doctrine\Website\Repositories\ContributorRepository;
class TeamController
{
/** @var ContributorRepository */
private $contributorRepository;
public function __construct(ContributorRepository $contributorRepository)
/** @param ContributorRepository<Contributor> $contributorRepository */
public function __construct(private ContributorRepository $contributorRepository)
{
$this->contributorRepository = $contributorRepository;
}
public function maintainers(): Response

View File

@@ -10,12 +10,8 @@ class BlogPostDataBuilder implements DataBuilder
{
public const DATA_FILE = 'blog_posts';
/** @var SourceFileFilesystemReader */
private $sourceFileFilesystemReader;
public function __construct(SourceFileFilesystemReader $sourceFileFilesystemReader)
public function __construct(private SourceFileFilesystemReader $sourceFileFilesystemReader)
{
$this->sourceFileFilesystemReader = $sourceFileFilesystemReader;
}
public function getName(): string

View File

@@ -4,18 +4,16 @@ declare(strict_types=1);
namespace Doctrine\Website\DataBuilder;
use Doctrine\Website\Model\ProjectContributor;
use Doctrine\Website\Repositories\ProjectContributorRepository;
class ContributorDataBuilder implements DataBuilder
{
public const DATA_FILE = 'contributors';
/** @var ProjectContributorRepository */
private $projectContributorRepository;
public function __construct(ProjectContributorRepository $projectContributorRepository)
/** @param ProjectContributorRepository<ProjectContributor> $projectContributorRepository */
public function __construct(private ProjectContributorRepository $projectContributorRepository)
{
$this->projectContributorRepository = $projectContributorRepository;
}
public function getName(): string

View File

@@ -5,6 +5,8 @@ declare(strict_types=1);
namespace Doctrine\Website\DataBuilder;
use Doctrine\Website\Github\GithubProjectContributors;
use Doctrine\Website\Model\Project;
use Doctrine\Website\Model\TeamMember;
use Doctrine\Website\Repositories\ProjectRepository;
use Doctrine\Website\Repositories\TeamMemberRepository;
@@ -12,23 +14,15 @@ class ProjectContributorDataBuilder implements DataBuilder
{
public const DATA_FILE = 'project_contributors';
/** @var ProjectRepository */
private $projectRepository;
/** @var TeamMemberRepository */
private $teamMemberRepository;
/** @var GithubProjectContributors */
private $githubProjectContributors;
/**
* @param ProjectRepository<Project> $projectRepository
* @param TeamMemberRepository<TeamMember> $teamMemberRepository
*/
public function __construct(
ProjectRepository $projectRepository,
TeamMemberRepository $teamMemberRepository,
GithubProjectContributors $githubProjectContributors
private ProjectRepository $projectRepository,
private TeamMemberRepository $teamMemberRepository,
private GithubProjectContributors $githubProjectContributors,
) {
$this->projectRepository = $projectRepository;
$this->teamMemberRepository = $teamMemberRepository;
$this->githubProjectContributors = $githubProjectContributors;
}
public function getName(): string
@@ -64,9 +58,7 @@ class ProjectContributorDataBuilder implements DataBuilder
$contributor['author']['login'],
);
$isMaintainer = $teamMember !== null
? $teamMember->isProjectMaintainer($project)
: false;
$isMaintainer = $teamMember?->isProjectMaintainer($project) ?? false;
$isTeamMember = $teamMember !== null;

View File

@@ -31,43 +31,15 @@ class ProjectDataBuilder implements DataBuilder
'integration' => false,
];
/** @var ProjectDataRepository */
private $projectDataRepository;
/** @var ProjectGitSyncer */
private $projectGitSyncer;
/** @var ProjectDataReader */
private $projectDataReader;
/** @var ProjectVersionsReader */
private $projectVersionsReader;
/** @var RSTLanguagesDetector */
private $rstLanguagesDetector;
/** @var GetProjectPackagistData */
private $getProjectPackagistData;
/** @var string */
private $projectsDir;
public function __construct(
ProjectDataRepository $projectDataRepository,
ProjectGitSyncer $projectGitSyncer,
ProjectDataReader $projectDataReader,
ProjectVersionsReader $projectVersionsReader,
RSTLanguagesDetector $rstLanguagesDetector,
GetProjectPackagistData $getProjectPackagistData,
string $projectsDir
private ProjectDataRepository $projectDataRepository,
private ProjectGitSyncer $projectGitSyncer,
private ProjectDataReader $projectDataReader,
private ProjectVersionsReader $projectVersionsReader,
private RSTLanguagesDetector $rstLanguagesDetector,
private GetProjectPackagistData $getProjectPackagistData,
private string $projectsDir,
) {
$this->projectDataRepository = $projectDataRepository;
$this->projectGitSyncer = $projectGitSyncer;
$this->projectDataReader = $projectDataReader;
$this->projectVersionsReader = $projectVersionsReader;
$this->getProjectPackagistData = $getProjectPackagistData;
$this->rstLanguagesDetector = $rstLanguagesDetector;
$this->projectsDir = $projectsDir;
}
public function getName(): string
@@ -152,7 +124,7 @@ class ProjectDataBuilder implements DataBuilder
*/
private function applyConfiguredProjectVersions(
array &$projectVersions,
array $projectData
array $projectData,
): array {
foreach ($projectVersions as $key => $projectVersion) {
$configured = false;
@@ -213,7 +185,7 @@ class ProjectDataBuilder implements DataBuilder
private function prepareProjectVersions(
string $repositoryName,
array &$projectVersions,
array $projectData
array $projectData,
): array {
$docsRepositoryName = $projectData['docsRepositoryName'] ?? $projectData['repositoryName'];

View File

@@ -6,17 +6,9 @@ namespace Doctrine\Website\DataBuilder;
class WebsiteData
{
/** @var string */
private $name;
/** @var mixed[] */
private $data;
/** @param mixed[] $data */
public function __construct(string $name, array $data)
public function __construct(private string $name, private array $data)
{
$this->name = $name;
$this->data = $data;
}
public function getName(): string

View File

@@ -13,12 +13,8 @@ use function sprintf;
class WebsiteDataReader
{
/** @var string */
private $cacheDir;
public function __construct(string $cacheDir)
public function __construct(private string $cacheDir)
{
$this->cacheDir = $cacheDir;
}
public function read(string $file): WebsiteData

View File

@@ -15,12 +15,8 @@ use const JSON_UNESCAPED_SLASHES;
class WebsiteDataWriter
{
/** @var string */
private $cacheDir;
public function __construct(string $cacheDir)
public function __construct(private string $cacheDir)
{
$this->cacheDir = $cacheDir;
}
public function write(WebsiteData $websiteData): void

View File

@@ -8,13 +8,9 @@ use Doctrine\SkeletonMapper\DataSource\DataSource;
final class ArrayDataSource implements DataSource
{
/** @var mixed[] */
private $sourceRows;
/** @param mixed[] $sourceRows */
public function __construct(array $sourceRows)
public function __construct(private array $sourceRows)
{
$this->sourceRows = $sourceRows;
}
/** @return mixed[][] */

View File

@@ -11,12 +11,8 @@ use Doctrine\Website\DataBuilder\WebsiteDataReader;
class BlogPosts implements DataSource
{
/** @var WebsiteDataReader */
private $dataReader;
public function __construct(WebsiteDataReader $dataReader)
public function __construct(private WebsiteDataReader $dataReader)
{
$this->dataReader = $dataReader;
}
/** @return mixed[][] */

View File

@@ -7,28 +7,22 @@ namespace Doctrine\Website\DataSources;
use Doctrine\SkeletonMapper\DataSource\DataSource;
use Doctrine\Website\DataBuilder\ContributorDataBuilder;
use Doctrine\Website\DataBuilder\WebsiteDataReader;
use Doctrine\Website\Model\Project;
use Doctrine\Website\Model\TeamMember;
use Doctrine\Website\Repositories\ProjectRepository;
use Doctrine\Website\Repositories\TeamMemberRepository;
class Contributors implements DataSource
{
/** @var WebsiteDataReader */
private $dataReader;
/** @var TeamMemberRepository */
private $teamMemberRepository;
/** @var ProjectRepository */
private $projectRepository;
/**
* @param TeamMemberRepository<TeamMember> $teamMemberRepository
* @param ProjectRepository<Project> $projectRepository
*/
public function __construct(
WebsiteDataReader $dataReader,
TeamMemberRepository $teamMemberRepository,
ProjectRepository $projectRepository
private WebsiteDataReader $dataReader,
private TeamMemberRepository $teamMemberRepository,
private ProjectRepository $projectRepository,
) {
$this->dataReader = $dataReader;
$this->teamMemberRepository = $teamMemberRepository;
$this->projectRepository = $projectRepository;
}
/** @return mixed[][] */

View File

@@ -7,28 +7,22 @@ namespace Doctrine\Website\DataSources;
use Doctrine\SkeletonMapper\DataSource\DataSource;
use Doctrine\Website\DataBuilder\ProjectContributorDataBuilder;
use Doctrine\Website\DataBuilder\WebsiteDataReader;
use Doctrine\Website\Model\Project;
use Doctrine\Website\Model\TeamMember;
use Doctrine\Website\Repositories\ProjectRepository;
use Doctrine\Website\Repositories\TeamMemberRepository;
class ProjectContributors implements DataSource
{
/** @var WebsiteDataReader */
private $dataReader;
/** @var TeamMemberRepository */
private $teamMemberRepository;
/** @var ProjectRepository */
private $projectRepository;
/**
* @param TeamMemberRepository<TeamMember> $teamMemberRepository
* @param ProjectRepository<Project> $projectRepository
*/
public function __construct(
WebsiteDataReader $dataReader,
TeamMemberRepository $teamMemberRepository,
ProjectRepository $projectRepository
private WebsiteDataReader $dataReader,
private TeamMemberRepository $teamMemberRepository,
private ProjectRepository $projectRepository,
) {
$this->dataReader = $dataReader;
$this->teamMemberRepository = $teamMemberRepository;
$this->projectRepository = $projectRepository;
}
/** @return mixed[][] */

View File

@@ -10,12 +10,8 @@ use Doctrine\Website\DataBuilder\WebsiteDataReader;
class Projects implements DataSource
{
/** @var WebsiteDataReader */
private $dataReader;
public function __construct(WebsiteDataReader $dataReader)
public function __construct(private WebsiteDataReader $dataReader)
{
$this->dataReader = $dataReader;
}
/** @return mixed[][] */

View File

@@ -10,12 +10,8 @@ use Doctrine\StaticWebsiteGenerator\SourceFile\SourceFileRepository;
class SitemapPages implements DataSource
{
/** @var SourceFileRepository */
private $sourceFileRepository;
public function __construct(SourceFileRepository $sourceFileRepository)
public function __construct(private SourceFileRepository $sourceFileRepository)
{
$this->sourceFileRepository = $sourceFileRepository;
}
/** @return mixed[][] */

View File

@@ -19,35 +19,20 @@ use function sprintf;
class BuildDocs
{
/** @var ProjectRepository */
private $projectRepository;
/** @var ProjectGitSyncer */
private $projectGitSyncer;
/** @var RSTBuilder */
private $rstBuilder;
/** @var SearchIndexer */
private $searchIndexer;
/** @param ProjectRepository<Project> $projectRepository */
public function __construct(
ProjectRepository $projectRepository,
ProjectGitSyncer $projectGitSyncer,
RSTBuilder $rstBuilder,
SearchIndexer $searchIndexer
private ProjectRepository $projectRepository,
private ProjectGitSyncer $projectGitSyncer,
private RSTBuilder $rstBuilder,
private SearchIndexer $searchIndexer,
) {
$this->projectRepository = $projectRepository;
$this->projectGitSyncer = $projectGitSyncer;
$this->rstBuilder = $rstBuilder;
$this->searchIndexer = $searchIndexer;
}
public function build(
OutputInterface $output,
string $projectToBuild,
string $versionToBuild,
bool $buildSearchIndexes
bool $buildSearchIndexes,
): void {
if ($buildSearchIndexes) {
$this->searchIndexer->initSearchIndex();

View File

@@ -22,12 +22,8 @@ class CodeBlockLanguageDetector
'php-attributes' => 'php',
];
/** @var string */
private $rootDir;
public function __construct(string $rootDir)
public function __construct(private string $rootDir)
{
$this->rootDir = $rootDir;
}
/** @param string[] $lines */

View File

@@ -8,20 +8,12 @@ use function in_array;
class CodeBlockRenderer
{
private const CONSOLE_LANGUAGES = ['bash', 'sh', 'console'];
/** @var CodeBlockConsoleRenderer */
private $codeBlockConsoleRenderer;
/** @var CodeBlockWithLineNumbersRenderer */
private $codeBlockWithLineNumbersRenderer;
private const CONSOLE_LANGUAGES = ['terminal', 'bash', 'sh', 'console'];
public function __construct(
CodeBlockConsoleRenderer $codeBlockConsoleRenderer,
CodeBlockWithLineNumbersRenderer $codeBlockWithLineNumbersRenderer
private CodeBlockConsoleRenderer $codeBlockConsoleRenderer,
private CodeBlockWithLineNumbersRenderer $codeBlockWithLineNumbersRenderer,
) {
$this->codeBlockConsoleRenderer = $codeBlockConsoleRenderer;
$this->codeBlockWithLineNumbersRenderer = $codeBlockWithLineNumbersRenderer;
}
/** @param string[] $lines */

View File

@@ -46,12 +46,8 @@ class CodeBlockWithLineNumbersRenderer
</pre>
TEMPLATE;
/** @var Highlighter */
private $highlighter;
public function __construct(Highlighter $highlighter)
public function __construct(private Highlighter $highlighter)
{
$this->highlighter = $highlighter;
}
/** @param string[] $lines */

View File

@@ -12,43 +12,15 @@ use Symfony\Component\Filesystem\Filesystem;
class RSTBuilder
{
/** @var RSTFileRepository */
private $rstFileRepository;
/** @var RSTCopier */
private $rstCopier;
/** @var Builder */
private $builder;
/** @var RSTPostBuildProcessor */
private $rstPostBuildProcessor;
/** @var Filesystem */
private $filesystem;
/** @var string */
private $sourceDir;
/** @var string */
private $docsDir;
public function __construct(
RSTFileRepository $rstFileRepository,
RSTCopier $rstCopier,
Builder $builder,
RSTPostBuildProcessor $rstPostBuildProcessor,
Filesystem $filesystem,
string $sourceDir,
string $docsDir
private RSTFileRepository $rstFileRepository,
private RSTCopier $rstCopier,
private Builder $builder,
private RSTPostBuildProcessor $rstPostBuildProcessor,
private Filesystem $filesystem,
private string $sourceDir,
private string $docsDir,
) {
$this->rstFileRepository = $rstFileRepository;
$this->rstCopier = $rstCopier;
$this->builder = $builder;
$this->rstPostBuildProcessor = $rstPostBuildProcessor;
$this->filesystem = $filesystem;
$this->sourceDir = $sourceDir;
$this->docsDir = $docsDir;
}
/** @return DocumentNode[] */

View File

@@ -33,23 +33,11 @@ TEMPLATE;
/*
SIDEBAR;
/** @var RSTFileRepository */
private $rstFileRepository;
/** @var Filesystem */
private $filesystem;
/** @var string */
private $docsDir;
public function __construct(
RSTFileRepository $rstFileRepository,
Filesystem $filesystem,
string $docsDir
private RSTFileRepository $rstFileRepository,
private Filesystem $filesystem,
private string $docsDir,
) {
$this->rstFileRepository = $rstFileRepository;
$this->filesystem = $filesystem;
$this->docsDir = $docsDir;
}
public function copyRst(Project $project, ProjectVersion $version): void
@@ -83,7 +71,7 @@ SIDEBAR;
RSTLanguage $language,
string $file,
string $outputPath,
string $sidebar
string $sidebar,
): void {
$filePath = str_replace($language->getPath(), '', $file);

View File

@@ -6,16 +6,8 @@ namespace Doctrine\Website\Docs\RST;
class RSTLanguage
{
/** @var string */
private $code;
/** @var string */
private $path;
public function __construct(string $code, string $path)
public function __construct(private string $code, private string $path)
{
$this->code = $code;
$this->path = $path;
}
public function getCode(): string

View File

@@ -25,23 +25,11 @@ docsSourcePath: "%s"
%s
TEMPLATE;
/** @var RSTFileRepository */
private $rstFileRepository;
/** @var Filesystem */
private $filesystem;
/** @var string */
private $sourceDir;
public function __construct(
RSTFileRepository $rstFileRepository,
Filesystem $filesystem,
string $sourceDir
private RSTFileRepository $rstFileRepository,
private Filesystem $filesystem,
private string $sourceDir,
) {
$this->rstFileRepository = $rstFileRepository;
$this->filesystem = $filesystem;
$this->sourceDir = $sourceDir;
}
public function postRstBuild(Project $project, ProjectVersion $version, RSTLanguage $language): void
@@ -57,22 +45,15 @@ TEMPLATE;
$files = $this->rstFileRepository->findFiles($projectVersionDocsOutputPath);
foreach ($files as $file) {
$this->processFile($project, $version, $language, $file);
$this->processFile($file);
}
}
private function processFile(
Project $project,
ProjectVersion $version,
RSTLanguage $language,
string $file
): void {
private function processFile(string $file): void
{
$contents = $this->getFileContents($file);
$processedContents = $this->processFileContents(
$project,
$version,
$language,
$file,
$contents,
);
@@ -80,26 +61,18 @@ TEMPLATE;
$this->filesystem->dumpFile($file, $processedContents);
}
private function processFileContents(
Project $project,
ProjectVersion $version,
RSTLanguage $language,
string $file,
string $contents
): string {
private function processFileContents(string $file, string $contents): string
{
if (strpos($file, '.html') !== false) {
return $this->processHtmlFile($project, $version, $language, $file, $contents);
return $this->processHtmlFile($file, $contents);
}
return $contents;
}
private function processHtmlFile(
Project $project,
ProjectVersion $version,
RSTLanguage $language,
string $file,
string $contents
string $contents,
): string {
// parse out the source file that generated this file
preg_match('/<p>{{ DOCS_SOURCE_PATH : (.*) }}<\/p>/', $contents, $match);
@@ -121,13 +94,18 @@ TEMPLATE;
return sprintf(
self::PARAMETERS_TEMPLATE,
$title,
$this->escapeYaml($title),
strpos($file, 'index.html') !== false ? 'true' : 'false',
$docsSourcePath,
$contents,
);
}
private function escapeYaml(string $text): string
{
return str_replace('\\', '\\\\', $text);
}
private function getFileContents(string $file): string
{
$contents = $this->rstFileRepository->getFileContents($file);

View File

@@ -4,8 +4,8 @@ declare(strict_types=1);
namespace Doctrine\Website\Docs;
use AlgoliaSearch\Client;
use AlgoliaSearch\Index;
use Algolia\AlgoliaSearch\SearchClient;
use Algolia\AlgoliaSearch\SearchIndex;
use Doctrine\RST\Nodes\DocumentNode;
use Doctrine\RST\Nodes\Node;
use Doctrine\RST\Nodes\ParagraphNode;
@@ -13,7 +13,6 @@ use Doctrine\RST\Nodes\TitleNode;
use Doctrine\Website\Model\Project;
use Doctrine\Website\Model\ProjectVersion;
use function get_class;
use function in_array;
use function is_string;
use function md5;
@@ -28,12 +27,8 @@ class SearchIndexer
{
public const INDEX_NAME = 'pages';
/** @var Client */
private $client;
public function __construct(Client $client)
public function __construct(private SearchClient $client)
{
$this->client = $client;
}
public function initSearchIndex(): void
@@ -53,14 +48,14 @@ class SearchIndexer
'removeWordsIfNoResults' => 'allOptional',
]);
$index->clearIndex();
$index->clearObjects();
}
/** @param DocumentNode[] $documents */
public function buildSearchIndexes(
Project $project,
ProjectVersion $version,
array $documents
array $documents,
): void {
$records = [];
@@ -68,7 +63,7 @@ class SearchIndexer
$this->buildDocumentSearchRecords($document, $records, $project, $version);
}
$this->getSearchIndex()->addObjects($records);
$this->getSearchIndex()->saveObjects($records, ['autoGenerateObjectIDIfNotExist' => true]);
}
/** @param mixed[][] $records */
@@ -76,7 +71,7 @@ class SearchIndexer
DocumentNode $document,
array &$records,
Project $project,
ProjectVersion $version
ProjectVersion $version,
): void {
$environment = $document->getEnvironment();
@@ -94,7 +89,7 @@ class SearchIndexer
$nodeTypes = [TitleNode::class, ParagraphNode::class];
$nodes = $document->getNodes(static function (Node $node) use ($nodeTypes): bool {
return in_array(get_class($node), $nodeTypes, true);
return in_array($node::class, $nodeTypes, true);
});
foreach ($nodes as $node) {
@@ -132,7 +127,7 @@ class SearchIndexer
array &$current,
string &$currentLink,
Project $project,
ProjectVersion $version
ProjectVersion $version,
): array {
$level = $node instanceof TitleNode ? $node->getLevel() : false;
@@ -193,18 +188,18 @@ class SearchIndexer
{
$nodeValue = $node->getValue();
if ($nodeValue instanceof Node) {
return $nodeValue->render();
if ($nodeValue === null) {
return '';
}
if (is_string($nodeValue)) {
return $nodeValue;
}
return (string) $nodeValue;
return $nodeValue->render();
}
private function getSearchIndex(): Index
private function getSearchIndex(): SearchIndex
{
return $this->client->initIndex(self::INDEX_NAME);
}

View File

@@ -4,7 +4,7 @@ declare(strict_types=1);
namespace Doctrine\Website\Email;
use Pelago\Emogrifier;
use Pelago\Emogrifier\CssInliner;
use Twig\Environment;
use Twig\Extension\AbstractExtension;
use Twig\Loader\FilesystemLoader;
@@ -15,24 +15,11 @@ use function trim;
final class RenderEmail
{
/** @var Emogrifier */
private $emogrifier;
/** @var string */
private $templatesDir;
/** @var AbstractExtension[] */
private $extensions;
/** @param AbstractExtension[] $extensions */
public function __construct(
Emogrifier $emogrifier,
string $templatesDir,
array $extensions
private string $templatesDir,
private array $extensions,
) {
$this->emogrifier = $emogrifier;
$this->templatesDir = $templatesDir;
$this->extensions = $extensions;
}
/** @param mixed[] $parameters */
@@ -40,7 +27,7 @@ final class RenderEmail
{
$twig = $this->createTwigEnvironment($this->createFilesystemLoader());
$template = $twig->loadTemplate($template);
$template = $twig->createTemplate($template);
$subject = $template->renderBlock('subject', $parameters);
$inlineCss = $template->renderBlock('inline_css', $parameters);
@@ -51,10 +38,8 @@ final class RenderEmail
$bodyText = strip_tags($template->renderBlock('body_html', $parameters));
}
$this->emogrifier->setHtml($bodyHtml);
$this->emogrifier->setCss($inlineCss);
$mergedHtml = $this->emogrifier->emogrify();
$emogrifier = CssInliner::fromHtml($bodyHtml)->inlineCss($inlineCss);
$mergedHtml = $emogrifier->render();
return new RenderedEmail($subject, $bodyText, $mergedHtml);
}

View File

@@ -6,20 +6,8 @@ namespace Doctrine\Website\Email;
final class RenderedEmail
{
/** @var string */
private $subject;
/** @var string */
private $bodyText;
/** @var string */
private $bodyHtml;
public function __construct(string $subject, string $bodyText, string $bodyHtml)
public function __construct(private string $subject, private string $bodyText, private string $bodyHtml)
{
$this->subject = $subject;
$this->bodyText = $bodyText;
$this->bodyHtml = $bodyHtml;
}
public function getSubject(): string

View File

@@ -9,23 +9,11 @@ use SendGrid;
final class SendEmail
{
/** @var Site */
private $site;
/** @var SendGrid */
private $sendGrid;
/** @var RenderEmail */
private $renderEmail;
public function __construct(
Site $site,
SendGrid $sendGrid,
RenderEmail $renderEmail
private Site $site,
private SendGrid $sendGrid,
private RenderEmail $renderEmail,
) {
$this->site = $site;
$this->sendGrid = $sendGrid;
$this->renderEmail = $renderEmail;
}
/** @param mixed[] $parameters */

View File

@@ -10,12 +10,8 @@ use Doctrine\Website\Model\Event;
final class EmailParticipants
{
/** @var SendEmail */
private $sendEmail;
public function __construct(SendEmail $sendEmail)
public function __construct(private SendEmail $sendEmail)
{
$this->sendEmail = $sendEmail;
}
/** @param EventParticipant[] $participants */

View File

@@ -87,10 +87,9 @@ final class GetStripeEventParticipants
return $allEventStripeCheckouts;
}
/** @return Stripe\Collection<string, mixed> */
private function getEventStripeCheckouts(
Event $event,
?string $startingAfter = null
string|null $startingAfter = null,
): Stripe\Collection {
$parameters = [
'created' => ['gt' => strtotime('1 year ago')],

View File

@@ -0,0 +1,26 @@
<?php
declare(strict_types=1);
namespace Doctrine\Website\Event;
use Doctrine\RST\Event\PreParseDocumentEvent;
use function str_contains;
use function str_replace;
final class TableIncompatibility
{
private const BEFORE = '| **SQL Server** | +----------------------------------------------------------+';
private const AFTER = '| **SQL Server** | | |';
public function preParseDocument(PreParseDocumentEvent $event): void
{
if (! str_contains($event->getContents(), self::BEFORE)) {
return;
}
$content = str_replace(self::BEFORE, self::AFTER, $event->getContents());
$event->setContents($content);
}
}

View File

@@ -27,16 +27,8 @@ class Tag
private const COMPOSER_EPOCH = '2011-09-25';
/** @var string */
private $name;
/** @var DateTimeImmutable */
private $date;
public function __construct(string $name, DateTimeImmutable $date)
public function __construct(private string $name, private DateTimeImmutable $date)
{
$this->name = $name;
$this->date = $date;
}
public function getName(): string

View File

@@ -16,15 +16,11 @@ class TagBranchGuesser
{
private const COMMAND = 'cd %s && git branch -a';
/** @var ProcessFactory */
private $processFactory;
public function __construct(ProcessFactory $processFactory)
public function __construct(private ProcessFactory $processFactory)
{
$this->processFactory = $processFactory;
}
public function guessTagBranchName(string $repositoryPath, Tag $tag): ?string
public function guessTagBranchName(string $repositoryPath, Tag $tag): string|null
{
$command = sprintf(self::COMMAND, $repositoryPath);
@@ -52,7 +48,7 @@ class TagBranchGuesser
return null;
}
public function generateTagBranchSlug(Tag $tag): ?string
public function generateTagBranchSlug(Tag $tag): string|null
{
$versionSlug = ltrim($tag->getName(), 'v');

View File

@@ -17,12 +17,8 @@ class TagReader
{
private const COMMAND = "cd %s && git tag -l --format='refname: %%(refname) creatordate: %%(creatordate)'";
/** @var ProcessFactory */
private $processFactory;
public function __construct(ProcessFactory $processFactory)
public function __construct(private ProcessFactory $processFactory)
{
$this->processFactory = $processFactory;
}
/** @return Tag[] */
@@ -71,7 +67,7 @@ class TagReader
return $tags;
}
private function extractTagFromLine(string $line): ?Tag
private function extractTagFromLine(string $line): Tag|null
{
preg_match_all('/refname: (.*) creatordate: (.*)/', $line, $matches);

View File

@@ -4,34 +4,25 @@ declare(strict_types=1);
namespace Doctrine\Website\Github;
use Github\AuthMethod;
use Github\Client;
use InvalidArgumentException;
class GithubClientProvider
{
/** @var Client */
private $githubClient;
private bool $authenticated = false;
/** @var string */
private $githubHttpToken;
/** @var bool */
private $authenticated = false;
public function __construct(Client $githubClient, string $githubHttpToken)
public function __construct(private Client $githubClient, private string $githubHttpToken)
{
if ($githubHttpToken === '') {
throw new InvalidArgumentException('You must configure a Github http token.');
}
$this->githubClient = $githubClient;
$this->githubHttpToken = $githubHttpToken;
}
public function getGithubClient(): Client
{
if ($this->authenticated === false) {
$this->githubClient->authenticate($this->githubHttpToken, '', 'http_token');
$this->githubClient->authenticate($this->githubHttpToken, '', AuthMethod::ACCESS_TOKEN);
$this->authenticated = true;
}

View File

@@ -16,15 +16,10 @@ use function sprintf;
class ProdGithubProjectContributors implements GithubProjectContributors
{
private CacheItemPoolInterface $cache;
private Client $githubClient;
public function __construct(
CacheItemPoolInterface $cache,
Client $githubClient
private CacheItemPoolInterface $cache,
private Client $githubClient,
) {
$this->cache = $cache;
$this->githubClient = $githubClient;
}
/** @param Project[] $projects */

View File

@@ -10,12 +10,9 @@ use Doctrine\Website\Repositories\TeamMemberRepository;
class TestGithubProjectContributors implements GithubProjectContributors
{
/** @var TeamMemberRepository */
private $teamMemberRepository;
public function __construct(TeamMemberRepository $teamMemberRepository)
/** @param TeamMemberRepository<TeamMember> $teamMemberRepository */
public function __construct(private TeamMemberRepository $teamMemberRepository)
{
$this->teamMemberRepository = $teamMemberRepository;
}
/** @param Project[] $projects */

View File

@@ -15,9 +15,11 @@ use Doctrine\Website\Model\BlogPost;
* @property string $authorEmail
* @property string $contents
* @property DateTimeImmutable $date
* @template-extends ModelHydrator<BlogPost>
*/
final class BlogPostHydrator extends ModelHydrator
{
/** @return class-string<BlogPost> */
protected function getClassName(): string
{
return BlogPost::class;

View File

@@ -5,6 +5,8 @@ declare(strict_types=1);
namespace Doctrine\Website\Hydrators;
use Doctrine\Website\Model\Contributor;
use Doctrine\Website\Model\Project;
use Doctrine\Website\Model\TeamMember;
/**
* @property TeamMember|null $teamMember
@@ -14,9 +16,11 @@ use Doctrine\Website\Model\Contributor;
* @property int $numAdditions
* @property int $numDeletions
* @property Project[] $projects
* @template-extends ModelHydrator<Contributor>
*/
final class ContributorHydrator extends ModelHydrator
{
/** @return class-string<Contributor> */
protected function getClassName(): string
{
return Contributor::class;

View File

@@ -9,9 +9,11 @@ use Doctrine\Website\Model\DoctrineUser;
/**
* @property string $name
* @property string $url
* @template-extends ModelHydrator<DoctrineUser>
*/
final class DoctrineUserHydrator extends ModelHydrator
{
/** @return class-string<DoctrineUser> */
protected function getClassName(): string
{
return DoctrineUser::class;

View File

@@ -9,6 +9,7 @@ use Doctrine\SkeletonMapper\ObjectManagerInterface;
use Doctrine\Website\Application;
use Doctrine\Website\Model\Address;
use Doctrine\Website\Model\DateTimeRange;
use Doctrine\Website\Model\Entity\EventParticipant;
use Doctrine\Website\Model\Entity\EventParticipantRepository;
use Doctrine\Website\Model\Event;
use Doctrine\Website\Model\EventCfp;
@@ -41,6 +42,7 @@ use function sprintf;
* @property DateTimeRange $registrationDateTimeRange
* @property string $description
* @property float $price
* @template-extends ModelHydrator<Event>
*/
final class EventHydrator extends ModelHydrator
{
@@ -51,23 +53,16 @@ final class EventHydrator extends ModelHydrator
'test' => 'test',
];
/** @var EventParticipantRepository */
private $eventParticipantRepository;
/** @var string */
private $env;
/** @param EventParticipantRepository<EventParticipant> $eventParticipantRepository */
public function __construct(
ObjectManagerInterface $objectManager,
EventParticipantRepository $eventParticipantRepository,
string $env
private EventParticipantRepository $eventParticipantRepository,
private string $env,
) {
parent::__construct($objectManager);
$this->eventParticipantRepository = $eventParticipantRepository;
$this->env = $env;
}
/** @return class-string<Event> */
protected function getClassName(): string
{
return Event::class;

View File

@@ -9,52 +9,46 @@ use Doctrine\SkeletonMapper\Mapping\ClassMetadataInterface;
use Doctrine\SkeletonMapper\ObjectManagerInterface;
use ReflectionProperty;
/** @template T of object */
abstract class ModelHydrator extends ObjectHydrator
{
/** @var ObjectManagerInterface */
protected $objectManager;
private object $object;
/** @var object */
private $object;
/** @var ClassMetadataInterface */
private $classMetadata;
/** @var ClassMetadataInterface<T> */
private ClassMetadataInterface $classMetadata;
/** @var ReflectionProperty[] */
private $reflectionProperties;
private array $reflectionProperties;
public function __construct(ObjectManagerInterface $objectManager)
public function __construct(protected ObjectManagerInterface $objectManager)
{
$this->objectManager = $objectManager;
$this->classMetadata = $this->objectManager->getClassMetadata($this->getClassName());
}
/** @param mixed[] $data */
abstract protected function doHydrate(array $data): void;
/** @return class-string<T> */
abstract protected function getClassName(): string;
/**
* @param object $object
* @param mixed[] $data
*
* @phpcsSuppress SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingParameterTypeHint
*/
public function hydrate($object, array $data): void
public function hydrate(object $object, array $data): void
{
$this->object = $object;
$this->doHydrate($data);
}
/** @return mixed */
public function __get(string $field)
public function __get(string $field): mixed
{
return $this->getReflectionProperty($field)->getValue($this->object);
}
/** @param mixed $value */
public function __set(string $field, $value): void
public function __set(string $field, mixed $value): void
{
$this->getReflectionProperty($field)->setValue($this->object, $value);
}

View File

@@ -19,9 +19,11 @@ use function array_merge;
* @property bool $featured
* @property PartnerDetails $details
* @property UtmParameters $utmParameters
* @template-extends ModelHydrator<Partner>
*/
final class PartnerHydrator extends ModelHydrator
{
/** @return class-string<Partner> */
protected function getClassName(): string
{
return Partner::class;

View File

@@ -6,6 +6,7 @@ namespace Doctrine\Website\Hydrators;
use Doctrine\Website\Model\Project;
use Doctrine\Website\Model\ProjectContributor;
use Doctrine\Website\Model\TeamMember;
/**
* @property TeamMember|null $teamMember
@@ -16,9 +17,11 @@ use Doctrine\Website\Model\ProjectContributor;
* @property int $numCommits
* @property int $numAdditions
* @property int $numDeletions
* @template-extends ModelHydrator<ProjectContributor>
*/
final class ProjectContributorHydrator extends ModelHydrator
{
/** @return class-string<ProjectContributor> */
protected function getClassName(): string
{
return ProjectContributor::class;

View File

@@ -28,9 +28,11 @@ use Doctrine\Website\Model\ProjectVersion;
* @property ProjectVersion[] $versions
* @property ProjectIntegrationType $projectIntegrationType
* @property ProjectStats $projectStats
* @template-extends ModelHydrator<Project>
*/
final class ProjectHydrator extends ModelHydrator
{
/** @return class-string<Project> */
protected function getClassName(): string
{
return Project::class;

View File

@@ -10,9 +10,11 @@ use Doctrine\Website\Model\SitemapPage;
/**
* @property string $url
* @property DateTimeImmutable $date
* @template-extends ModelHydrator<SitemapPage>
*/
final class SitemapPageHydrator extends ModelHydrator
{
/** @return class-string<SitemapPage> */
protected function getClassName(): string
{
return SitemapPage::class;

View File

@@ -14,9 +14,11 @@ use function array_merge;
* @property string $url
* @property UtmParameters $utmParameters
* @property bool $highlighted
* @template-extends ModelHydrator<Sponsor>
*/
final class SponsorHydrator extends ModelHydrator
{
/** @return class-string<Sponsor> */
protected function getClassName(): string
{
return Sponsor::class;

View File

@@ -23,9 +23,11 @@ use function assert;
* @property string $headshot
* @property string $bio
* @property Closure|Contributor $contributor
* @template-extends ModelHydrator<TeamMember>
*/
final class TeamMemberHydrator extends ModelHydrator
{
/** @return class-string<TeamMember> */
protected function getClassName(): string
{
return TeamMember::class;

View File

@@ -8,38 +8,14 @@ use function sprintf;
final class Address
{
/** @var string */
private $line1;
/** @var string */
private $line2;
/** @var string */
private $city;
/** @var string */
private $state;
/** @var string */
private $zipCode;
/** @var string */
private $countryCode;
public function __construct(
string $line1,
string $line2,
string $city,
string $state,
string $zipCode,
string $countryCode
private string $line1,
private string $line2,
private string $city,
private string $state,
private string $zipCode,
private string $countryCode,
) {
$this->line1 = $line1;
$this->line2 = $line2;
$this->city = $city;
$this->state = $state;
$this->zipCode = $zipCode;
$this->countryCode = $countryCode;
}
public function getLine1(): string

View File

@@ -10,43 +10,15 @@ use Doctrine\SkeletonMapper\Mapping\LoadMetadataInterface;
class BlogPost implements LoadMetadataInterface
{
/** @var string */
private $url;
/** @var string */
private $slug;
/** @var string */
private $title;
/** @var string */
private $authorName;
/** @var string */
private $authorEmail;
/** @var string */
private $contents;
/** @var DateTimeImmutable */
private $date;
public function __construct(
string $url,
string $slug,
string $title,
string $authorName,
string $authorEmail,
string $contents,
DateTimeImmutable $date
private string $url,
private string $slug,
private string $title,
private string $authorName,
private string $authorEmail,
private string $contents,
private DateTimeImmutable $date,
) {
$this->url = $url;
$this->slug = $slug;
$this->title = $title;
$this->authorName = $authorName;
$this->authorEmail = $authorEmail;
$this->contents = $contents;
$this->date = $date;
}
public static function loadMetadata(ClassMetadataInterface $metadata): void

View File

@@ -6,14 +6,11 @@ namespace Doctrine\Website\Model;
final class CommittersStats implements CommitterStats
{
/** @var int */
private $numCommits = 0;
private int $numCommits = 0;
/** @var int */
private $numAdditions = 0;
private int $numAdditions = 0;
/** @var int */
private $numDeletions = 0;
private int $numDeletions = 0;
/** @param CommitterStats[] $committersStats */
public function __construct(array $committersStats)

View File

@@ -9,33 +9,27 @@ use Doctrine\SkeletonMapper\Mapping\LoadMetadataInterface;
class Contributor implements LoadMetadataInterface, CommitterStats
{
/** @var TeamMember|null */
private $teamMember;
private TeamMember|null $teamMember = null;
/** @var string */
private $github;
private string $github;
/** @var string */
private $avatarUrl;
private string $avatarUrl;
/** @var int */
private $numCommits;
private int $numCommits;
/** @var int */
private $numAdditions;
private int $numAdditions;
/** @var int */
private $numDeletions;
private int $numDeletions;
/** @var Project[] */
private $projects;
private array $projects;
public static function loadMetadata(ClassMetadataInterface $metadata): void
{
$metadata->setIdentifier(['github']);
}
public function getTeamMember(): ?TeamMember
public function getTeamMember(): TeamMember|null
{
return $this->teamMember;
}

View File

@@ -8,23 +8,14 @@ use DateTimeImmutable;
final class DateTimeRange
{
/** @var DateTimeImmutable */
private $start;
/** @var DateTimeImmutable */
private $end;
/** @var DateTimeImmutable */
private $now;
private DateTimeImmutable $now;
public function __construct(
DateTimeImmutable $start,
DateTimeImmutable $end,
?DateTimeImmutable $now = null
private DateTimeImmutable $start,
private DateTimeImmutable $end,
DateTimeImmutable|null $now = null,
) {
$this->start = $start;
$this->end = $end;
$this->now = $now ?? new DateTimeImmutable();
$this->now = $now ?? new DateTimeImmutable();
}
public function getStart(): DateTimeImmutable

View File

@@ -9,11 +9,9 @@ use Doctrine\SkeletonMapper\Mapping\LoadMetadataInterface;
class DoctrineUser implements LoadMetadataInterface
{
/** @var string */
private $name;
private string $name;
/** @var string */
private $url;
private string $url;
public static function loadMetadata(ClassMetadataInterface $metadata): void
{

View File

@@ -4,39 +4,30 @@ declare(strict_types=1);
namespace Doctrine\Website\Model\Entity;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\GeneratedValue;
use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Mapping\Table;
use Doctrine\Website\Model\Event;
/**
* @Entity(repositoryClass="EventParticipantRepository")
* @Table(name="event_participants")
*/
#[Entity(repositoryClass: EventParticipantRepository::class)]
#[Table(name: 'event_participants')]
final class EventParticipant
{
/**
* @var int|null
* @Id
* @Column(type="integer")
* @GeneratedValue
**/
private $id;
#[Id]
#[Column(type: 'integer')]
#[GeneratedValue]
private int|null $id = null;
/**
* @var string
* @Column(type="string")
**/
private $email;
#[Column(type: 'string')]
private string $email;
/**
* @var int
* @Column(type="integer")
**/
private $quantity;
#[Column(type: 'integer')]
private int $quantity;
/**
* @var int
* @Column(type="integer")
**/
private $eventId;
#[Column(type: 'integer')]
private int $eventId;
public function __construct(Event $event, string $email, int $quantity)
{
@@ -45,7 +36,7 @@ final class EventParticipant
$this->quantity = $quantity;
}
public function getId(): ?int
public function getId(): int|null
{
return $this->id;
}

View File

@@ -8,9 +8,13 @@ use Doctrine\ORM\EntityRepository;
use function assert;
/**
* @template T of EventParticipant
* @template-extends EntityRepository<T>
*/
final class EventParticipantRepository extends EntityRepository
{
public function findOneByEmail(string $email): ?EventParticipant
public function findOneByEmail(string $email): EventParticipant|null
{
$eventParticipant = $this->findOneBy(['email' => $email]);
assert($eventParticipant instanceof EventParticipant);

View File

@@ -10,53 +10,37 @@ use Doctrine\SkeletonMapper\Mapping\LoadMetadataInterface;
final class Event implements LoadMetadataInterface
{
/** @var int */
private $id;
private int $id;
/** @var string */
private $type;
private string $type;
/** @var string */
private $sku;
private string $sku;
/** @var string */
private $name;
private string $name;
/** @var string */
private $slug;
private string $slug;
/** @var string */
private $joinUrl;
private string $joinUrl;
/** @var DateTimeRange */
private $dateTimeRange;
private DateTimeRange $dateTimeRange;
/** @var DateTimeRange */
private $registrationDateTimeRange;
private DateTimeRange $registrationDateTimeRange;
/** @var EventCfp */
private $cfp;
private EventCfp $cfp;
/** @var EventLocation|null */
private $location;
private EventLocation|null $location = null;
/** @var EventSponsors */
private $sponsors;
private EventSponsors $sponsors;
/** @var EventSpeakers */
private $speakers;
private EventSpeakers $speakers;
/** @var EventSchedule */
private $schedule;
private EventSchedule $schedule;
/** @var EventParticipants */
private $participants;
private EventParticipants $participants;
/** @var string */
private $description;
private string $description;
/** @var float */
private $price;
private float $price;
public static function loadMetadata(ClassMetadataInterface $metadata): void
{
@@ -123,7 +107,7 @@ final class Event implements LoadMetadataInterface
return $this->cfp;
}
public function getLocation(): ?EventLocation
public function getLocation(): EventLocation|null
{
return $this->location;
}

View File

@@ -10,16 +10,8 @@ use function sprintf;
final class EventCfp
{
/** @var string */
private $googleFormId;
/** @var DateTimeRange */
private $dateTimeRange;
public function __construct(string $googleFormId, DateTimeRange $dateTimeRange)
public function __construct(private string $googleFormId, private DateTimeRange $dateTimeRange)
{
$this->googleFormId = $googleFormId;
$this->dateTimeRange = $dateTimeRange;
}
public function exists(): bool

View File

@@ -6,16 +6,8 @@ namespace Doctrine\Website\Model;
final class EventLocation
{
/** @var string */
private $name;
/** @var Address */
private $address;
public function __construct(string $name, Address $address)
public function __construct(private string $name, private Address $address)
{
$this->name = $name;
$this->address = $address;
}
public function getName(): string

View File

@@ -12,16 +12,9 @@ use Doctrine\Website\Model\Entity\EventParticipantRepository;
/** @template-extends AbstractLazyCollection<int, EventParticipant> */
final class EventParticipants extends AbstractLazyCollection
{
/** @var int */
private $eventId;
/** @var EventParticipantRepository */
private $eventParticipantRepository;
public function __construct(int $eventId, EventParticipantRepository $eventParticipantRepository)
/** @param EventParticipantRepository<EventParticipant> $eventParticipantRepository */
public function __construct(private int $eventId, private EventParticipantRepository $eventParticipantRepository)
{
$this->eventId = $eventId;
$this->eventParticipantRepository = $eventParticipantRepository;
}
protected function doInitialize(): void

View File

@@ -14,17 +14,9 @@ use function sprintf;
/** @template-extends AbstractLazyCollection<int, EventScheduleSlot> */
final class EventSchedule extends AbstractLazyCollection
{
/** @var mixed[] */
private $event;
/** @var EventSpeakers */
private $speakers;
/** @param mixed[] $event */
public function __construct(array $event, EventSpeakers $speakers)
public function __construct(private array $event, private EventSpeakers $speakers)
{
$this->event = $event;
$this->speakers = $speakers;
}
protected function doInitialize(): void

View File

@@ -8,23 +8,11 @@ use DateTimeImmutable;
final class EventScheduleSlot
{
/** @var EventSpeaker */
private $speaker;
/** @var DateTimeImmutable */
private $startDate;
/** @var DateTimeImmutable */
private $endDate;
public function __construct(
EventSpeaker $speaker,
DateTimeImmutable $startDate,
DateTimeImmutable $endDate
private EventSpeaker $speaker,
private DateTimeImmutable $startDate,
private DateTimeImmutable $endDate,
) {
$this->speaker = $speaker;
$this->startDate = $startDate;
$this->endDate = $endDate;
}
public function getSpeaker(): EventSpeaker

View File

@@ -8,38 +8,14 @@ use function sprintf;
final class EventSpeaker
{
/** @var string */
private $name;
/** @var string */
private $avatarUrl;
/** @var string */
private $topic;
/** @var string */
private $topicSlug;
/** @var string */
private $description;
/** @var string */
private $youTubeVideoId;
public function __construct(
string $name,
string $avatarUrl,
string $topic,
string $topicSlug,
string $description,
string $youTubeVideoId
private string $name,
private string $avatarUrl,
private string $topic,
private string $topicSlug,
private string $description,
private string $youTubeVideoId,
) {
$this->name = $name;
$this->avatarUrl = $avatarUrl;
$this->topic = $topic;
$this->topicSlug = $topicSlug;
$this->description = $description;
$this->youTubeVideoId = $youTubeVideoId;
}
public function getName(): string

View File

@@ -14,17 +14,9 @@ use function assert;
/** @template-extends AbstractLazyCollection<string, EventSpeaker> */
final class EventSpeakers extends AbstractLazyCollection
{
/** @var mixed[] */
private $event;
/** @var ObjectManagerInterface */
private $objectManager;
/** @param mixed[] $event */
public function __construct(array $event, ObjectManagerInterface $objectManager)
public function __construct(private array $event, private ObjectManagerInterface $objectManager)
{
$this->event = $event;
$this->objectManager = $objectManager;
}
protected function doInitialize(): void
@@ -44,8 +36,8 @@ final class EventSpeakers extends AbstractLazyCollection
$topicSlug = (string) ($speaker['topicSlug'] ?? '');
$speakers[$topicSlug] = new EventSpeaker(
$teamMember !== null ? $teamMember->getName() : $speakerName,
$teamMember !== null ? $teamMember->getAvatarUrl() : (string) ($speaker['avatarUrl'] ?? ''),
$teamMember?->getName() ?? $speakerName,
$teamMember?->getAvatarUrl() ?? (string) ($speaker['avatarUrl'] ?? ''),
(string) ($speaker['topic'] ?? ''),
$topicSlug,
(string) ($speaker['description'] ?? ''),

View File

@@ -6,24 +6,8 @@ namespace Doctrine\Website\Model;
final class EventSponsor
{
/** @var string */
private $name;
/** @var string */
private $url;
/** @var string */
private $logo;
/** @var UtmParameters */
private $utmParameters;
public function __construct(string $name, string $url, string $logo, UtmParameters $utmParameters)
public function __construct(private string $name, private string $url, private string $logo, private UtmParameters $utmParameters)
{
$this->name = $name;
$this->url = $url;
$this->logo = $logo;
$this->utmParameters = $utmParameters;
}
public function getName(): string

View File

@@ -12,13 +12,9 @@ use function array_merge;
/** @template-extends AbstractLazyCollection<int, EventSponsor> */
final class EventSponsors extends AbstractLazyCollection
{
/** @var mixed[] */
private $event;
/** @param mixed[] $event */
public function __construct(array $event)
public function __construct(private array $event)
{
$this->event = $event;
}
protected function doInitialize(): void

View File

@@ -9,29 +9,21 @@ use Doctrine\SkeletonMapper\Mapping\LoadMetadataInterface;
final class Partner implements LoadMetadataInterface
{
/** @var string */
private $name;
private string $name;
/** @var string */
private $slug;
private string $slug;
/** @var string */
private $url;
private string $url;
/** @var UtmParameters */
private $utmParameters;
private UtmParameters $utmParameters;
/** @var string */
private $logo;
private string $logo;
/** @var string */
private $bio;
private string $bio;
/** @var PartnerDetails */
private $details;
private PartnerDetails $details;
/** @var bool */
private $featured;
private bool $featured;
public static function loadMetadata(ClassMetadataInterface $metadata): void
{

View File

@@ -6,17 +6,9 @@ namespace Doctrine\Website\Model;
final class PartnerDetails
{
/** @var string */
private $label;
/** @var string[] */
private $items;
/** @param string[] $items */
public function __construct(string $label, array $items)
public function __construct(private string $label, private array $items)
{
$this->label = $label;
$this->items = $items;
}
public function getLabel(): string

View File

@@ -15,66 +15,50 @@ use function sprintf;
class Project implements LoadMetadataInterface
{
/** @var ProjectIntegrationType|null */
private $projectIntegrationType;
private ProjectIntegrationType|null $projectIntegrationType = null;
/** @var ProjectStats */
private $projectStats;
private ProjectStats $projectStats;
/** @var bool */
private $active;
private bool $active;
/** @var bool */
private $archived;
private bool $archived;
/** @var string */
private $name;
private string $name;
/** @var string */
private $shortName;
private string $shortName;
/** @var string */
private $slug;
private string $slug;
/** @var string */
private $docsSlug;
private string $docsSlug;
/** @var string */
private $composerPackageName;
private string $composerPackageName;
/** @var string */
private $repositoryName;
private string $repositoryName;
/** @var bool */
private $isIntegration = false;
private bool $isIntegration = false;
/** @var string */
private $integrationFor;
private string $integrationFor;
/** @var string */
private $docsRepositoryName;
private string $docsRepositoryName;
/** @var string */
private $docsPath;
private string $docsPath;
/** @var string */
private $codePath;
private string $codePath;
/** @var string */
private $description;
private string $description;
/** @var string[] */
private $keywords = [];
private array $keywords = [];
/** @var ProjectVersion[] */
private $versions = [];
private array $versions = [];
public static function loadMetadata(ClassMetadataInterface $metadata): void
{
$metadata->setIdentifier(['slug']);
}
public function getProjectIntegrationType(): ?ProjectIntegrationType
public function getProjectIntegrationType(): ProjectIntegrationType|null
{
return $this->projectIntegrationType;
}
@@ -161,7 +145,7 @@ class Project implements LoadMetadataInterface
}
/** @return ProjectVersion[] */
public function getVersions(?Closure $filter = null): array
public function getVersions(Closure|null $filter = null): array
{
if ($filter !== null) {
return array_values(array_filter($this->versions, $filter));
@@ -200,7 +184,7 @@ class Project implements LoadMetadataInterface
return $projectVersion;
}
public function getCurrentVersion(): ?ProjectVersion
public function getCurrentVersion(): ProjectVersion|null
{
return $this->getVersions(static function (ProjectVersion $version): bool {
return $version->isCurrent();
@@ -230,7 +214,7 @@ class Project implements LoadMetadataInterface
public function getProjectVersionDocsOutputPath(
string $outputPath,
ProjectVersion $version,
string $language
string $language,
): string {
return $outputPath . '/projects/' . $this->getDocsSlug() . '/' . $language . '/' . $version->getSlug();
}

View File

@@ -9,36 +9,28 @@ use Doctrine\SkeletonMapper\Mapping\LoadMetadataInterface;
class ProjectContributor implements LoadMetadataInterface, CommitterStats
{
/** @var TeamMember|null */
private $teamMember;
private TeamMember|null $teamMember = null;
/** @var string */
private $projectSlug;
private string $projectSlug;
/** @var Project */
private $project;
private Project $project;
/** @var string */
private $github;
private string $github;
/** @var string */
private $avatarUrl;
private string $avatarUrl;
/** @var int */
private $numCommits;
private int $numCommits;
/** @var int */
private $numAdditions;
private int $numAdditions;
/** @var int */
private $numDeletions;
private int $numDeletions;
public static function loadMetadata(ClassMetadataInterface $metadata): void
{
$metadata->setIdentifier(['projectSlug', 'github']);
}
public function getTeamMember(): ?TeamMember
public function getTeamMember(): TeamMember|null
{
return $this->teamMember;
}

View File

@@ -6,14 +6,11 @@ namespace Doctrine\Website\Model;
class ProjectIntegrationType
{
/** @var string */
private $name;
private string $name;
/** @var string */
private $url;
private string $url;
/** @var string */
private $icon;
private string $icon;
/** @param mixed[] $projectIntegrationType */
public function __construct(array $projectIntegrationType)

View File

@@ -6,53 +6,17 @@ namespace Doctrine\Website\Model;
final class ProjectStats
{
/** @var int */
private $githubStars = 0;
/** @var int */
private $githubWatchers = 0;
/** @var int */
private $githubForks = 0;
/** @var int */
private $githubOpenIssues = 0;
/** @var int */
private $dependents = 0;
/** @var int */
private $suggesters = 0;
/** @var int */
private $totalDownloads = 0;
/** @var int */
private $monthlyDownloads = 0;
/** @var int */
private $dailyDownloads = 0;
public function __construct(
int $githubStars,
int $githubWatchers,
int $githubForks,
int $githubOpenIssues,
int $dependents,
int $suggesters,
int $totalDownloads,
int $monthlyDownloads,
int $dailyDownloads
private int $githubStars = 0,
private int $githubWatchers = 0,
private int $githubForks = 0,
private int $githubOpenIssues = 0,
private int $dependents = 0,
private int $suggesters = 0,
private int $totalDownloads = 0,
private int $monthlyDownloads = 0,
private int $dailyDownloads = 0,
) {
$this->githubStars = $githubStars;
$this->githubWatchers = $githubWatchers;
$this->githubForks = $githubForks;
$this->githubOpenIssues = $githubOpenIssues;
$this->dependents = $dependents;
$this->suggesters = $suggesters;
$this->totalDownloads = $totalDownloads;
$this->monthlyDownloads = $monthlyDownloads;
$this->dailyDownloads = $dailyDownloads;
}
public function getGithubStars(): int

View File

@@ -21,35 +21,28 @@ class ProjectVersion
private const STABLE = 'stable';
private const UNMAINTAINED = 'unmaintained';
/** @var string */
private $name;
private string $name;
/** @var string */
private $branchName;
private string|null $branchName;
/** @var string */
private $slug;
private string $slug;
/** @var bool */
private $current = false;
private bool $current = false;
/** @var bool */
private $maintained = true;
private bool $maintained = true;
/** @var bool */
private $upcoming = false;
private bool $upcoming = false;
/** @var bool */
private $hasDocs = true;
private bool $hasDocs = true;
/** @var RSTLanguage[] */
private $docsLanguages = [];
private array $docsLanguages = [];
/** @var string[] */
private $aliases;
private array $aliases;
/** @var Tag[] */
private $tags;
private array $tags;
/** @param mixed[] $version */
public function __construct(array $version)
@@ -95,7 +88,7 @@ class ProjectVersion
return $this->name;
}
public function getBranchName(): ?string
public function getBranchName(): string|null
{
return $this->branchName;
}
@@ -159,12 +152,12 @@ class ProjectVersion
throw new InvalidArgumentException(sprintf('Could not find tag "%s".', $slug));
}
public function getFirstTag(): ?Tag
public function getFirstTag(): Tag|null
{
return $this->tags[0] ?? null;
}
public function getLatestTag(): ?Tag
public function getLatestTag(): Tag|null
{
$latestTag = end($this->tags);
@@ -199,7 +192,7 @@ class ProjectVersion
return self::UPCOMING;
}
public function getStabilityColor(?string $stability = null): string
public function getStabilityColor(string|null $stability = null): string
{
$map = [
'upcoming' => 'warning',
@@ -211,7 +204,7 @@ class ProjectVersion
'dev' => 'primary',
];
$stability = $stability ?? $this->getStability();
$stability ??= $this->getStability();
return $map[$stability] ?? 'secondary';
}

View File

@@ -10,16 +10,8 @@ use Doctrine\SkeletonMapper\Mapping\LoadMetadataInterface;
class SitemapPage implements LoadMetadataInterface
{
/** @var string */
private $url;
/** @var DateTimeImmutable */
private $date;
public function __construct(string $url, DateTimeImmutable $date)
public function __construct(private string $url, private DateTimeImmutable $date)
{
$this->url = $url;
$this->date = $date;
}
public static function loadMetadata(ClassMetadataInterface $metadata): void

Some files were not shown because too many files have changed in this diff Show More