Started to increase the phpstan level

This commit is contained in:
Jan Böhmer 2023-06-13 10:36:34 +02:00
parent 71cd4057a7
commit fc3290271c
29 changed files with 119 additions and 55 deletions

View file

@ -327,9 +327,8 @@ abstract class BaseAdminController extends AbstractController
try { try {
$errors = $importer->importFileAndPersistToDB($file, $options); $errors = $importer->importFileAndPersistToDB($file, $options);
/** @var ConstraintViolationList $error */
foreach ($errors as $name => $error) { foreach ($errors as $name => $error) {
foreach ($error['violations'] as $violation) { foreach ($error as $violation) {
$this->addFlash('error', $name.': '.$violation->getMessage()); $this->addFlash('error', $name.': '.$violation->getMessage());
} }
} }

View file

@ -40,8 +40,8 @@ class EntityConstraint extends AbstractConstraint
* @param class-string<T> $class * @param class-string<T> $class
* @param string $property * @param string $property
* @param string|null $identifier * @param string|null $identifier
* @param null $value * @param null|T $value
* @param string $operator * @param string|null $operator
*/ */
public function __construct(protected ?NodesListBuilder $nodesListBuilder, public function __construct(protected ?NodesListBuilder $nodesListBuilder,
protected string $class, protected string $class,
@ -82,9 +82,10 @@ class EntityConstraint extends AbstractConstraint
} }
/** /**
* @param T|null $value * @param AbstractDBElement|null $value
* @phpstan-param T|null $value
*/ */
public function setValue(?AbstractDBElement $value): void public function setValue(AbstractDBElement|null $value): void
{ {
if (!$value instanceof $this->class) { if (!$value instanceof $this->class) {
throw new \InvalidArgumentException('The value must be an instance of ' . $this->class); throw new \InvalidArgumentException('The value must be an instance of ' . $this->class);

View file

@ -29,7 +29,7 @@ trait FilterTrait
protected bool $useHaving = false; protected bool $useHaving = false;
public function useHaving($value = true): self public function useHaving($value = true): static
{ {
$this->useHaving = $value; $this->useHaving = $value;
return $this; return $this;

View file

@ -85,6 +85,7 @@ class PartFilter implements FilterInterface
protected IntConstraint $attachmentsCount; protected IntConstraint $attachmentsCount;
protected EntityConstraint $attachmentType; protected EntityConstraint $attachmentType;
protected TextConstraint $attachmentName; protected TextConstraint $attachmentName;
/** @var ArrayCollection<int, ParameterConstraint> */ /** @var ArrayCollection<int, ParameterConstraint> */
protected ArrayCollection $parameters; protected ArrayCollection $parameters;
protected IntConstraint $parametersCount; protected IntConstraint $parametersCount;

View file

@ -37,6 +37,7 @@ use LogicException;
/** /**
* Class Attachment. * Class Attachment.
* @see \App\Tests\Entity\Attachments\AttachmentTest * @see \App\Tests\Entity\Attachments\AttachmentTest
* @template-covariant T of AttachmentContainingDBElement
*/ */
#[ORM\Entity(repositoryClass: AttachmentRepository::class)] #[ORM\Entity(repositoryClass: AttachmentRepository::class)]
#[ORM\InheritanceType('SINGLE_TABLE')] #[ORM\InheritanceType('SINGLE_TABLE')]
@ -75,9 +76,9 @@ abstract class Attachment extends AbstractNamedDBElement
/** /**
* @var string The class of the element that can be passed to this attachment. Must be overridden in subclasses. * @var string The class of the element that can be passed to this attachment. Must be overridden in subclasses.
* * @phpstan-var class-string<T>
*/ */
protected const ALLOWED_ELEMENT_CLASS = ''; protected const ALLOWED_ELEMENT_CLASS = AttachmentContainingDBElement::class;
/** /**
* @var string|null the original filename the file had, when the user uploaded it * @var string|null the original filename the file had, when the user uploaded it
@ -101,6 +102,7 @@ abstract class Attachment extends AbstractNamedDBElement
/** /**
* ORM mapping is done in subclasses (like PartAttachment). * ORM mapping is done in subclasses (like PartAttachment).
* @phpstan-param T|null $element
*/ */
protected ?AttachmentContainingDBElement $element = null; protected ?AttachmentContainingDBElement $element = null;
@ -116,7 +118,7 @@ abstract class Attachment extends AbstractNamedDBElement
public function __construct() public function __construct()
{ {
//parent::__construct(); //parent::__construct();
if ('' === static::ALLOWED_ELEMENT_CLASS) { if (AttachmentContainingDBElement::class === static::ALLOWED_ELEMENT_CLASS) {
throw new LogicException('An *Attachment class must override the ALLOWED_ELEMENT_CLASS const!'); throw new LogicException('An *Attachment class must override the ALLOWED_ELEMENT_CLASS const!');
} }
} }

View file

@ -31,13 +31,17 @@ use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups; use Symfony\Component\Serializer\Annotation\Groups;
/**
* @template-covariant AT of Attachment
*/
#[ORM\MappedSuperclass] #[ORM\MappedSuperclass]
abstract class AttachmentContainingDBElement extends AbstractNamedDBElement implements HasMasterAttachmentInterface, HasAttachmentsInterface abstract class AttachmentContainingDBElement extends AbstractNamedDBElement implements HasMasterAttachmentInterface, HasAttachmentsInterface
{ {
use MasterAttachmentTrait; use MasterAttachmentTrait;
/** /**
* @var Attachment[]|Collection * @var Collection<int, Attachment>
* @phpstan-var Collection<int, AT>
* ORM Mapping is done in subclasses (e.g. Part) * ORM Mapping is done in subclasses (e.g. Part)
*/ */
#[Groups(['full'])] #[Groups(['full'])]
@ -76,7 +80,7 @@ abstract class AttachmentContainingDBElement extends AbstractNamedDBElement impl
/** /**
* Gets all attachments associated with this element. * Gets all attachments associated with this element.
* *
* @return Attachment[]|Collection * @return Collection<Attachment>
*/ */
public function getAttachments(): Collection public function getAttachments(): Collection
{ {

View file

@ -35,6 +35,7 @@ use Symfony\Component\Validator\Constraints as Assert;
/** /**
* Class AttachmentType. * Class AttachmentType.
* @see \App\Tests\Entity\Attachments\AttachmentTypeTest * @see \App\Tests\Entity\Attachments\AttachmentTypeTest
* @extends AbstractStructuralDBElement<AttachmentTypeAttachment, AttachmentTypeParameter>
*/ */
#[ORM\Entity(repositoryClass: StructuralDBElementRepository::class)] #[ORM\Entity(repositoryClass: StructuralDBElementRepository::class)]
#[ORM\Table(name: '`attachment_types`')] #[ORM\Table(name: '`attachment_types`')]

View file

@ -27,6 +27,7 @@ use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/** /**
* A attachment attached to an attachmentType element. * A attachment attached to an attachmentType element.
* @extends Attachment<AttachmentType>
*/ */
#[UniqueEntity(['name', 'attachment_type', 'element'])] #[UniqueEntity(['name', 'attachment_type', 'element'])]
#[ORM\Entity] #[ORM\Entity]

View file

@ -28,6 +28,7 @@ use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/** /**
* An attachment attached to a category element. * An attachment attached to a category element.
* @extends Attachment<Category>
*/ */
#[UniqueEntity(['name', 'attachment_type', 'element'])] #[UniqueEntity(['name', 'attachment_type', 'element'])]
#[ORM\Entity] #[ORM\Entity]

View file

@ -22,6 +22,8 @@ declare(strict_types=1);
namespace App\Entity\Base; namespace App\Entity\Base;
use App\Entity\Attachments\Attachment;
use App\Entity\Parameters\AbstractParameter;
use Doctrine\DBAL\Types\Types; use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups; use Symfony\Component\Serializer\Annotation\Groups;
@ -30,6 +32,10 @@ use Symfony\Component\Validator\Constraints as Assert;
/** /**
* This abstract class is used for companies like suppliers or manufacturers. * This abstract class is used for companies like suppliers or manufacturers.
*
* @template-covariant AT of Attachment
* @template-covariant PT of AbstractParameter
* @extends AbstractPartsContainingDBElement<AT, PT>
*/ */
#[ORM\MappedSuperclass] #[ORM\MappedSuperclass]
abstract class AbstractCompany extends AbstractPartsContainingDBElement abstract class AbstractCompany extends AbstractPartsContainingDBElement

View file

@ -22,13 +22,19 @@ declare(strict_types=1);
namespace App\Entity\Base; namespace App\Entity\Base;
use App\Entity\Attachments\Attachment;
use App\Entity\Attachments\AttachmentContainingDBElement;
use App\Entity\Parameters\AbstractParameter;
use App\Entity\Parameters\ParametersTrait;
use App\Repository\AbstractPartsContainingRepository; use App\Repository\AbstractPartsContainingRepository;
use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups; use Symfony\Component\Serializer\Annotation\Groups;
/** /**
* Class PartsContainingDBElement. * @template-covariant AT of Attachment
* @template-covariant PT of AbstractParameter
* @extends AbstractStructuralDBElement<AT, PT>
*/ */
#[ORM\MappedSuperclass(repositoryClass: AbstractPartsContainingRepository::class)] #[ORM\MappedSuperclass(repositoryClass: AbstractPartsContainingRepository::class)]
abstract class AbstractPartsContainingDBElement extends AbstractStructuralDBElement abstract class AbstractPartsContainingDBElement extends AbstractStructuralDBElement

View file

@ -22,12 +22,16 @@ declare(strict_types=1);
namespace App\Entity\Base; namespace App\Entity\Base;
use App\Entity\Attachments\Attachment;
use App\Entity\Parameters\AbstractParameter;
use App\Repository\StructuralDBElementRepository; use App\Repository\StructuralDBElementRepository;
use App\EntityListeners\TreeCacheInvalidationListener; use App\EntityListeners\TreeCacheInvalidationListener;
use Doctrine\DBAL\Types\Types; use Doctrine\DBAL\Types\Types;
use App\Entity\Attachments\AttachmentContainingDBElement; use App\Entity\Attachments\AttachmentContainingDBElement;
use App\Entity\Parameters\ParametersTrait; use App\Entity\Parameters\ParametersTrait;
use App\Validator\Constraints\NoneOfItsChildren; use App\Validator\Constraints\NoneOfItsChildren;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Constraints\Valid;
use function count; use function count;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Collection;
@ -48,6 +52,12 @@ use Symfony\Component\Serializer\Annotation\Groups;
* *
* *
* @see \App\Tests\Entity\Base\AbstractStructuralDBElementTest * @see \App\Tests\Entity\Base\AbstractStructuralDBElementTest
*
* @template-covariant AT of Attachment
* @template-covariant PT of AbstractParameter
* @template-use ParametersTrait<PT>
* @extends AttachmentContainingDBElement<AT>
* @uses ParametersTrait<PT>
*/ */
#[UniqueEntity(fields: ['name', 'parent'], ignoreNull: false, message: 'structural.entity.unique_name')] #[UniqueEntity(fields: ['name', 'parent'], ignoreNull: false, message: 'structural.entity.unique_name')]
#[ORM\MappedSuperclass(repositoryClass: StructuralDBElementRepository::class)] #[ORM\MappedSuperclass(repositoryClass: StructuralDBElementRepository::class)]
@ -87,15 +97,29 @@ abstract class AbstractStructuralDBElement extends AttachmentContainingDBElement
* We can not define the mapping here, or we will get an exception. Unfortunately we have to do the mapping in the * We can not define the mapping here, or we will get an exception. Unfortunately we have to do the mapping in the
* subclasses. * subclasses.
* *
* @var Collection<AbstractStructuralDBElement> * @var Collection<int, AbstractStructuralDBElement>
* @phpstan-var Collection<int, static>
*/ */
#[Groups(['include_children'])] #[Groups(['include_children'])]
protected Collection $children; protected Collection $children;
/**
* @var AbstractStructuralDBElement|null
* @phpstan-var static|null
*/
#[Groups(['include_parents', 'import'])] #[Groups(['include_parents', 'import'])]
#[NoneOfItsChildren] #[NoneOfItsChildren]
protected ?AbstractStructuralDBElement $parent = null; protected ?AbstractStructuralDBElement $parent = null;
/**
* Mapping done in subclasses.
*
* @var Collection<int, AbstractParameter>
* @phpstan-var Collection<int, PT>
*/
#[Assert\Valid()]
protected Collection $parameters;
/** @var string[] all names of all parent elements as an array of strings, /** @var string[] all names of all parent elements as an array of strings,
* the last array element is the name of the element itself * the last array element is the name of the element itself
*/ */
@ -314,9 +338,8 @@ abstract class AbstractStructuralDBElement extends AttachmentContainingDBElement
/** /**
* Sets the new parent object. * Sets the new parent object.
* *
* @param AbstractStructuralDBElement|null $new_parent The new parent object * @param static|null $new_parent The new parent object
* * @return $this
* @return AbstractStructuralDBElement
*/ */
public function setParent(?self $new_parent): self public function setParent(?self $new_parent): self
{ {
@ -325,6 +348,11 @@ abstract class AbstractStructuralDBElement extends AttachmentContainingDBElement
throw new \InvalidArgumentException('You can not use one of the element childs as parent!'); throw new \InvalidArgumentException('You can not use one of the element childs as parent!');
} */ } */
//Ensure that the parent is of the same type as this element
if (!$new_parent instanceof static) {
throw new \InvalidArgumentException('The parent must be of the same type as this element!');
}
$this->parent = $new_parent; $this->parent = $new_parent;
//Add this element as child to the new parent //Add this element as child to the new parent
@ -340,7 +368,7 @@ abstract class AbstractStructuralDBElement extends AttachmentContainingDBElement
* *
* @param string $new_comment the new comment * @param string $new_comment the new comment
* *
* @return AbstractStructuralDBElement * @return $this
*/ */
public function setComment(string $new_comment): self public function setComment(string $new_comment): self
{ {

View file

@ -52,6 +52,9 @@ use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert; use Symfony\Component\Validator\Constraints as Assert;
/**
* @extends AttachmentContainingDBElement<LabelAttachment>
*/
#[UniqueEntity(['name', 'options.supported_element'])] #[UniqueEntity(['name', 'options.supported_element'])]
#[ORM\Entity(repositoryClass: LabelProfileRepository::class)] #[ORM\Entity(repositoryClass: LabelProfileRepository::class)]
#[ORM\EntityListeners([TreeCacheInvalidationListener::class])] #[ORM\EntityListeners([TreeCacheInvalidationListener::class])]

View file

@ -86,7 +86,7 @@ class PartStockChangedLogEntry extends AbstractLogEntry
* @param float $new_stock The new stock of the lot. * @param float $new_stock The new stock of the lot.
* @param float $new_total_part_instock The new total instock of the part. * @param float $new_total_part_instock The new total instock of the part.
* @param string $comment The comment associated with the change. * @param string $comment The comment associated with the change.
* @return static * @return self
*/ */
public static function add(PartLot $lot, float $old_stock, float $new_stock, float $new_total_part_instock, string $comment): self public static function add(PartLot $lot, float $old_stock, float $new_stock, float $new_total_part_instock, string $comment): self
{ {
@ -100,7 +100,7 @@ class PartStockChangedLogEntry extends AbstractLogEntry
* @param float $new_stock The new stock of the lot. * @param float $new_stock The new stock of the lot.
* @param float $new_total_part_instock The new total instock of the part. * @param float $new_total_part_instock The new total instock of the part.
* @param string $comment The comment associated with the change. * @param string $comment The comment associated with the change.
* @return static * @return self
*/ */
public static function withdraw(PartLot $lot, float $old_stock, float $new_stock, float $new_total_part_instock, string $comment): self public static function withdraw(PartLot $lot, float $old_stock, float $new_stock, float $new_total_part_instock, string $comment): self
{ {

View file

@ -44,20 +44,25 @@ namespace App\Entity\Parameters;
use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Collection;
use Symfony\Component\Validator\Constraints as Assert; use Symfony\Component\Validator\Constraints as Assert;
/**
* @template-covariant T of AbstractParameter
*/
trait ParametersTrait trait ParametersTrait
{ {
/** /**
* Mapping done in subclasses. * Mapping done in subclasses.
* *
* @var Collection<int, AbstractParameter> * @var Collection<int, AbstractParameter>
* @phpstan-var Collection<int, T>
*/ */
#[Assert\Valid] #[Assert\Valid]
protected Collection $parameters; protected Collection $parameters;
/** /**
* Return all associated specifications. * Return all associated specifications.
* @return Collection<int, AbstractParameter>
* @phpstan-return Collection<int, T>
* *
* @psalm-return Collection<int, AbstractParameter>
*/ */
public function getParameters(): Collection public function getParameters(): Collection
{ {
@ -66,7 +71,7 @@ trait ParametersTrait
/** /**
* Add a new parameter information. * Add a new parameter information.
* * @phpstan-param T $parameter
* @return $this * @return $this
*/ */
public function addParameter(AbstractParameter $parameter): self public function addParameter(AbstractParameter $parameter): self
@ -77,6 +82,9 @@ trait ParametersTrait
return $this; return $this;
} }
/**
* @phpstan-param T $parameter
*/
public function removeParameter(AbstractParameter $parameter): self public function removeParameter(AbstractParameter $parameter): self
{ {
$this->parameters->removeElement($parameter); $this->parameters->removeElement($parameter);
@ -84,6 +92,10 @@ trait ParametersTrait
return $this; return $this;
} }
/**
* @return array<string, array<int, AbstractParameter>>
* @phpstan-return array<string, array<int, T>>
*/
public function getGroupedParameters(): array public function getGroupedParameters(): array
{ {
$tmp = []; $tmp = [];

View file

@ -35,7 +35,9 @@ use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert; use Symfony\Component\Validator\Constraints as Assert;
/** /**
* Class AttachmentType. * This entity describes a category, a part can belong to, which is used to group parts by their function.
*
* @extends AbstractPartsContainingDBElement<CategoryAttachment, CategoryParameter>
*/ */
#[ORM\Entity(repositoryClass: CategoryRepository::class)] #[ORM\Entity(repositoryClass: CategoryRepository::class)]
#[ORM\Table(name: '`categories`')] #[ORM\Table(name: '`categories`')]
@ -43,9 +45,6 @@ use Symfony\Component\Validator\Constraints as Assert;
#[ORM\Index(name: 'category_idx_parent_name', columns: ['parent_id', 'name'])] #[ORM\Index(name: 'category_idx_parent_name', columns: ['parent_id', 'name'])]
class Category extends AbstractPartsContainingDBElement class Category extends AbstractPartsContainingDBElement
{ {
/**
* @var Collection
*/
#[ORM\OneToMany(targetEntity: 'Category', mappedBy: 'parent')] #[ORM\OneToMany(targetEntity: 'Category', mappedBy: 'parent')]
#[ORM\OrderBy(['name' => 'ASC'])] #[ORM\OrderBy(['name' => 'ASC'])]
protected Collection $children; protected Collection $children;

View file

@ -33,7 +33,9 @@ use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert; use Symfony\Component\Validator\Constraints as Assert;
/** /**
* Class Footprint. * This entity represents a footprint of a part (its physical dimensions and shape).
*
* @extends AbstractPartsContainingDBElement<FootprintAttachment, FootprintParameter>
*/ */
#[ORM\Entity(repositoryClass: FootprintRepository::class)] #[ORM\Entity(repositoryClass: FootprintRepository::class)]
#[ORM\Table('`footprints`')] #[ORM\Table('`footprints`')]
@ -45,9 +47,6 @@ class Footprint extends AbstractPartsContainingDBElement
#[ORM\JoinColumn(name: 'parent_id')] #[ORM\JoinColumn(name: 'parent_id')]
protected ?AbstractStructuralDBElement $parent = null; protected ?AbstractStructuralDBElement $parent = null;
/**
* @var Collection
*/
#[ORM\OneToMany(targetEntity: 'Footprint', mappedBy: 'parent')] #[ORM\OneToMany(targetEntity: 'Footprint', mappedBy: 'parent')]
#[ORM\OrderBy(['name' => 'ASC'])] #[ORM\OrderBy(['name' => 'ASC'])]
protected Collection $children; protected Collection $children;

View file

@ -33,7 +33,9 @@ use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert; use Symfony\Component\Validator\Constraints as Assert;
/** /**
* Class Manufacturer. * This entity represents a manufacturer of a part (The company that produces the part).
*
* @extends AbstractCompany<ManufacturerAttachment, ManufacturerParameter>
*/ */
#[ORM\Entity(repositoryClass: ManufacturerRepository::class)] #[ORM\Entity(repositoryClass: ManufacturerRepository::class)]
#[ORM\Table('`manufacturers`')] #[ORM\Table('`manufacturers`')]
@ -45,9 +47,6 @@ class Manufacturer extends AbstractCompany
#[ORM\JoinColumn(name: 'parent_id')] #[ORM\JoinColumn(name: 'parent_id')]
protected ?AbstractStructuralDBElement $parent = null; protected ?AbstractStructuralDBElement $parent = null;
/**
* @var Collection
*/
#[ORM\OneToMany(targetEntity: 'Manufacturer', mappedBy: 'parent')] #[ORM\OneToMany(targetEntity: 'Manufacturer', mappedBy: 'parent')]
#[ORM\OrderBy(['name' => 'ASC'])] #[ORM\OrderBy(['name' => 'ASC'])]
protected Collection $children; protected Collection $children;

View file

@ -38,6 +38,8 @@ use Symfony\Component\Validator\Constraints as Assert;
/** /**
* This unit represents the unit in which the amount of parts in stock are measured. * This unit represents the unit in which the amount of parts in stock are measured.
* This could be something like N, grams, meters, etc... * This could be something like N, grams, meters, etc...
*
* @extends AbstractPartsContainingDBElement<MeasurementUnitAttachment,MeasurementUnitParameter>
*/ */
#[UniqueEntity('unit')] #[UniqueEntity('unit')]
#[ORM\Entity(repositoryClass: MeasurementUnitRepository::class)] #[ORM\Entity(repositoryClass: MeasurementUnitRepository::class)]
@ -72,9 +74,6 @@ class MeasurementUnit extends AbstractPartsContainingDBElement
#[ORM\Column(type: Types::BOOLEAN, name: 'use_si_prefix')] #[ORM\Column(type: Types::BOOLEAN, name: 'use_si_prefix')]
protected bool $use_si_prefix = false; protected bool $use_si_prefix = false;
/**
* @var Collection
*/
#[ORM\OneToMany(targetEntity: 'MeasurementUnit', mappedBy: 'parent', cascade: ['persist'])] #[ORM\OneToMany(targetEntity: 'MeasurementUnit', mappedBy: 'parent', cascade: ['persist'])]
#[ORM\OrderBy(['name' => 'ASC'])] #[ORM\OrderBy(['name' => 'ASC'])]
protected Collection $children; protected Collection $children;

View file

@ -36,7 +36,8 @@ use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert; use Symfony\Component\Validator\Constraints as Assert;
/** /**
* Class Store location. * This entity represents a storage location, where parts can be stored.
* @extends AbstractPartsContainingDBElement<StorelocationAttachment, StorelocationParameter>
*/ */
#[ORM\Entity(repositoryClass: StorelocationRepository::class)] #[ORM\Entity(repositoryClass: StorelocationRepository::class)]
#[ORM\Table('`storelocations`')] #[ORM\Table('`storelocations`')]
@ -44,9 +45,6 @@ use Symfony\Component\Validator\Constraints as Assert;
#[ORM\Index(name: 'location_idx_parent_name', columns: ['parent_id', 'name'])] #[ORM\Index(name: 'location_idx_parent_name', columns: ['parent_id', 'name'])]
class Storelocation extends AbstractPartsContainingDBElement class Storelocation extends AbstractPartsContainingDBElement
{ {
/**
* @var Collection
*/
#[ORM\OneToMany(targetEntity: 'Storelocation', mappedBy: 'parent')] #[ORM\OneToMany(targetEntity: 'Storelocation', mappedBy: 'parent')]
#[ORM\OrderBy(['name' => 'ASC'])] #[ORM\OrderBy(['name' => 'ASC'])]
protected Collection $children; protected Collection $children;

View file

@ -39,7 +39,9 @@ use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert; use Symfony\Component\Validator\Constraints as Assert;
/** /**
* Class Supplier. * This entity represents a supplier of parts (the company that sells the parts).
*
* @extends AbstractCompany<SupplierAttachment, SupplierParameter>
*/ */
#[ORM\Entity(repositoryClass: SupplierRepository::class)] #[ORM\Entity(repositoryClass: SupplierRepository::class)]
#[ORM\Table('`suppliers`')] #[ORM\Table('`suppliers`')]
@ -47,9 +49,6 @@ use Symfony\Component\Validator\Constraints as Assert;
#[ORM\Index(name: 'supplier_idx_parent_name', columns: ['parent_id', 'name'])] #[ORM\Index(name: 'supplier_idx_parent_name', columns: ['parent_id', 'name'])]
class Supplier extends AbstractCompany class Supplier extends AbstractCompany
{ {
/**
* @var Collection
*/
#[ORM\OneToMany(targetEntity: 'Supplier', mappedBy: 'parent')] #[ORM\OneToMany(targetEntity: 'Supplier', mappedBy: 'parent')]
#[ORM\OrderBy(['name' => 'ASC'])] #[ORM\OrderBy(['name' => 'ASC'])]
protected Collection $children; protected Collection $children;

View file

@ -38,6 +38,8 @@ use Symfony\Component\Validator\Constraints as Assert;
/** /**
* This entity describes a currency that can be used for price information. * This entity describes a currency that can be used for price information.
*
* @extends AbstractStructuralDBElement<CurrencyAttachment, CurrencyParameter>
*/ */
#[UniqueEntity('iso_code')] #[UniqueEntity('iso_code')]
#[ORM\Entity] #[ORM\Entity]

View file

@ -37,15 +37,14 @@ use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Context\ExecutionContextInterface;
/** /**
* Class AttachmentType. * This class represents a project in the database.
*
* @extends AbstractStructuralDBElement<ProjectAttachment, ProjectParameter>
*/ */
#[ORM\Entity(repositoryClass: DeviceRepository::class)] #[ORM\Entity(repositoryClass: DeviceRepository::class)]
#[ORM\Table(name: 'projects')] #[ORM\Table(name: 'projects')]
class Project extends AbstractStructuralDBElement class Project extends AbstractStructuralDBElement
{ {
/**
* @var Collection
*/
#[ORM\OneToMany(targetEntity: 'Project', mappedBy: 'parent')] #[ORM\OneToMany(targetEntity: 'Project', mappedBy: 'parent')]
#[ORM\OrderBy(['name' => 'ASC'])] #[ORM\OrderBy(['name' => 'ASC'])]
protected Collection $children; protected Collection $children;

View file

@ -37,6 +37,8 @@ use Symfony\Component\Validator\Constraints as Assert;
/** /**
* This entity represents a user group. * This entity represents a user group.
*
* @extends AbstractStructuralDBElement<GroupAttachment, GroupParameter>
*/ */
#[ORM\Entity] #[ORM\Entity]
#[ORM\Table('`groups`')] #[ORM\Table('`groups`')]
@ -45,9 +47,6 @@ use Symfony\Component\Validator\Constraints as Assert;
#[NoLockout()] #[NoLockout()]
class Group extends AbstractStructuralDBElement implements HasPermissionsInterface class Group extends AbstractStructuralDBElement implements HasPermissionsInterface
{ {
/**
* @var Collection<int, self>
*/
#[ORM\OneToMany(targetEntity: 'Group', mappedBy: 'parent')] #[ORM\OneToMany(targetEntity: 'Group', mappedBy: 'parent')]
#[ORM\OrderBy(['name' => 'ASC'])] #[ORM\OrderBy(['name' => 'ASC'])]
protected Collection $children; protected Collection $children;

View file

@ -59,6 +59,8 @@ use Jbtronics\TFAWebauthn\Model\TwoFactorInterface as WebauthnTwoFactorInterface
* This entity represents a user, which can log in and have permissions. * This entity represents a user, which can log in and have permissions.
* Also, this entity is able to save some information about the user, like the names, email-address and other info. * Also, this entity is able to save some information about the user, like the names, email-address and other info.
* @see \App\Tests\Entity\UserSystem\UserTest * @see \App\Tests\Entity\UserSystem\UserTest
*
* @extends AttachmentContainingDBElement<UserAttachment>
*/ */
#[UniqueEntity('name', message: 'validator.user.username_already_used')] #[UniqueEntity('name', message: 'validator.user.username_already_used')]
#[ORM\Entity(repositoryClass: UserRepository::class)] #[ORM\Entity(repositoryClass: UserRepository::class)]

View file

@ -52,6 +52,7 @@ class DBElementRepository extends EntityRepository
* You should only use it to undelete former existing elements, everything else is most likely a bad idea! * You should only use it to undelete former existing elements, everything else is most likely a bad idea!
* *
* @param AbstractDBElement $element The element whose ID should be changed * @param AbstractDBElement $element The element whose ID should be changed
* @phpstan-param TEntityClass $element
* @param int $new_id The new ID * @param int $new_id The new ID
*/ */
public function changeID(AbstractDBElement $element, int $new_id): void public function changeID(AbstractDBElement $element, int $new_id): void
@ -73,6 +74,7 @@ class DBElementRepository extends EntityRepository
* Find all elements that match a list of IDs. * Find all elements that match a list of IDs.
* *
* @return AbstractDBElement[] * @return AbstractDBElement[]
* @phpstan-return list<TEntityClass>
*/ */
public function getElementsFromIDArray(array $ids): array public function getElementsFromIDArray(array $ids): array
{ {

View file

@ -26,6 +26,8 @@ use App\Entity\Base\AbstractNamedDBElement;
use App\Entity\Base\AbstractStructuralDBElement; use App\Entity\Base\AbstractStructuralDBElement;
use App\Entity\Parts\Category; use App\Entity\Parts\Category;
use App\Entity\Parts\Part; use App\Entity\Parts\Part;
use Composer\Semver\Constraint\Constraint;
use Symfony\Component\Validator\ConstraintViolationList;
use Symplify\EasyCodingStandard\ValueObject\Option; use Symplify\EasyCodingStandard\ValueObject\Option;
use function count; use function count;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
@ -238,7 +240,7 @@ class EntityImporter
* @param array $options options for the import process * @param array $options options for the import process
* @param AbstractNamedDBElement[] $entities The imported entities are returned in this array * @param AbstractNamedDBElement[] $entities The imported entities are returned in this array
* *
* @return array An associative array containing an ConstraintViolationList and the entity name as key are returned, * @return array<string, ConstraintViolationList> An associative array containing an ConstraintViolationList and the entity name as key are returned,
* if an error happened during validation. When everything was successfully, the array should be empty. * if an error happened during validation. When everything was successfully, the array should be empty.
*/ */
public function importFileAndPersistToDB(File $file, array $options = [], array &$entities = []): array public function importFileAndPersistToDB(File $file, array $options = [], array &$entities = []): array

View file

@ -123,6 +123,6 @@ final class EntityExtension extends AbstractExtension
} }
} }
return false; return null;
} }
} }

View file

@ -54,7 +54,7 @@ final class TwigCoreExtension extends AbstractExtension
*/ */
new TwigTest('instanceof', static fn($var, $instance) => $var instanceof $instance), new TwigTest('instanceof', static fn($var, $instance) => $var instanceof $instance),
/* Checks if a given variable is an object. E.g. `x is object` */ /* Checks if a given variable is an object. E.g. `x is object` */
new TwigTest('object', static fn($var): object => is_object($var)), new TwigTest('object', static fn($var): bool => is_object($var)),
]; ];
} }