diff --git a/src/Controller/AdminPages/BaseAdminController.php b/src/Controller/AdminPages/BaseAdminController.php index 92f6ee07..cf856e8f 100644 --- a/src/Controller/AdminPages/BaseAdminController.php +++ b/src/Controller/AdminPages/BaseAdminController.php @@ -29,6 +29,7 @@ use App\Entity\Base\AbstractNamedDBElement; use App\Entity\Base\AbstractPartsContainingDBElement; use App\Entity\Base\AbstractStructuralDBElement; use App\Entity\Base\PartsContainingRepositoryInterface; +use App\Entity\LabelSystem\LabelProcessMode; use App\Entity\LabelSystem\LabelProfile; use App\Entity\Parameters\AbstractParameter; use App\Entity\UserSystem\User; @@ -159,7 +160,7 @@ abstract class BaseAdminController extends AbstractController //Disable editing of options, if user is not allowed to use twig... if ( $entity instanceof LabelProfile - && 'twig' === $entity->getOptions()->getProcessMode() + && LabelProcessMode::TWIG === $entity->getOptions()->getProcessMode() && !$this->isGranted('@labels.use_twig') ) { $form_options['disable_options'] = true; diff --git a/src/Controller/LabelController.php b/src/Controller/LabelController.php index 36f9b669..7d98019d 100644 --- a/src/Controller/LabelController.php +++ b/src/Controller/LabelController.php @@ -43,6 +43,7 @@ namespace App\Controller; use App\Entity\Base\AbstractDBElement; use App\Entity\LabelSystem\LabelOptions; +use App\Entity\LabelSystem\LabelProcessMode; use App\Entity\LabelSystem\LabelProfile; use App\Entity\LabelSystem\LabelSupportedElement; use App\Exceptions\TwigModeException; @@ -81,7 +82,7 @@ class LabelController extends AbstractController $label_options = $profile instanceof LabelProfile ? $profile->getOptions() : new LabelOptions(); //We have to disable the options, if twig mode is selected and user is not allowed to use it. - $disable_options = 'twig' === $label_options->getProcessMode() && !$this->isGranted('@labels.use_twig'); + $disable_options = (LabelProcessMode::TWIG === $label_options->getProcessMode()) && !$this->isGranted('@labels.use_twig'); $form = $this->createForm(LabelDialogType::class, null, [ 'disable_options' => $disable_options, diff --git a/src/Controller/ProjectController.php b/src/Controller/ProjectController.php index a15ce97f..08ddc258 100644 --- a/src/Controller/ProjectController.php +++ b/src/Controller/ProjectController.php @@ -176,9 +176,9 @@ class ProjectController extends AbstractController return $this->redirectToRoute('project_edit', ['id' => $project->getID()]); } - if (count ($errors) > 0) { - $this->addFlash('error', t('project.bom_import.flash.invalid_entries')); - } + //When we get here, there were validation errors + $this->addFlash('error', t('project.bom_import.flash.invalid_entries')); + } catch (\UnexpectedValueException|SyntaxError $e) { $this->addFlash('error', t('project.bom_import.flash.invalid_file', ['%message%' => $e->getMessage()])); } diff --git a/src/Controller/WebauthnKeyRegistrationController.php b/src/Controller/WebauthnKeyRegistrationController.php index f2323510..5f2e3e9b 100644 --- a/src/Controller/WebauthnKeyRegistrationController.php +++ b/src/Controller/WebauthnKeyRegistrationController.php @@ -77,9 +77,14 @@ class WebauthnKeyRegistrationController extends AbstractController return $this->redirectToRoute('webauthn_register'); } + $user = $this->getUser(); + if (!$user instanceof User) { + throw new RuntimeException('This controller only works only for Part-DB User objects!'); + } + $keyEntity = WebauthnKey::fromRegistration($new_key); $keyEntity->setName($keyName); - $keyEntity->setUser($this->getUser()); + $keyEntity->setUser($user); $em->persist($keyEntity); $em->flush(); diff --git a/src/DataTables/Filters/Constraints/EntityConstraint.php b/src/DataTables/Filters/Constraints/EntityConstraint.php index 40293e02..7365890b 100644 --- a/src/DataTables/Filters/Constraints/EntityConstraint.php +++ b/src/DataTables/Filters/Constraints/EntityConstraint.php @@ -96,6 +96,7 @@ class EntityConstraint extends AbstractConstraint /** * Checks whether the constraints apply to a structural type or not + * @phpstan-assert-if-true AbstractStructuralDBElement $this->value */ public function isStructural(): bool { diff --git a/src/DataTables/ProjectBomEntriesDataTable.php b/src/DataTables/ProjectBomEntriesDataTable.php index 1870c262..dec3ea1e 100644 --- a/src/DataTables/ProjectBomEntriesDataTable.php +++ b/src/DataTables/ProjectBomEntriesDataTable.php @@ -95,6 +95,8 @@ class ProjectBomEntriesDataTable implements DataTableTypeInterface } return $tmp; } + + //@phpstan-ignore-next-line throw new \Exception('This should never happen!'); }, ]) diff --git a/src/Entity/Attachments/Attachment.php b/src/Entity/Attachments/Attachment.php index 06e7fdd6..270e3c5b 100644 --- a/src/Entity/Attachments/Attachment.php +++ b/src/Entity/Attachments/Attachment.php @@ -110,7 +110,7 @@ abstract class Attachment extends AbstractNamedDBElement protected bool $show_in_table = false; #[Assert\NotNull(message: 'validator.attachment.must_not_be_null')] - #[ORM\ManyToOne(targetEntity: 'AttachmentType', inversedBy: 'attachments_with_type')] + #[ORM\ManyToOne(targetEntity: AttachmentType::class, inversedBy: 'attachments_with_type')] #[ORM\JoinColumn(name: 'type_id', nullable: false)] #[Selectable()] protected ?AttachmentType $attachment_type = null; diff --git a/src/Entity/Attachments/AttachmentType.php b/src/Entity/Attachments/AttachmentType.php index 72752a72..6314fe7c 100644 --- a/src/Entity/Attachments/AttachmentType.php +++ b/src/Entity/Attachments/AttachmentType.php @@ -43,11 +43,11 @@ use Symfony\Component\Validator\Constraints as Assert; #[ORM\Index(name: 'attachment_types_idx_parent_name', columns: ['parent_id', 'name'])] class AttachmentType extends AbstractStructuralDBElement { - #[ORM\OneToMany(targetEntity: 'AttachmentType', mappedBy: 'parent', cascade: ['persist'])] + #[ORM\OneToMany(targetEntity: AttachmentType::class, mappedBy: 'parent', cascade: ['persist'])] #[ORM\OrderBy(['name' => 'ASC'])] protected Collection $children; - #[ORM\ManyToOne(targetEntity: 'AttachmentType', inversedBy: 'children')] + #[ORM\ManyToOne(targetEntity: AttachmentType::class, inversedBy: 'children')] #[ORM\JoinColumn(name: 'parent_id')] protected ?AbstractStructuralDBElement $parent = null; @@ -76,7 +76,7 @@ class AttachmentType extends AbstractStructuralDBElement /** * @var Collection */ - #[ORM\OneToMany(targetEntity: 'Attachment', mappedBy: 'attachment_type')] + #[ORM\OneToMany(targetEntity: Attachment::class, mappedBy: 'attachment_type')] protected Collection $attachments_with_type; public function __construct() diff --git a/src/Entity/Base/AbstractNamedDBElement.php b/src/Entity/Base/AbstractNamedDBElement.php index 20009658..e5e30441 100644 --- a/src/Entity/Base/AbstractNamedDBElement.php +++ b/src/Entity/Base/AbstractNamedDBElement.php @@ -22,6 +22,7 @@ declare(strict_types=1); namespace App\Entity\Base; +use App\Repository\NamedDBElementRepository; use Doctrine\DBAL\Types\Types; use App\Entity\Contracts\NamedElementInterface; use App\Entity\Contracts\TimeStampableInterface; @@ -32,7 +33,7 @@ use Symfony\Component\Validator\Constraints as Assert; /** * All subclasses of this class have an attribute "name". */ -#[ORM\MappedSuperclass(repositoryClass: 'App\Repository\NamedDBElement')] +#[ORM\MappedSuperclass(repositoryClass: NamedDBElementRepository::class)] #[ORM\HasLifecycleCallbacks] abstract class AbstractNamedDBElement extends AbstractDBElement implements NamedElementInterface, TimeStampableInterface, \Stringable { diff --git a/src/Entity/Parts/Category.php b/src/Entity/Parts/Category.php index 2f4b2d08..e5e3320e 100644 --- a/src/Entity/Parts/Category.php +++ b/src/Entity/Parts/Category.php @@ -45,11 +45,11 @@ use Symfony\Component\Validator\Constraints as Assert; #[ORM\Index(name: 'category_idx_parent_name', columns: ['parent_id', 'name'])] class Category extends AbstractPartsContainingDBElement { - #[ORM\OneToMany(targetEntity: 'Category', mappedBy: 'parent')] + #[ORM\OneToMany(targetEntity: self::class, mappedBy: 'parent')] #[ORM\OrderBy(['name' => 'ASC'])] protected Collection $children; - #[ORM\ManyToOne(targetEntity: 'Category', inversedBy: 'children')] + #[ORM\ManyToOne(targetEntity: self::class, inversedBy: 'children')] #[ORM\JoinColumn(name: 'parent_id')] protected ?AbstractStructuralDBElement $parent = null; diff --git a/src/Entity/Parts/Footprint.php b/src/Entity/Parts/Footprint.php index 8ec1bc35..8138f967 100644 --- a/src/Entity/Parts/Footprint.php +++ b/src/Entity/Parts/Footprint.php @@ -43,11 +43,11 @@ use Symfony\Component\Validator\Constraints as Assert; #[ORM\Index(name: 'footprint_idx_parent_name', columns: ['parent_id', 'name'])] class Footprint extends AbstractPartsContainingDBElement { - #[ORM\ManyToOne(targetEntity: 'Footprint', inversedBy: 'children')] + #[ORM\ManyToOne(targetEntity: self::class, inversedBy: 'children')] #[ORM\JoinColumn(name: 'parent_id')] protected ?AbstractStructuralDBElement $parent = null; - #[ORM\OneToMany(targetEntity: 'Footprint', mappedBy: 'parent')] + #[ORM\OneToMany(targetEntity: self::class, mappedBy: 'parent')] #[ORM\OrderBy(['name' => 'ASC'])] protected Collection $children; diff --git a/src/Entity/Parts/Manufacturer.php b/src/Entity/Parts/Manufacturer.php index c5b45bcd..b6768e4a 100644 --- a/src/Entity/Parts/Manufacturer.php +++ b/src/Entity/Parts/Manufacturer.php @@ -43,11 +43,11 @@ use Symfony\Component\Validator\Constraints as Assert; #[ORM\Index(name: 'manufacturer_idx_parent_name', columns: ['parent_id', 'name'])] class Manufacturer extends AbstractCompany { - #[ORM\ManyToOne(targetEntity: 'Manufacturer', inversedBy: 'children')] + #[ORM\ManyToOne(targetEntity: self::class, inversedBy: 'children')] #[ORM\JoinColumn(name: 'parent_id')] protected ?AbstractStructuralDBElement $parent = null; - #[ORM\OneToMany(targetEntity: 'Manufacturer', mappedBy: 'parent')] + #[ORM\OneToMany(targetEntity: self::class, mappedBy: 'parent')] #[ORM\OrderBy(['name' => 'ASC'])] protected Collection $children; diff --git a/src/Entity/Parts/MeasurementUnit.php b/src/Entity/Parts/MeasurementUnit.php index 62a3dd82..054056a8 100644 --- a/src/Entity/Parts/MeasurementUnit.php +++ b/src/Entity/Parts/MeasurementUnit.php @@ -74,11 +74,11 @@ class MeasurementUnit extends AbstractPartsContainingDBElement #[ORM\Column(type: Types::BOOLEAN, name: 'use_si_prefix')] protected bool $use_si_prefix = false; - #[ORM\OneToMany(targetEntity: 'MeasurementUnit', mappedBy: 'parent', cascade: ['persist'])] + #[ORM\OneToMany(targetEntity: self::class, mappedBy: 'parent', cascade: ['persist'])] #[ORM\OrderBy(['name' => 'ASC'])] protected Collection $children; - #[ORM\ManyToOne(targetEntity: 'MeasurementUnit', inversedBy: 'children')] + #[ORM\ManyToOne(targetEntity: self::class, inversedBy: 'children')] #[ORM\JoinColumn(name: 'parent_id')] protected ?AbstractStructuralDBElement $parent = null; diff --git a/src/Entity/Parts/PartLot.php b/src/Entity/Parts/PartLot.php index 15cda250..04cc726d 100644 --- a/src/Entity/Parts/PartLot.php +++ b/src/Entity/Parts/PartLot.php @@ -79,7 +79,7 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface, Named * @var Storelocation|null The storelocation of this lot */ #[Groups(['simple', 'extended', 'full', 'import'])] - #[ORM\ManyToOne(targetEntity: 'Storelocation')] + #[ORM\ManyToOne(targetEntity: Storelocation::class)] #[ORM\JoinColumn(name: 'id_store_location')] #[Selectable()] protected ?Storelocation $storage_location = null; @@ -110,7 +110,7 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface, Named * @var Part The part that is stored in this lot */ #[Assert\NotNull] - #[ORM\ManyToOne(targetEntity: 'Part', inversedBy: 'partLots')] + #[ORM\ManyToOne(targetEntity: Part::class, inversedBy: 'partLots')] #[ORM\JoinColumn(name: 'id_part', nullable: false, onDelete: 'CASCADE')] protected Part $part; diff --git a/src/Entity/Parts/PartTraits/BasicPropertyTrait.php b/src/Entity/Parts/PartTraits/BasicPropertyTrait.php index 192531e3..b0f593d6 100644 --- a/src/Entity/Parts/PartTraits/BasicPropertyTrait.php +++ b/src/Entity/Parts/PartTraits/BasicPropertyTrait.php @@ -66,7 +66,7 @@ trait BasicPropertyTrait #[Assert\NotNull(message: 'validator.select_valid_category')] #[Selectable()] #[Groups(['simple', 'extended', 'full', 'import'])] - #[ORM\ManyToOne(targetEntity: 'Category')] + #[ORM\ManyToOne(targetEntity: Category::class)] #[ORM\JoinColumn(name: 'id_category', nullable: false)] protected ?Category $category = null; @@ -74,7 +74,7 @@ trait BasicPropertyTrait * @var Footprint|null The footprint of this part (e.g. DIP8) */ #[Groups(['simple', 'extended', 'full', 'import'])] - #[ORM\ManyToOne(targetEntity: 'Footprint')] + #[ORM\ManyToOne(targetEntity: Footprint::class)] #[ORM\JoinColumn(name: 'id_footprint')] #[Selectable()] protected ?Footprint $footprint = null; diff --git a/src/Entity/Parts/PartTraits/InstockTrait.php b/src/Entity/Parts/PartTraits/InstockTrait.php index f4a95e16..23168fd3 100644 --- a/src/Entity/Parts/PartTraits/InstockTrait.php +++ b/src/Entity/Parts/PartTraits/InstockTrait.php @@ -40,7 +40,7 @@ trait InstockTrait */ #[Assert\Valid] #[Groups(['extended', 'full', 'import'])] - #[ORM\OneToMany(targetEntity: 'PartLot', mappedBy: 'part', cascade: ['persist', 'remove'], orphanRemoval: true)] + #[ORM\OneToMany(targetEntity: PartLot::class, mappedBy: 'part', cascade: ['persist', 'remove'], orphanRemoval: true)] #[ORM\OrderBy(['amount' => 'DESC'])] protected Collection $partLots; @@ -57,7 +57,7 @@ trait InstockTrait * @var ?MeasurementUnit the unit in which the part's amount is measured */ #[Groups(['extended', 'full', 'import'])] - #[ORM\ManyToOne(targetEntity: 'MeasurementUnit')] + #[ORM\ManyToOne(targetEntity: MeasurementUnit::class)] #[ORM\JoinColumn(name: 'id_part_unit')] protected ?MeasurementUnit $partUnit = null; diff --git a/src/Entity/Parts/PartTraits/ManufacturerTrait.php b/src/Entity/Parts/PartTraits/ManufacturerTrait.php index 1aa3d988..81ab8ac9 100644 --- a/src/Entity/Parts/PartTraits/ManufacturerTrait.php +++ b/src/Entity/Parts/PartTraits/ManufacturerTrait.php @@ -39,7 +39,7 @@ trait ManufacturerTrait * @var Manufacturer|null The manufacturer of this part */ #[Groups(['simple', 'extended', 'full', 'import'])] - #[ORM\ManyToOne(targetEntity: 'Manufacturer')] + #[ORM\ManyToOne(targetEntity: Manufacturer::class)] #[ORM\JoinColumn(name: 'id_manufacturer')] #[Selectable()] protected ?Manufacturer $manufacturer = null; diff --git a/src/Entity/Parts/PartTraits/OrderTrait.php b/src/Entity/Parts/PartTraits/OrderTrait.php index b17f014b..2e0ec0b2 100644 --- a/src/Entity/Parts/PartTraits/OrderTrait.php +++ b/src/Entity/Parts/PartTraits/OrderTrait.php @@ -98,7 +98,7 @@ trait OrderTrait * * @param bool $hide_obsolete If true, obsolete orderdetails will NOT be returned * - * @return Collection|Orderdetail[] * all orderdetails as a one-dimensional array of Orderdetails objects + * @return Collection * all orderdetails as a one-dimensional array of Orderdetails objects * (empty array if there are no ones) * * the array is sorted by the suppliers names / minimum order quantity */ diff --git a/src/Entity/Parts/Storelocation.php b/src/Entity/Parts/Storelocation.php index 205735d4..08c4911b 100644 --- a/src/Entity/Parts/Storelocation.php +++ b/src/Entity/Parts/Storelocation.php @@ -45,18 +45,18 @@ use Symfony\Component\Validator\Constraints as Assert; #[ORM\Index(name: 'location_idx_parent_name', columns: ['parent_id', 'name'])] class Storelocation extends AbstractPartsContainingDBElement { - #[ORM\OneToMany(targetEntity: 'Storelocation', mappedBy: 'parent')] + #[ORM\OneToMany(targetEntity: self::class, mappedBy: 'parent')] #[ORM\OrderBy(['name' => 'ASC'])] protected Collection $children; - #[ORM\ManyToOne(targetEntity: 'Storelocation', inversedBy: 'children')] + #[ORM\ManyToOne(targetEntity: self::class, inversedBy: 'children')] #[ORM\JoinColumn(name: 'parent_id')] protected ?AbstractStructuralDBElement $parent = null; /** * @var MeasurementUnit|null The measurement unit, which parts can be stored in here */ - #[ORM\ManyToOne(targetEntity: 'MeasurementUnit')] + #[ORM\ManyToOne(targetEntity: MeasurementUnit::class)] #[ORM\JoinColumn(name: 'storage_type_id')] protected ?MeasurementUnit $storage_type = null; diff --git a/src/Entity/Parts/Supplier.php b/src/Entity/Parts/Supplier.php index f7c56b2e..34483ca3 100644 --- a/src/Entity/Parts/Supplier.php +++ b/src/Entity/Parts/Supplier.php @@ -49,11 +49,11 @@ use Symfony\Component\Validator\Constraints as Assert; #[ORM\Index(name: 'supplier_idx_parent_name', columns: ['parent_id', 'name'])] class Supplier extends AbstractCompany { - #[ORM\OneToMany(targetEntity: 'Supplier', mappedBy: 'parent')] + #[ORM\OneToMany(targetEntity: self::class, mappedBy: 'parent')] #[ORM\OrderBy(['name' => 'ASC'])] protected Collection $children; - #[ORM\ManyToOne(targetEntity: 'Supplier', inversedBy: 'children')] + #[ORM\ManyToOne(targetEntity: self::class, inversedBy: 'children')] #[ORM\JoinColumn(name: 'parent_id')] protected ?AbstractStructuralDBElement $parent = null; diff --git a/src/Entity/PriceInformations/Currency.php b/src/Entity/PriceInformations/Currency.php index 171f5693..7e51c4c4 100644 --- a/src/Entity/PriceInformations/Currency.php +++ b/src/Entity/PriceInformations/Currency.php @@ -66,11 +66,11 @@ class Currency extends AbstractStructuralDBElement #[ORM\Column(type: Types::STRING)] protected string $iso_code = ""; - #[ORM\OneToMany(targetEntity: 'Currency', mappedBy: 'parent', cascade: ['persist'])] + #[ORM\OneToMany(targetEntity: self::class, mappedBy: 'parent', cascade: ['persist'])] #[ORM\OrderBy(['name' => 'ASC'])] protected Collection $children; - #[ORM\ManyToOne(targetEntity: 'Currency', inversedBy: 'children')] + #[ORM\ManyToOne(targetEntity: self::class, inversedBy: 'children')] #[ORM\JoinColumn(name: 'parent_id')] protected ?AbstractStructuralDBElement $parent = null; diff --git a/src/Entity/PriceInformations/Orderdetail.php b/src/Entity/PriceInformations/Orderdetail.php index f39690d4..40d512a5 100644 --- a/src/Entity/PriceInformations/Orderdetail.php +++ b/src/Entity/PriceInformations/Orderdetail.php @@ -52,7 +52,7 @@ class Orderdetail extends AbstractDBElement implements TimeStampableInterface, N #[Assert\Valid] #[Groups(['extended', 'full', 'import'])] - #[ORM\OneToMany(targetEntity: 'Pricedetail', mappedBy: 'orderdetail', cascade: ['persist', 'remove'], orphanRemoval: true)] + #[ORM\OneToMany(targetEntity: Pricedetail::class, mappedBy: 'orderdetail', cascade: ['persist', 'remove'], orphanRemoval: true)] #[ORM\OrderBy(['min_discount_quantity' => 'ASC'])] protected Collection $pricedetails; diff --git a/src/Entity/PriceInformations/Pricedetail.php b/src/Entity/PriceInformations/Pricedetail.php index 34df9e57..26afbb50 100644 --- a/src/Entity/PriceInformations/Pricedetail.php +++ b/src/Entity/PriceInformations/Pricedetail.php @@ -64,7 +64,7 @@ class Pricedetail extends AbstractDBElement implements TimeStampableInterface * If this is null, the global base unit is assumed */ #[Groups(['extended', 'full', 'import'])] - #[ORM\ManyToOne(targetEntity: 'Currency', inversedBy: 'pricedetails')] + #[ORM\ManyToOne(targetEntity: Currency::class, inversedBy: 'pricedetails')] #[ORM\JoinColumn(name: 'id_currency')] #[Selectable()] protected ?Currency $currency = null; @@ -95,7 +95,7 @@ class Pricedetail extends AbstractDBElement implements TimeStampableInterface * @var Orderdetail|null */ #[Assert\NotNull] - #[ORM\ManyToOne(targetEntity: 'Orderdetail', inversedBy: 'pricedetails')] + #[ORM\ManyToOne(targetEntity: Orderdetail::class, inversedBy: 'pricedetails')] #[ORM\JoinColumn(name: 'orderdetails_id', nullable: false, onDelete: 'CASCADE')] protected ?Orderdetail $orderdetail = null; diff --git a/src/Entity/ProjectSystem/Project.php b/src/Entity/ProjectSystem/Project.php index 966d19c1..0b07ef22 100644 --- a/src/Entity/ProjectSystem/Project.php +++ b/src/Entity/ProjectSystem/Project.php @@ -45,17 +45,17 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface; #[ORM\Table(name: 'projects')] class Project extends AbstractStructuralDBElement { - #[ORM\OneToMany(targetEntity: 'Project', mappedBy: 'parent')] + #[ORM\OneToMany(targetEntity: self::class, mappedBy: 'parent')] #[ORM\OrderBy(['name' => 'ASC'])] protected Collection $children; - #[ORM\ManyToOne(targetEntity: 'Project', inversedBy: 'children')] + #[ORM\ManyToOne(targetEntity: self::class, inversedBy: 'children')] #[ORM\JoinColumn(name: 'parent_id')] protected ?AbstractStructuralDBElement $parent = null; #[Assert\Valid] #[Groups(['extended', 'full'])] - #[ORM\OneToMany(targetEntity: 'ProjectBOMEntry', mappedBy: 'project', cascade: ['persist', 'remove'], orphanRemoval: true)] + #[ORM\OneToMany(targetEntity: ProjectBOMEntry::class, mappedBy: 'project', cascade: ['persist', 'remove'], orphanRemoval: true)] protected Collection $bom_entries; #[ORM\Column(type: Types::INTEGER)] diff --git a/src/Entity/ProjectSystem/ProjectBOMEntry.php b/src/Entity/ProjectSystem/ProjectBOMEntry.php index 4469f86f..af8b48c1 100644 --- a/src/Entity/ProjectSystem/ProjectBOMEntry.php +++ b/src/Entity/ProjectSystem/ProjectBOMEntry.php @@ -76,7 +76,7 @@ class ProjectBOMEntry extends AbstractDBElement /** * @var Project|null */ - #[ORM\ManyToOne(targetEntity: 'Project', inversedBy: 'bom_entries')] + #[ORM\ManyToOne(targetEntity: Project::class, inversedBy: 'bom_entries')] #[ORM\JoinColumn(name: 'id_device')] protected ?Project $project = null; diff --git a/src/Entity/UserSystem/Group.php b/src/Entity/UserSystem/Group.php index f833fdfc..b56cabf4 100644 --- a/src/Entity/UserSystem/Group.php +++ b/src/Entity/UserSystem/Group.php @@ -47,18 +47,18 @@ use Symfony\Component\Validator\Constraints as Assert; #[NoLockout()] class Group extends AbstractStructuralDBElement implements HasPermissionsInterface { - #[ORM\OneToMany(targetEntity: 'Group', mappedBy: 'parent')] + #[ORM\OneToMany(targetEntity: self::class, mappedBy: 'parent')] #[ORM\OrderBy(['name' => 'ASC'])] protected Collection $children; - #[ORM\ManyToOne(targetEntity: 'Group', inversedBy: 'children')] + #[ORM\ManyToOne(targetEntity: self::class, inversedBy: 'children')] #[ORM\JoinColumn(name: 'parent_id')] protected ?AbstractStructuralDBElement $parent = null; /** * @var Collection */ - #[ORM\OneToMany(targetEntity: 'User', mappedBy: 'group')] + #[ORM\OneToMany(targetEntity: User::class, mappedBy: 'group')] protected Collection $users; /** @@ -77,7 +77,7 @@ class Group extends AbstractStructuralDBElement implements HasPermissionsInterfa protected Collection $attachments; #[Groups(['full'])] - #[ORM\Embedded(class: 'PermissionData', columnPrefix: 'permissions_')] + #[ORM\Embedded(class: PermissionData::class, columnPrefix: 'permissions_')] #[ValidPermission()] protected ?PermissionData $permissions = null; diff --git a/src/Entity/UserSystem/User.php b/src/Entity/UserSystem/User.php index 614f01e5..da6a240f 100644 --- a/src/Entity/UserSystem/User.php +++ b/src/Entity/UserSystem/User.php @@ -133,7 +133,7 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe * DO NOT PUT A fetch eager here! Otherwise, you can not unset the group of a user! This seems to be some kind of bug in doctrine. Maybe this is fixed in future versions. */ #[Groups(['extended', 'full', 'import'])] - #[ORM\ManyToOne(targetEntity: 'Group', inversedBy: 'users')] + #[ORM\ManyToOne(targetEntity: Group::class, inversedBy: 'users')] #[ORM\JoinColumn(name: 'group_id')] #[Selectable] protected ?Group $group = null; diff --git a/src/EventSubscriber/UserSystem/UpgradePermissionsSchemaSubscriber.php b/src/EventSubscriber/UserSystem/UpgradePermissionsSchemaSubscriber.php index 6e81ec85..613bc6ec 100644 --- a/src/EventSubscriber/UserSystem/UpgradePermissionsSchemaSubscriber.php +++ b/src/EventSubscriber/UserSystem/UpgradePermissionsSchemaSubscriber.php @@ -58,6 +58,11 @@ class UpgradePermissionsSchemaSubscriber implements EventSubscriberInterface $session = $event->getRequest()->getSession(); $flashBag = $session->getFlashBag(); + //Check if the user is an instance of User, otherwise we can't upgrade the schema + if (!$user instanceof User) { + return; + } + if ($this->permissionSchemaUpdater->isSchemaUpdateNeeded($user)) { $this->eventCommentHelper->setMessage('Automatic permission schema update'); $this->permissionSchemaUpdater->userUpgradeSchemaRecursively($user); diff --git a/src/Repository/LogEntryRepository.php b/src/Repository/LogEntryRepository.php index a3456b6c..770e6cd6 100644 --- a/src/Repository/LogEntryRepository.php +++ b/src/Repository/LogEntryRepository.php @@ -52,13 +52,13 @@ class LogEntryRepository extends DBElementRepository * Find log entries associated with the given element (the history of the element). * * @param AbstractDBElement $element The element for which the history should be generated - * @param string $order By default, the newest entries are shown first. Change this to ASC to show the oldest entries first. - * @param null $limit - * @param null $offset + * @param string $order By default, the newest entries are shown first. Change this to ASC to show the oldest entries first. + * @param int|null $limit + * @param int|null $offset * * @return AbstractLogEntry[] */ - public function getElementHistory(AbstractDBElement $element, string $order = 'DESC', $limit = null, $offset = null): array + public function getElementHistory(AbstractDBElement $element, string $order = 'DESC', ?int $limit = null, ?int $offset = null): array { return $this->findBy(['element' => $element], ['timestamp' => $order], $limit, $offset); } @@ -100,11 +100,11 @@ class LogEntryRepository extends DBElementRepository * Gets all log entries that are related to time travelling. * * @param AbstractDBElement $element The element for which the time travel data should be retrieved - * @param DateTime $until Back to which timestamp should the data be got (including the timestamp) + * @param \DateTimeInterface $until Back to which timestamp should the data be got (including the timestamp) * * @return AbstractLogEntry[] */ - public function getTimetravelDataForElement(AbstractDBElement $element, DateTime $until): array + public function getTimetravelDataForElement(AbstractDBElement $element, \DateTimeInterface $until): array { $qb = $this->createQueryBuilder('log'); $qb->select('log') @@ -132,7 +132,7 @@ class LogEntryRepository extends DBElementRepository * * @return bool True if the element existed at the given timestamp */ - public function getElementExistedAtTimestamp(AbstractDBElement $element, DateTime $timestamp): bool + public function getElementExistedAtTimestamp(AbstractDBElement $element, \DateTimeInterface $timestamp): bool { $qb = $this->createQueryBuilder('log'); $qb->select('count(log)') @@ -157,8 +157,8 @@ class LogEntryRepository extends DBElementRepository /** * Gets the last log entries ordered by timestamp. * - * @param null $limit - * @param null $offset + * @param int|null $limit + * @param int|null $offset */ public function getLogsOrderedByTimestamp(string $order = 'DESC', $limit = null, $offset = null): array { diff --git a/src/Services/ElementTypeNameGenerator.php b/src/Services/ElementTypeNameGenerator.php index e9b24d23..f907712b 100644 --- a/src/Services/ElementTypeNameGenerator.php +++ b/src/Services/ElementTypeNameGenerator.php @@ -26,6 +26,7 @@ use App\Entity\Attachments\AttachmentContainingDBElement; use App\Entity\Attachments\Attachment; use App\Entity\Attachments\AttachmentType; use App\Entity\Base\AbstractDBElement; +use App\Entity\Base\AbstractNamedDBElement; use App\Entity\Contracts\NamedElementInterface; use App\Entity\ProjectSystem\Project; use App\Entity\LabelSystem\LabelProfile; @@ -180,7 +181,7 @@ class ElementTypeNameGenerator $on = $entity->getProject(); } - if (isset($on) && is_object($on)) { + if (isset($on) && $on instanceof NamedElementInterface) { try { $tmp .= sprintf( ' (%s)', diff --git a/src/Services/LabelSystem/LabelExampleElementsGenerator.php b/src/Services/LabelSystem/LabelExampleElementsGenerator.php index 40ebafa0..a5e194b2 100644 --- a/src/Services/LabelSystem/LabelExampleElementsGenerator.php +++ b/src/Services/LabelSystem/LabelExampleElementsGenerator.php @@ -132,6 +132,14 @@ final class LabelExampleElementsGenerator return $user; } + /** + * @template T of AbstractStructuralDBElement + * @param string $class + * @phpstan-param class-string $class + * @return AbstractStructuralDBElement + * @phpstan-return T + * @throws \ReflectionException + */ private function getStructuralData(string $class): AbstractStructuralDBElement { if (!is_a($class, AbstractStructuralDBElement::class, true)) { diff --git a/src/Services/LabelSystem/PlaceholderProviders/BarcodeProvider.php b/src/Services/LabelSystem/PlaceholderProviders/BarcodeProvider.php index eb413518..11824054 100644 --- a/src/Services/LabelSystem/PlaceholderProviders/BarcodeProvider.php +++ b/src/Services/LabelSystem/PlaceholderProviders/BarcodeProvider.php @@ -22,6 +22,7 @@ declare(strict_types=1); */ namespace App\Services\LabelSystem\PlaceholderProviders; +use App\Entity\LabelSystem\BarcodeType; use App\Entity\LabelSystem\LabelOptions; use App\Services\LabelSystem\BarcodeGenerator; use App\Services\LabelSystem\Barcodes\BarcodeContentGenerator; @@ -52,19 +53,19 @@ final class BarcodeProvider implements PlaceholderProviderInterface if ('[[BARCODE_QR]]' === $placeholder) { $label_options = new LabelOptions(); - $label_options->setBarcodeType('qr'); + $label_options->setBarcodeType(BarcodeType::QR); return $this->barcodeGenerator->generateHTMLBarcode($label_options, $label_target); } if ('[[BARCODE_C39]]' === $placeholder) { $label_options = new LabelOptions(); - $label_options->setBarcodeType('code39'); + $label_options->setBarcodeType(BarcodeType::CODE39); return $this->barcodeGenerator->generateHTMLBarcode($label_options, $label_target); } if ('[[BARCODE_C128]]' === $placeholder) { $label_options = new LabelOptions(); - $label_options->setBarcodeType('code128'); + $label_options->setBarcodeType(BarcodeType::CODE128); return $this->barcodeGenerator->generateHTMLBarcode($label_options, $label_target); } diff --git a/src/Services/LogSystem/TimeTravel.php b/src/Services/LogSystem/TimeTravel.php index 5cc4be79..82e98afb 100644 --- a/src/Services/LogSystem/TimeTravel.php +++ b/src/Services/LogSystem/TimeTravel.php @@ -79,7 +79,7 @@ class TimeTravel * * @throws Exception */ - public function revertEntityToTimestamp(AbstractDBElement $element, DateTime $timestamp, array $reverted_elements = []): void + public function revertEntityToTimestamp(AbstractDBElement $element, \DateTimeInterface $timestamp, array $reverted_elements = []): void { if (!$element instanceof TimeStampableInterface) { throw new InvalidArgumentException('$element must have a Timestamp!'); @@ -228,7 +228,7 @@ class TimeTravel $this->setField($element, 'lastModified', $logEntry->getTimestamp()); } - protected function getField(AbstractDBElement $element, string $field) + protected function getField(AbstractDBElement $element, string $field): mixed { $reflection = new ReflectionClass($element::class); $property = $reflection->getProperty($field); @@ -237,7 +237,7 @@ class TimeTravel return $property->getValue($element); } - protected function setField(AbstractDBElement $element, string $field, \DateTime|int|null $new_value): void + protected function setField(AbstractDBElement $element, string $field, mixed $new_value): void { $reflection = new ReflectionClass($element::class); $property = $reflection->getProperty($field); diff --git a/src/Services/UserSystem/PermissionManager.php b/src/Services/UserSystem/PermissionManager.php index 333e6168..fa591a91 100644 --- a/src/Services/UserSystem/PermissionManager.php +++ b/src/Services/UserSystem/PermissionManager.php @@ -112,7 +112,7 @@ class PermissionManager /** @var Group $parent */ $parent = $user->getGroup(); - while ($parent instanceof AbstractStructuralDBElement) { //The top group, has parent == null + while ($parent instanceof Group) { //The top group, has parent == null //Check if our current element gives an info about disallow/allow $allowed = $this->dontInherit($parent, $permission, $operation); if (null !== $allowed) { diff --git a/src/Services/UserSystem/PermissionPresetsHelper.php b/src/Services/UserSystem/PermissionPresetsHelper.php index d12eb1ef..ecc56699 100644 --- a/src/Services/UserSystem/PermissionPresetsHelper.php +++ b/src/Services/UserSystem/PermissionPresetsHelper.php @@ -172,12 +172,18 @@ class PermissionPresetsHelper return $perm_holder; } + /** + * @phpstan-api + */ private function AllForbid(HasPermissionsInterface $perm_holder): HasPermissionsInterface { $this->permissionResolver->setAllPermissions($perm_holder, PermissionData::DISALLOW); return $perm_holder; } + /** + * @phpstan-api + */ private function AllAllow(HasPermissionsInterface $perm_holder): HasPermissionsInterface { $this->permissionResolver->setAllPermissions($perm_holder, PermissionData::ALLOW);