diff --git a/.github/workflows/testing.yaml b/.github/workflows/testing.yaml index 4dbcc519..6afe76b7 100644 --- a/.github/workflows/testing.yaml +++ b/.github/workflows/testing.yaml @@ -51,6 +51,9 @@ jobs: - name: Validate Composer run: composer validate --strict + - name: Warmup cache for PHPStan + run: APP_ENV=dev bin/console kimai:reload -n + - name: Check codestyles run: vendor/bin/php-cs-fixer fix --dry-run --verbose --config=.php-cs-fixer.dist.php --using-cache=no --show-progress=none --format=checkstyle | cs2pr diff --git a/composer.json b/composer.json index 8a1eaebf..01d229a8 100644 --- a/composer.json +++ b/composer.json @@ -79,7 +79,7 @@ "doctrine/doctrine-fixtures-bundle": "^3.2", "fakerphp/faker": "^1.15", "friendsofphp/php-cs-fixer": "3.2.*", - "phpstan/phpstan": "1.4.0", + "phpstan/phpstan": "^1.0", "phpstan/phpstan-doctrine": "^1.0", "phpstan/phpstan-phpunit": "^1.0", "phpstan/phpstan-symfony": "^1.0", diff --git a/composer.lock b/composer.lock index fafe6afe..bb1e1682 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "3e985073360a85ce7e4f13f550b1da94", + "content-hash": "5dde0b8628ebb8a37360ca2726f224df", "packages": [ { "name": "beberlei/doctrineextensions", @@ -11778,16 +11778,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.4.0", + "version": "1.4.2", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "72b04d97b5e6e60a081f17c416fef35bd521120b" + "reference": "1dd8f3e40bf7aa30031a75c65cece99220a161b8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/72b04d97b5e6e60a081f17c416fef35bd521120b", - "reference": "72b04d97b5e6e60a081f17c416fef35bd521120b", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/1dd8f3e40bf7aa30031a75c65cece99220a161b8", + "reference": "1dd8f3e40bf7aa30031a75c65cece99220a161b8", "shasum": "" }, "require": { @@ -11818,7 +11818,7 @@ "description": "PHPStan - PHP Static Analysis Tool", "support": { "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/1.4.0" + "source": "https://github.com/phpstan/phpstan/tree/1.4.2" }, "funding": [ { @@ -11838,25 +11838,25 @@ "type": "tidelift" } ], - "time": "2022-01-14T15:58:47+00:00" + "time": "2022-01-18T16:09:11+00:00" }, { "name": "phpstan/phpstan-doctrine", - "version": "1.0.4", + "version": "1.2.3", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-doctrine.git", - "reference": "251d9556737b01ec9bb01afa540550de04fa595b" + "reference": "16cb23af853014620473a0c72d188cf76b9a9401" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-doctrine/zipball/251d9556737b01ec9bb01afa540550de04fa595b", - "reference": "251d9556737b01ec9bb01afa540550de04fa595b", + "url": "https://api.github.com/repos/phpstan/phpstan-doctrine/zipball/16cb23af853014620473a0c72d188cf76b9a9401", + "reference": "16cb23af853014620473a0c72d188cf76b9a9401", "shasum": "" }, "require": { "php": "^7.1 || ^8.0", - "phpstan/phpstan": "^1.3" + "phpstan/phpstan": "^1.4.1" }, "conflict": { "doctrine/collections": "<1.0", @@ -11869,11 +11869,11 @@ "doctrine/annotations": "^1.11.0", "doctrine/collections": "^1.6", "doctrine/common": "^2.7 || ^3.0", - "doctrine/dbal": "^2.13.7", + "doctrine/dbal": "^2.13.7 || ^3.0", "doctrine/lexer": "^1.2.1", "doctrine/mongodb-odm": "^1.3 || ^2.1", "doctrine/orm": "^2.11.0", - "doctrine/persistence": "^1.1 || ^2.0", + "doctrine/persistence": "^1.3.8 || ^2.2.1", "nesbot/carbon": "^2.49", "nikic/php-parser": "^4.13.2", "php-parallel-lint/php-parallel-lint": "^1.2", @@ -11886,7 +11886,7 @@ "type": "phpstan-extension", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "1.2-dev" }, "phpstan": { "includes": [ @@ -11907,9 +11907,9 @@ "description": "Doctrine extensions for PHPStan", "support": { "issues": "https://github.com/phpstan/phpstan-doctrine/issues", - "source": "https://github.com/phpstan/phpstan-doctrine/tree/1.0.4" + "source": "https://github.com/phpstan/phpstan-doctrine/tree/1.2.3" }, - "time": "2022-01-16T07:46:10+00:00" + "time": "2022-01-23T12:35:08+00:00" }, { "name": "phpstan/phpstan-phpunit", diff --git a/phpstan.neon b/phpstan.neon index 73877dc8..0423af3b 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,8 +1,9 @@ includes: - - vendor/phpstan/phpstan-symfony/extension.neon - - vendor/phpstan/phpstan-doctrine/extension.neon - - vendor/phpstan/phpstan-symfony/rules.neon - - vendor/phpstan/phpstan/conf/bleedingEdge.neon + - %rootDir%/../phpstan-symfony/extension.neon + - %rootDir%/../phpstan-symfony/rules.neon + - %rootDir%/../phpstan-doctrine/extension.neon + - %rootDir%/../phpstan-doctrine/rules.neon + - %rootDir%/../phpstan/conf/bleedingEdge.neon parameters: tmpDir: %rootDir%/../../../var/cache/phpstan @@ -11,4 +12,8 @@ parameters: excludePaths: - %rootDir%/../../../src/Ldap/LdapDriver.php treatPhpDocTypesAsCertain: false - inferPrivatePropertyTypeFromConstructor: true \ No newline at end of file + inferPrivatePropertyTypeFromConstructor: true + doctrine: + objectManagerLoader: %rootDir%/../../../tests/phpstan-doctrine.php + symfony: + containerXmlPath: %rootDir%/../../../var/cache/dev/srcApp_KernelDevDebugContainer.xml diff --git a/src/DependencyInjection/AppExtension.php b/src/DependencyInjection/AppExtension.php index c1cd5fec..157a579b 100644 --- a/src/DependencyInjection/AppExtension.php +++ b/src/DependencyInjection/AppExtension.php @@ -100,6 +100,7 @@ class AppExtension extends Extension $container->setParameter('kimai.i18n_domains', $localTranslations); // this should happen always at the end, so bundles do not mess with the base configuration + /* @phpstan-ignore-next-line */ if ($container->hasParameter('kimai.bundles.config')) { $bundleConfig = $container->getParameter('kimai.bundles.config'); if (!\is_array($bundleConfig)) { diff --git a/src/Entity/Activity.php b/src/Entity/Activity.php index da0aed84..5291e5d5 100644 --- a/src/Entity/Activity.php +++ b/src/Entity/Activity.php @@ -99,7 +99,7 @@ class Activity implements EntityWithMetaFields, EntityWithBudget /** * Description of this activity * - * @var string + * @var string|null * * @Serializer\Expose() * @Serializer\Groups({"Activity_Entity"}) diff --git a/src/Entity/BudgetTrait.php b/src/Entity/BudgetTrait.php index 055f5598..684e788a 100644 --- a/src/Entity/BudgetTrait.php +++ b/src/Entity/BudgetTrait.php @@ -51,7 +51,7 @@ trait BudgetTrait * - null = default / full time * - month = monthly budget * - * @var string + * @var string|null * * @Serializer\Expose() * @Serializer\Groups({"Activity_Entity", "Project_Entity", "Customer_Entity"}) diff --git a/src/Entity/ColorTrait.php b/src/Entity/ColorTrait.php index 06c83971..1984b3cd 100644 --- a/src/Entity/ColorTrait.php +++ b/src/Entity/ColorTrait.php @@ -20,7 +20,7 @@ trait ColorTrait /** * The assigned color in HTML hex format, eg. #dd1d00 * - * @var string + * @var string|null * * @Serializer\Expose() * @Serializer\Groups({"Default"}) @@ -32,9 +32,6 @@ trait ColorTrait */ private $color = null; - /** - * @return string - */ public function getColor(): ?string { if ($this->color === Constants::DEFAULT_COLOR) { @@ -49,9 +46,6 @@ trait ColorTrait return null !== $this->color && $this->color !== Constants::DEFAULT_COLOR; } - /** - * @param string $color - */ public function setColor(?string $color = null): void { $this->color = $color; diff --git a/src/Entity/Configuration.php b/src/Entity/Configuration.php index 634be521..2d46a279 100644 --- a/src/Entity/Configuration.php +++ b/src/Entity/Configuration.php @@ -30,10 +30,8 @@ class Configuration * @ORM\Id * @ORM\GeneratedValue * @ORM\Column(name="id", type="integer") - * @phpstan-ignore-next-line */ private $id; - /** * @var string * @@ -42,9 +40,8 @@ class Configuration * @Assert\Length(min=2, max=100, allowEmptyString=false) */ private $name; - /** - * @var string + * @var string|null * * @ORM\Column(name="value", type="string", length=1024, nullable=true) * @Assert\Length(max=1024, allowEmptyString=true) diff --git a/src/Entity/Customer.php b/src/Entity/Customer.php index 2dae7328..5fc6bd39 100644 --- a/src/Entity/Customer.php +++ b/src/Entity/Customer.php @@ -64,7 +64,7 @@ class Customer implements EntityWithMetaFields, EntityWithBudget */ private $name; /** - * @var string + * @var string|null * * @Serializer\Expose() * @Serializer\Groups({"Default"}) @@ -76,7 +76,7 @@ class Customer implements EntityWithMetaFields, EntityWithBudget */ private $number; /** - * @var string + * @var string|null * * @Serializer\Expose() * @Serializer\Groups({"Customer_Entity"}) @@ -99,7 +99,7 @@ class Customer implements EntityWithMetaFields, EntityWithBudget */ private $visible = true; /** - * @var string + * @var string|null * * @Serializer\Expose() * @Serializer\Groups({"Customer_Entity"}) @@ -111,7 +111,7 @@ class Customer implements EntityWithMetaFields, EntityWithBudget */ private $company; /** - * @var string + * @var string|null * * @Serializer\Expose() * @Serializer\Groups({"Customer_Entity"}) @@ -123,7 +123,7 @@ class Customer implements EntityWithMetaFields, EntityWithBudget */ private $vatId; /** - * @var string + * @var string|null * * @Serializer\Expose() * @Serializer\Groups({"Customer_Entity"}) @@ -135,7 +135,7 @@ class Customer implements EntityWithMetaFields, EntityWithBudget */ private $contact; /** - * @var string + * @var string|null * * @Serializer\Expose() * @Serializer\Groups({"Customer_Entity"}) @@ -174,7 +174,7 @@ class Customer implements EntityWithMetaFields, EntityWithBudget */ private $currency = self::DEFAULT_CURRENCY; /** - * @var string + * @var string|null * * @Serializer\Expose() * @Serializer\Groups({"Customer_Entity"}) @@ -186,7 +186,7 @@ class Customer implements EntityWithMetaFields, EntityWithBudget */ private $phone; /** - * @var string + * @var string|null * * @Serializer\Expose() * @Serializer\Groups({"Customer_Entity"}) @@ -198,7 +198,7 @@ class Customer implements EntityWithMetaFields, EntityWithBudget */ private $fax; /** - * @var string + * @var string|null * * @Serializer\Expose() * @Serializer\Groups({"Customer_Entity"}) @@ -214,7 +214,7 @@ class Customer implements EntityWithMetaFields, EntityWithBudget * * Limited via RFC to 254 chars * - * @var string + * @var string|null * * @Serializer\Expose() * @Serializer\Groups({"Customer_Entity"}) @@ -226,7 +226,7 @@ class Customer implements EntityWithMetaFields, EntityWithBudget */ private $email; /** - * @var string + * @var string|null * * @Serializer\Expose() * @Serializer\Groups({"Customer_Entity"}) diff --git a/src/Entity/Invoice.php b/src/Entity/Invoice.php index 3e8dd6b5..b7d9e642 100644 --- a/src/Entity/Invoice.php +++ b/src/Entity/Invoice.php @@ -53,7 +53,6 @@ class Invoice implements EntityWithMetaFields * @ORM\GeneratedValue(strategy="IDENTITY") */ private $id; - /** * @var string * @@ -63,9 +62,8 @@ class Invoice implements EntityWithMetaFields * @Assert\NotNull() */ private $invoiceNumber; - /** - * @var string + * @var string|null * * @Serializer\Expose() * @Serializer\Groups({"Customer_Entity"}) @@ -75,25 +73,22 @@ class Invoice implements EntityWithMetaFields * @ORM\Column(name="comment", type="text", nullable=true) */ private $comment; - /** - * @var Customer|null + * @var Customer * * @ORM\ManyToOne(targetEntity="App\Entity\Customer") * @ORM\JoinColumn(onDelete="CASCADE", nullable=false) * @Assert\NotNull() */ private $customer; - /** - * @var User|null + * @var User * * @ORM\ManyToOne(targetEntity="App\Entity\User") * @ORM\JoinColumn(onDelete="CASCADE", nullable=false) * @Assert\NotNull() */ private $user; - /** * @var \DateTime * @@ -103,14 +98,12 @@ class Invoice implements EntityWithMetaFields * @Assert\NotNull() */ private $createdAt; - /** * @var string * * @ORM\Column(name="timezone", type="string", length=64, nullable=false) */ private $timezone; - /** * @var float * @@ -120,7 +113,6 @@ class Invoice implements EntityWithMetaFields * @Assert\NotNull() */ private $total = 0.00; - /** * @var float * @@ -130,7 +122,6 @@ class Invoice implements EntityWithMetaFields * @Assert\NotNull() */ private $tax = 0.00; - /** * @var string * @@ -141,7 +132,6 @@ class Invoice implements EntityWithMetaFields * @Assert\Length(max=3) */ private $currency; - /** * @var int * @@ -152,7 +142,6 @@ class Invoice implements EntityWithMetaFields * @Assert\Range(min = 0, max = 999) */ private $dueDays = 30; - /** * @var float * @@ -163,7 +152,6 @@ class Invoice implements EntityWithMetaFields * @Assert\Range(min = 0.0, max = 99.99) */ private $vat = 0.00; - /** * @var string * @@ -173,7 +161,6 @@ class Invoice implements EntityWithMetaFields * @Assert\NotNull() */ private $status = self::STATUS_NEW; - /** * @var string * @@ -184,19 +171,16 @@ class Invoice implements EntityWithMetaFields * @Assert\Length(min=1, max=150, allowEmptyString=false) */ private $invoiceFilename; - /** * @var bool */ private $localized = false; - /** * @var \DateTime|null * * @ORM\Column(name="payment_date", type="date", nullable=true) */ private $paymentDate; - /** * Meta fields * diff --git a/src/Entity/InvoiceTemplate.php b/src/Entity/InvoiceTemplate.php index 11bb89aa..260260e0 100644 --- a/src/Entity/InvoiceTemplate.php +++ b/src/Entity/InvoiceTemplate.php @@ -32,7 +32,6 @@ class InvoiceTemplate * @ORM\GeneratedValue(strategy="IDENTITY") */ private $id; - /** * @var string * @@ -41,7 +40,6 @@ class InvoiceTemplate * @Assert\Length(min=1, max=60, allowEmptyString=false) */ private $name; - /** * @var string * @@ -49,7 +47,6 @@ class InvoiceTemplate * @Assert\NotBlank() */ private $title; - /** * @var string * @@ -57,29 +54,25 @@ class InvoiceTemplate * @Assert\NotBlank() */ private $company; - /** - * @var string + * @var string|null * * @ORM\Column(name="vat_id", type="string", length=50, nullable=true) * @Assert\Length(max=50) */ private $vatId; - /** - * @var string + * @var string|null * * @ORM\Column(name="address", type="text", nullable=true) */ private $address; - /** - * @var string + * @var string|null * * @ORM\Column(name="contact", type="text", nullable=true) */ private $contact; - /** * @var int * @@ -87,7 +80,6 @@ class InvoiceTemplate * @Assert\Range(min = 0, max = 999) */ private $dueDays = 30; - /** * @var float * @@ -95,7 +87,6 @@ class InvoiceTemplate * @Assert\Range(min = 0.0, max = 99.99) */ private $vat = 0.00; - /** * @var string * @@ -112,7 +103,6 @@ class InvoiceTemplate * @Assert\Length(max=20) */ private $numberGenerator = 'default'; - /** * @var string * @@ -121,21 +111,18 @@ class InvoiceTemplate * @Assert\Length(max=20) */ private $renderer = 'default'; - /** - * @var string + * @var string|null * * @ORM\Column(name="payment_terms", type="text", nullable=true) */ private $paymentTerms; - /** - * @var string + * @var string|null * * @ORM\Column(name="payment_details", type="text", nullable=true) */ private $paymentDetails; - /** * Used when rendering HTML templates. * @@ -145,11 +132,10 @@ class InvoiceTemplate * @Assert\NotNull() */ private $decimalDuration = false; - /** * Used for translations and locale dependent number and date formats. * - * @var string + * @var string|null * * @ORM\Column(name="language", type="string", length=6, nullable=true) */ diff --git a/src/Entity/MetaTableTypeTrait.php b/src/Entity/MetaTableTypeTrait.php index d0ddeb19..5153e906 100644 --- a/src/Entity/MetaTableTypeTrait.php +++ b/src/Entity/MetaTableTypeTrait.php @@ -45,7 +45,7 @@ trait MetaTableTypeTrait /** * Value of the meta (custom) field * - * @var string + * @var string|null * * @Serializer\Expose() * @Serializer\Groups({"Default"}) diff --git a/src/Entity/Project.php b/src/Entity/Project.php index fb3523d2..00b1c59e 100644 --- a/src/Entity/Project.php +++ b/src/Entity/Project.php @@ -104,7 +104,7 @@ class Project implements EntityWithMetaFields, EntityWithBudget /** * Project order number * - * @var string + * @var string|null * * @Serializer\Expose() * @Serializer\Groups({"Project_Entity"}) @@ -116,7 +116,7 @@ class Project implements EntityWithMetaFields, EntityWithBudget */ private $orderNumber; /** - * @var \DateTime + * @var \DateTime|null * * @Serializer\Expose() * @Serializer\Groups({"Project_Entity"}) @@ -131,7 +131,7 @@ class Project implements EntityWithMetaFields, EntityWithBudget */ private $orderDate; /** - * @var \DateTime + * @var \DateTime|null * * @Serializer\Expose() * @Serializer\Groups({"Project"}) @@ -146,7 +146,7 @@ class Project implements EntityWithMetaFields, EntityWithBudget */ private $start; /** - * @var \DateTime + * @var \DateTime|null * * @Serializer\Expose() * @Serializer\Groups({"Project"}) @@ -161,7 +161,7 @@ class Project implements EntityWithMetaFields, EntityWithBudget */ private $end; /** - * @var string + * @var string|null * @internal used for storing the timezone for "order", "start" and "end" date * * @ORM\Column(name="timezone", type="string", length=64, nullable=true) @@ -173,7 +173,7 @@ class Project implements EntityWithMetaFields, EntityWithBudget */ private $localized = false; /** - * @var string + * @var string|null * * @Serializer\Expose() * @Serializer\Groups({"Project_Entity"}) diff --git a/src/Entity/Rate.php b/src/Entity/Rate.php index 270234e4..bd75b3ee 100644 --- a/src/Entity/Rate.php +++ b/src/Entity/Rate.php @@ -28,7 +28,7 @@ trait Rate */ private $id; /** - * @var User + * @var User|null * * @Serializer\Expose() * @Serializer\Groups({"Default"}) diff --git a/src/Entity/Role.php b/src/Entity/Role.php index c6f45aa6..73a88198 100644 --- a/src/Entity/Role.php +++ b/src/Entity/Role.php @@ -30,7 +30,6 @@ class Role * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="IDENTITY") - * @phpstan-ignore-next-line */ private $id; /** diff --git a/src/Entity/RolePermission.php b/src/Entity/RolePermission.php index 6a1e49f6..800e8bbf 100644 --- a/src/Entity/RolePermission.php +++ b/src/Entity/RolePermission.php @@ -30,7 +30,6 @@ class RolePermission * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="IDENTITY") - * @phpstan-ignore-next-line */ private $id; /** diff --git a/src/Entity/Tag.php b/src/Entity/Tag.php index b5bd765b..c7a6ddb4 100644 --- a/src/Entity/Tag.php +++ b/src/Entity/Tag.php @@ -39,7 +39,6 @@ class Tag * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="IDENTITY") - * @phpstan-ignore-next-line */ private $id; /** diff --git a/src/Entity/Team.php b/src/Entity/Team.php index 3586ab72..74d9310b 100644 --- a/src/Entity/Team.php +++ b/src/Entity/Team.php @@ -59,7 +59,7 @@ class Team /** * All team member (including team leads) * - * @var TeamMember[]|Collection + * @var Collection * * @Serializer\Expose() * @Serializer\Groups({"Team_Entity"}) diff --git a/src/Entity/TeamMember.php b/src/Entity/TeamMember.php index 8e101bda..67c3d742 100644 --- a/src/Entity/TeamMember.php +++ b/src/Entity/TeamMember.php @@ -32,7 +32,6 @@ class TeamMember * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="IDENTITY") - * @phpstan-ignore-next-line */ private $id; /** diff --git a/src/Entity/Timesheet.php b/src/Entity/Timesheet.php index bb69c990..c46c71de 100644 --- a/src/Entity/Timesheet.php +++ b/src/Entity/Timesheet.php @@ -134,7 +134,7 @@ class Timesheet implements EntityWithMetaFields, ExportItemInterface */ private $begin; /** - * @var DateTime + * @var DateTime|null * * @Serializer\Expose() * @Serializer\Groups({"Default"}) @@ -160,7 +160,7 @@ class Timesheet implements EntityWithMetaFields, ExportItemInterface */ private $localized = false; /** - * @var int + * @var int|null * * @Serializer\Expose() * @Serializer\Groups({"Default"}) @@ -202,7 +202,7 @@ class Timesheet implements EntityWithMetaFields, ExportItemInterface */ private $project; /** - * @var string + * @var string|null * * @Serializer\Expose() * @Serializer\Groups({"Default"}) @@ -240,7 +240,7 @@ class Timesheet implements EntityWithMetaFields, ExportItemInterface */ private $fixedRate = null; /** - * @var float + * @var float|null * * @Serializer\Expose() * @Serializer\Groups({"Entity"}) diff --git a/src/Entity/User.php b/src/Entity/User.php index 0210200d..a0447b5f 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -100,7 +100,7 @@ class User implements UserInterface, EquatableInterface, \Serializable /** * The user alias will be displayed in the frontend instead of the username * - * @var string + * @var string|null * * @Serializer\Expose() * @Serializer\Groups({"Default"}) @@ -114,7 +114,7 @@ class User implements UserInterface, EquatableInterface, \Serializable /** * Registration date for the user * - * @var DateTime + * @var DateTime|null * * @Exporter\Expose(label="profile.registration_date", type="datetime") * @@ -124,7 +124,7 @@ class User implements UserInterface, EquatableInterface, \Serializable /** * An additional title for the user, like the Job position or Department * - * @var string + * @var string|null * * @Serializer\Expose() * @Serializer\Groups({"User_Entity"}) @@ -136,9 +136,9 @@ class User implements UserInterface, EquatableInterface, \Serializable */ private $title; /** - * URL to the users avatar, will be auto-generated if empty + * URL to the user avatar, will be auto-generated if empty * - * @var string + * @var string|null * * @Serializer\Expose() * @Serializer\Groups({"User_Entity"}) @@ -150,7 +150,7 @@ class User implements UserInterface, EquatableInterface, \Serializable /** * API token (password) for this user * - * @var string + * @var string|null * * @ORM\Column(name="api_token", type="string", length=255, nullable=true) */ @@ -167,7 +167,7 @@ class User implements UserInterface, EquatableInterface, \Serializable * * List of preferences for this user, required ones have dedicated fields/methods * - * @var UserPreference[]|Collection + * @var Collection * * @ORM\OneToMany(targetEntity="App\Entity\UserPreference", mappedBy="user", cascade={"persist"}) */ @@ -175,7 +175,7 @@ class User implements UserInterface, EquatableInterface, \Serializable /** * List of all team memberships. * - * @var TeamMember[]|ArrayCollection + * @var Collection * * @Serializer\Expose() * @Serializer\Groups({"User_Entity"}) @@ -187,9 +187,9 @@ class User implements UserInterface, EquatableInterface, \Serializable */ private $memberships; /** - * The type of authentication used by the user (eg. "kimai", "ldap", "saml") + * The type of authentication used by the user (e.g. "kimai", "ldap", "saml") * - * @var string + * @var string|null * @internal for internal usage only * * @ORM\Column(name="auth", type="string", length=20, nullable=true) diff --git a/src/Entity/UserPreference.php b/src/Entity/UserPreference.php index 0db257a0..84705dd3 100644 --- a/src/Entity/UserPreference.php +++ b/src/Entity/UserPreference.php @@ -49,7 +49,7 @@ class UserPreference * @var User * * @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="preferences") - * @ORM\JoinColumn(onDelete="CASCADE") + * @ORM\JoinColumn(nullable=false, onDelete="CASCADE") * @Assert\NotNull() */ private $user; @@ -65,7 +65,7 @@ class UserPreference */ private $name; /** - * @var string + * @var string|null * * @Serializer\Expose() * @Serializer\Groups({"Default"}) diff --git a/src/Plugin/AbstractPluginExtension.php b/src/Plugin/AbstractPluginExtension.php index 4f5cd2f1..d832135d 100644 --- a/src/Plugin/AbstractPluginExtension.php +++ b/src/Plugin/AbstractPluginExtension.php @@ -18,6 +18,7 @@ abstract class AbstractPluginExtension extends Extension { $bundleConfig = [$this->getAlias() => $configs]; + /* @phpstan-ignore-next-line */ if ($container->hasParameter('kimai.bundles.config')) { $bundleConfig = array_merge( $container->getParameter('kimai.bundles.config'), diff --git a/tests/Command/ActivateUserCommandTest.php b/tests/Command/ActivateUserCommandTest.php index 767b2138..4a344b9c 100644 --- a/tests/Command/ActivateUserCommandTest.php +++ b/tests/Command/ActivateUserCommandTest.php @@ -31,6 +31,7 @@ class ActivateUserCommandTest extends KernelTestCase protected function setUp(): void { + parent::setUp(); $kernel = self::bootKernel(); $this->application = new Application($kernel); $container = self::$kernel->getContainer(); diff --git a/tests/Command/ChangePasswordCommandTest.php b/tests/Command/ChangePasswordCommandTest.php index 0db566de..54c0545c 100644 --- a/tests/Command/ChangePasswordCommandTest.php +++ b/tests/Command/ChangePasswordCommandTest.php @@ -31,6 +31,7 @@ class ChangePasswordCommandTest extends KernelTestCase protected function setUp(): void { + parent::setUp(); $kernel = self::bootKernel(); $this->application = new Application($kernel); $container = self::$kernel->getContainer(); diff --git a/tests/Command/CreateUserCommandTest.php b/tests/Command/CreateUserCommandTest.php index faca77fb..4df9cdbf 100644 --- a/tests/Command/CreateUserCommandTest.php +++ b/tests/Command/CreateUserCommandTest.php @@ -30,6 +30,7 @@ class CreateUserCommandTest extends KernelTestCase protected function setUp(): void { + parent::setUp(); $kernel = self::bootKernel(); $this->application = new Application($kernel); $container = self::$kernel->getContainer(); diff --git a/tests/Command/DeactivateUserCommandTest.php b/tests/Command/DeactivateUserCommandTest.php index a0ffbdfe..ff154518 100644 --- a/tests/Command/DeactivateUserCommandTest.php +++ b/tests/Command/DeactivateUserCommandTest.php @@ -31,6 +31,7 @@ class DeactivateUserCommandTest extends KernelTestCase protected function setUp(): void { + parent::setUp(); $kernel = self::bootKernel(); $this->application = new Application($kernel); $container = self::$kernel->getContainer(); diff --git a/tests/Command/DemoteUserCommandTest.php b/tests/Command/DemoteUserCommandTest.php index 669478ee..10e621f2 100644 --- a/tests/Command/DemoteUserCommandTest.php +++ b/tests/Command/DemoteUserCommandTest.php @@ -32,6 +32,7 @@ class DemoteUserCommandTest extends KernelTestCase protected function setUp(): void { + parent::setUp(); $kernel = self::bootKernel(); $this->application = new Application($kernel); $container = self::$kernel->getContainer(); diff --git a/tests/Command/ImportCustomerCommandTest.php b/tests/Command/ImportCustomerCommandTest.php index ac153bd1..55f1fe96 100644 --- a/tests/Command/ImportCustomerCommandTest.php +++ b/tests/Command/ImportCustomerCommandTest.php @@ -27,6 +27,7 @@ class ImportCustomerCommandTest extends KernelTestCase protected function setUp(): void { + parent::setUp(); $kernel = self::bootKernel(); $this->application = new Application($kernel); $container = self::$kernel->getContainer(); diff --git a/tests/Command/ImportProjectCommandTest.php b/tests/Command/ImportProjectCommandTest.php index 1437fc17..2b694c18 100644 --- a/tests/Command/ImportProjectCommandTest.php +++ b/tests/Command/ImportProjectCommandTest.php @@ -29,6 +29,7 @@ class ImportProjectCommandTest extends KernelTestCase protected function setUp(): void { + parent::setUp(); $kernel = self::bootKernel(); $this->application = new Application($kernel); $container = self::$kernel->getContainer(); diff --git a/tests/Command/ImportTimesheetCommandTest.php b/tests/Command/ImportTimesheetCommandTest.php index d39dfe2c..a6d0af24 100644 --- a/tests/Command/ImportTimesheetCommandTest.php +++ b/tests/Command/ImportTimesheetCommandTest.php @@ -34,6 +34,7 @@ class ImportTimesheetCommandTest extends KernelTestCase protected function setUp(): void { + parent::setUp(); $kernel = self::bootKernel(); $this->application = new Application($kernel); diff --git a/tests/Command/InstallCommandTest.php b/tests/Command/InstallCommandTest.php index 65ae0fd7..c104a12b 100644 --- a/tests/Command/InstallCommandTest.php +++ b/tests/Command/InstallCommandTest.php @@ -26,6 +26,7 @@ class InstallCommandTest extends KernelTestCase protected function setUp(): void { + parent::setUp(); $kernel = self::bootKernel(); $this->application = new Application($kernel); $container = self::$kernel->getContainer(); diff --git a/tests/Command/InvoiceCreateCommandTest.php b/tests/Command/InvoiceCreateCommandTest.php index 758f6dd6..10336120 100644 --- a/tests/Command/InvoiceCreateCommandTest.php +++ b/tests/Command/InvoiceCreateCommandTest.php @@ -61,6 +61,7 @@ class InvoiceCreateCommandTest extends KernelTestCase protected function setUp(): void { + parent::setUp(); $this->clearInvoiceFiles(); $kernel = self::bootKernel(); $this->application = new Application($kernel); diff --git a/tests/Command/KimaiImporterCommandTest.php b/tests/Command/KimaiImporterCommandTest.php index ebe51083..57f9b209 100644 --- a/tests/Command/KimaiImporterCommandTest.php +++ b/tests/Command/KimaiImporterCommandTest.php @@ -29,6 +29,7 @@ class KimaiImporterCommandTest extends KernelTestCase protected function setUp(): void { + parent::setUp(); $kernel = self::bootKernel(); $this->application = new Application($kernel); diff --git a/tests/Command/PromoteUserCommandTest.php b/tests/Command/PromoteUserCommandTest.php index 1f251a05..94ae607f 100644 --- a/tests/Command/PromoteUserCommandTest.php +++ b/tests/Command/PromoteUserCommandTest.php @@ -32,6 +32,7 @@ class PromoteUserCommandTest extends KernelTestCase protected function setUp(): void { + parent::setUp(); $kernel = self::bootKernel(); $this->application = new Application($kernel); $container = self::$kernel->getContainer(); diff --git a/tests/Command/ReloadCommandTest.php b/tests/Command/ReloadCommandTest.php index 2e4f42f8..573f19b8 100644 --- a/tests/Command/ReloadCommandTest.php +++ b/tests/Command/ReloadCommandTest.php @@ -26,6 +26,7 @@ class ReloadCommandTest extends KernelTestCase protected function setUp(): void { + parent::setUp(); $kernel = self::bootKernel(); $this->application = new Application($kernel); $this->application->add(new ReloadCommand()); diff --git a/tests/Command/VersionCommandTest.php b/tests/Command/VersionCommandTest.php index bb69f393..269a355a 100644 --- a/tests/Command/VersionCommandTest.php +++ b/tests/Command/VersionCommandTest.php @@ -28,6 +28,7 @@ class VersionCommandTest extends KernelTestCase protected function setUp(): void { + parent::setUp(); $kernel = self::bootKernel(); $this->application = new Application($kernel); diff --git a/tests/Entity/UserPreferenceTest.php b/tests/Entity/UserPreferenceTest.php index 141015ea..e9b447d8 100644 --- a/tests/Entity/UserPreferenceTest.php +++ b/tests/Entity/UserPreferenceTest.php @@ -46,10 +46,10 @@ class UserPreferenceTest extends TestCase $sut->setType(IntegerType::class); self::assertSame(1, $sut->getValue()); $sut->setType(YesNoType::class); - self::assertSame(true, $sut->getValue()); + self::assertTrue($sut->getValue()); $sut->setValue('0'); $sut->setType(CheckboxType::class); - self::assertSame(false, $sut->getValue()); + self::assertFalse($sut->getValue()); } public function testGetLabelWithLabelOption() diff --git a/tests/Repository/AbstractRepositoryTest.php b/tests/Repository/AbstractRepositoryTest.php index 6ab4c23e..d08c3b2f 100644 --- a/tests/Repository/AbstractRepositoryTest.php +++ b/tests/Repository/AbstractRepositoryTest.php @@ -31,6 +31,7 @@ abstract class AbstractRepositoryTest extends KernelTestCase */ protected function setUp(): void { + parent::setUp(); $kernel = self::bootKernel(); $this->entityManager = $kernel->getContainer() diff --git a/tests/phpstan-doctrine.php b/tests/phpstan-doctrine.php new file mode 100644 index 00000000..34c89351 --- /dev/null +++ b/tests/phpstan-doctrine.php @@ -0,0 +1,19 @@ +loadEnv(dirname(__DIR__) . '/.env'); +$kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']); +$kernel->boot(); + +return $kernel->getContainer()->get('doctrine')->getManager(); diff --git a/tests/phpstan.neon b/tests/phpstan.neon index ec352a75..c73b988a 100644 --- a/tests/phpstan.neon +++ b/tests/phpstan.neon @@ -1,7 +1,10 @@ includes: - %rootDir%/../phpstan-symfony/extension.neon + - %rootDir%/../phpstan-symfony/rules.neon - %rootDir%/../phpstan-doctrine/extension.neon + - %rootDir%/../phpstan-doctrine/rules.neon - %rootDir%/../phpstan-phpunit/extension.neon + - %rootDir%/../phpstan-phpunit/rules.neon parameters: tmpDir: %rootDir%/../../../var/cache/phpstan @@ -9,4 +12,6 @@ parameters: - '#Call to static method PHPUnit\\Framework\\Assert::assertSame\(\) with App\\Entity\\[a-zA-Z0-9]+ and null will always evaluate to false.#' excludePaths: - %rootDir%/../../../tests/Ldap/LdapDriverTest.php - inferPrivatePropertyTypeFromConstructor: true \ No newline at end of file + inferPrivatePropertyTypeFromConstructor: true + doctrine: + objectManagerLoader: %rootDir%/../../../tests/phpstan-doctrine.php