diff --git a/phpstan.neon b/phpstan.neon index 8aea6a8e..a335376b 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,5 +1,6 @@ parameters: inferPrivatePropertyTypeFromConstructor: true + treatPhpDocTypesAsCertain: false symfony: container_xml_path: '%rootDir%/../../../var/cache/dev/srcApp_KernelDevDebugContainer.xml' diff --git a/src/Command/CleanAttachmentsCommand.php b/src/Command/CleanAttachmentsCommand.php index f099baf2..c38c5dfe 100644 --- a/src/Command/CleanAttachmentsCommand.php +++ b/src/Command/CleanAttachmentsCommand.php @@ -86,7 +86,7 @@ class CleanAttachmentsCommand extends Command $table = new Table($output); $table->setHeaders(['Filename', 'MIME Type', 'Last modified date']); - $dateformatter = IntlDateFormatter::create(null, IntlDateFormatter::SHORT, IntlDateFormatter::SHORT); + $dateformatter = IntlDateFormatter::create(\Locale::getDefault(), IntlDateFormatter::SHORT, IntlDateFormatter::SHORT); foreach ($finder as $file) { //If not attachment object uses this file, print it diff --git a/src/Command/SetPasswordCommand.php b/src/Command/SetPasswordCommand.php index ac895d77..a95819af 100644 --- a/src/Command/SetPasswordCommand.php +++ b/src/Command/SetPasswordCommand.php @@ -64,14 +64,15 @@ class SetPasswordCommand extends Command /** @var User[] $users */ $users = $this->entityManager->getRepository(User::class)->findBy(['name' => $user_name]); - $user = $users[0]; - if (null === $user) { + if (empty($users)) { $io->error(sprintf('No user with the given username %s found in the database!', $user_name)); return 1; } + $user = $users[0]; + $io->note('User found!'); $proceed = $io->confirm( diff --git a/src/Controller/AdminPages/BaseAdminController.php b/src/Controller/AdminPages/BaseAdminController.php index b5f5ed31..3a76c15d 100644 --- a/src/Controller/AdminPages/BaseAdminController.php +++ b/src/Controller/AdminPages/BaseAdminController.php @@ -130,7 +130,7 @@ abstract class BaseAdminController extends AbstractController protected function _new(Request $request, EntityManagerInterface $em, EntityImporter $importer) { - /** @var StructuralDBElement $new_entity */ + /** @var StructuralDBElement|User $new_entity */ $new_entity = new $this->entity_class(); $this->denyAccessUnlessGranted('read', $new_entity); diff --git a/src/Controller/UserSettingsController.php b/src/Controller/UserSettingsController.php index 1338d02f..a2911bbf 100644 --- a/src/Controller/UserSettingsController.php +++ b/src/Controller/UserSettingsController.php @@ -236,9 +236,9 @@ class UserSettingsController extends AbstractController ], ], 'constraints' => [new Length([ - 'min' => 6, - 'max' => 128, - ])], + 'min' => 6, + 'max' => 128, + ])], ]) ->add('submit', SubmitType::class, ['label' => 'save']) ->getForm(); @@ -278,15 +278,13 @@ class UserSettingsController extends AbstractController return $this->redirectToRoute('user_settings'); } - if ($google_enabled) { - //Remove secret to disable google authenticator - $user->setGoogleAuthenticatorSecret(null); - $backupCodeManager->disableBackupCodesIfUnused($user); - $em->flush(); - $this->addFlash('success', 'user.settings.2fa.google.disabled'); + //Remove secret to disable google authenticator + $user->setGoogleAuthenticatorSecret(null); + $backupCodeManager->disableBackupCodesIfUnused($user); + $em->flush(); + $this->addFlash('success', 'user.settings.2fa.google.disabled'); - return $this->redirectToRoute('user_settings'); - } + return $this->redirectToRoute('user_settings'); } $backup_form = $this->get('form.factory')->createNamedBuilder('backup_codes')->add('reset_codes', SubmitType::class, [ diff --git a/src/DataTables/Column/EntityColumn.php b/src/DataTables/Column/EntityColumn.php index b8994e5f..f4ce6c35 100644 --- a/src/DataTables/Column/EntityColumn.php +++ b/src/DataTables/Column/EntityColumn.php @@ -57,7 +57,7 @@ class EntityColumn extends AbstractColumn return $value; } - public function configureOptions(OptionsResolver $resolver): void + public function configureOptions(OptionsResolver $resolver) { parent::configureOptions($resolver); @@ -69,7 +69,7 @@ class EntityColumn extends AbstractColumn $resolver->setDefault('render', function (Options $options) { return function ($value, Part $context) use ($options) { - /** @var DBElement $entity */ + /** @var DBElement|null $entity */ $entity = $this->accessor->getValue($context, $options['property']); if ($entity) { @@ -83,7 +83,10 @@ class EntityColumn extends AbstractColumn return sprintf('%s', $value); } + throw new \InvalidArgumentException('$entity must not be null!'); }; }); + + return $this; } } diff --git a/src/DataTables/Column/LogEntryTargetColumn.php b/src/DataTables/Column/LogEntryTargetColumn.php index 327b7f07..db937d77 100644 --- a/src/DataTables/Column/LogEntryTargetColumn.php +++ b/src/DataTables/Column/LogEntryTargetColumn.php @@ -58,9 +58,10 @@ class LogEntryTargetColumn extends AbstractColumn return $value; } - public function configureOptions(OptionsResolver $resolver): void + public function configureOptions(OptionsResolver $resolver) { parent::configureOptions($resolver); + return $this; } public function render($value, $context) diff --git a/src/DataTables/Column/PartAttachmentsColumn.php b/src/DataTables/Column/PartAttachmentsColumn.php index a4530741..974aa1d7 100644 --- a/src/DataTables/Column/PartAttachmentsColumn.php +++ b/src/DataTables/Column/PartAttachmentsColumn.php @@ -91,8 +91,9 @@ class PartAttachmentsColumn extends AbstractColumn return $tmp; } - public function configureOptions(OptionsResolver $resolver): void + public function configureOptions(OptionsResolver $resolver) { parent::configureOptions($resolver); + return $this; } } diff --git a/src/Entity/Attachments/Attachment.php b/src/Entity/Attachments/Attachment.php index 0288c416..b9a507a6 100644 --- a/src/Entity/Attachments/Attachment.php +++ b/src/Entity/Attachments/Attachment.php @@ -79,7 +79,7 @@ abstract class Attachment extends NamedDBElement public const ALLOWED_ELEMENT_CLASS = ''; /** - * @var string 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 * @ORM\Column(type="string", nullable=true) */ protected $original_filename; diff --git a/src/Entity/Attachments/AttachmentContainingDBElement.php b/src/Entity/Attachments/AttachmentContainingDBElement.php index cc447695..7fc3c153 100644 --- a/src/Entity/Attachments/AttachmentContainingDBElement.php +++ b/src/Entity/Attachments/AttachmentContainingDBElement.php @@ -43,7 +43,7 @@ abstract class AttachmentContainingDBElement extends NamedDBElement * * Mapping is done in sub classes like part */ - protected $attachments = []; + protected $attachments; public function __construct() { diff --git a/src/Entity/Base/DBElement.php b/src/Entity/Base/DBElement.php index 8d260e34..4a0cf09c 100644 --- a/src/Entity/Base/DBElement.php +++ b/src/Entity/Base/DBElement.php @@ -58,7 +58,8 @@ use Symfony\Component\Serializer\Annotation\Groups; */ abstract class DBElement { - /** @var int The Identification number for this part. This value is unique for the element in this table. + /** @var int|null The Identification number for this part. This value is unique for the element in this table. + * Null if the element is not saved to DB yet. * @ORM\Column(type="integer") * @ORM\Id() * @ORM\GeneratedValue() diff --git a/src/Entity/Base/StructuralDBElement.php b/src/Entity/Base/StructuralDBElement.php index 53d14b58..b141d524 100644 --- a/src/Entity/Base/StructuralDBElement.php +++ b/src/Entity/Base/StructuralDBElement.php @@ -81,10 +81,11 @@ abstract class StructuralDBElement extends AttachmentContainingDBElement * We can not define the mapping here or we will get an exception. Unfortunately we have to do the mapping in the * subclasses. * - * @var StructuralDBElement[] + * @var StructuralDBElement[]|Collection * @Groups({"include_children"}) */ - protected $children = []; + protected $children; + /** * @var StructuralDBElement * @NoneOfItsChildren() @@ -249,7 +250,7 @@ abstract class StructuralDBElement extends AttachmentContainingDBElement /** * Get all sub elements of this element. * - * @return Collection all subelements as an array of objects (sorted by their full path) + * @return Collection|iterable all subelements as an array of objects (sorted by their full path) */ public function getSubelements(): iterable { @@ -257,7 +258,7 @@ abstract class StructuralDBElement extends AttachmentContainingDBElement } /** - * @return Collection + * @return Collection|iterable */ public function getChildren(): iterable { @@ -311,9 +312,17 @@ abstract class StructuralDBElement extends AttachmentContainingDBElement return $this; } - public function setChildren(array $element): self + /** + * @param static[]|Collection $elements + * @return $this + */ + public function setChildren($elements): self { - $this->children = $element; + if (!is_array($elements) && !$elements instanceof Collection) { + throw new InvalidArgumentException('$elements must be an array or Collection!'); + } + + $this->children = $elements; return $this; } diff --git a/src/Entity/Parts/Supplier.php b/src/Entity/Parts/Supplier.php index 9c8da03f..0940755f 100644 --- a/src/Entity/Parts/Supplier.php +++ b/src/Entity/Parts/Supplier.php @@ -93,7 +93,7 @@ class Supplier extends Company protected $default_currency; /** - * @var float|null the shipping costs that have to be paid, when ordering via this supplier + * @var string|null the shipping costs that have to be paid, when ordering via this supplier * @ORM\Column(name="shipping_costs", nullable=true, type="decimal", precision=11, scale=5) * @Assert\PositiveOrZero() */ diff --git a/src/Entity/PriceInformations/Pricedetail.php b/src/Entity/PriceInformations/Pricedetail.php index 133c5acb..22ecac1d 100644 --- a/src/Entity/PriceInformations/Pricedetail.php +++ b/src/Entity/PriceInformations/Pricedetail.php @@ -109,7 +109,7 @@ class Pricedetail extends DBElement protected $manual_input = true; /** - * @var Orderdetail + * @var Orderdetail|null * @ORM\ManyToOne(targetEntity="Orderdetail", inversedBy="pricedetails") * @ORM\JoinColumn(name="orderdetails_id", referencedColumnName="id", nullable=false, onDelete="CASCADE") * @Assert\NotNull() diff --git a/src/Entity/UserSystem/U2FKey.php b/src/Entity/UserSystem/U2FKey.php index 446692f5..c77af17c 100644 --- a/src/Entity/UserSystem/U2FKey.php +++ b/src/Entity/UserSystem/U2FKey.php @@ -103,9 +103,10 @@ class U2FKey implements TwoFactorKeyInterface return $this->keyHandle; } - public function setKeyHandle($keyHandle): void + public function setKeyHandle($keyHandle): self { $this->keyHandle = $keyHandle; + return $this; } public function getPublicKey() @@ -113,9 +114,10 @@ class U2FKey implements TwoFactorKeyInterface return $this->publicKey; } - public function setPublicKey($publicKey): void + public function setPublicKey($publicKey): self { $this->publicKey = $publicKey; + return $this; } public function getCertificate() @@ -123,9 +125,10 @@ class U2FKey implements TwoFactorKeyInterface return $this->certificate; } - public function setCertificate($certificate): void + public function setCertificate($certificate): self { $this->certificate = $certificate; + return $this; } public function getCounter() @@ -133,9 +136,10 @@ class U2FKey implements TwoFactorKeyInterface return $this->counter; } - public function setCounter($counter): void + public function setCounter($counter): self { $this->counter = $counter; + return $this; } public function getName() @@ -143,9 +147,10 @@ class U2FKey implements TwoFactorKeyInterface return $this->name; } - public function setName($name): void + public function setName($name): self { $this->name = $name; + return $this; } /** @@ -173,7 +178,7 @@ class U2FKey implements TwoFactorKeyInterface * * @return $this */ - public function setUser(TwoFactorInterface $new_user): self + public function setUser(User $new_user): self { $this->user = $new_user; diff --git a/src/Entity/UserSystem/User.php b/src/Entity/UserSystem/User.php index 40dc02bf..3cdfe9e1 100644 --- a/src/Entity/UserSystem/User.php +++ b/src/Entity/UserSystem/User.php @@ -234,7 +234,7 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe */ protected $attachments; - /** @var DateTime The time when the backup codes were generated + /** @var DateTime|null The time when the backup codes were generated * @ORM\Column(type="datetime", nullable=true) */ protected $backupCodesGenerationDate; @@ -351,9 +351,9 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe /** * @see UserInterface */ - public function getSalt(): void + public function getSalt(): ?string { - // not needed when using the "bcrypt" algorithm in security.yaml + return null; } /** diff --git a/src/EventSubscriber/SymfonyDebugToolbarSubscriber.php b/src/EventSubscriber/SymfonyDebugToolbarSubscriber.php index c42ad500..68c3ca12 100644 --- a/src/EventSubscriber/SymfonyDebugToolbarSubscriber.php +++ b/src/EventSubscriber/SymfonyDebugToolbarSubscriber.php @@ -67,6 +67,6 @@ final class SymfonyDebugToolbarSubscriber implements EventSubscriberInterface } $response = $event->getResponse(); - $response->headers->set('Symfony-Debug-Toolbar-Replace', 1); + $response->headers->set('Symfony-Debug-Toolbar-Replace', '1'); } } diff --git a/src/EventSubscriber/U2FRegistrationSubscriber.php b/src/EventSubscriber/U2FRegistrationSubscriber.php index 54622d6c..3e55d03a 100644 --- a/src/EventSubscriber/U2FRegistrationSubscriber.php +++ b/src/EventSubscriber/U2FRegistrationSubscriber.php @@ -25,6 +25,7 @@ declare(strict_types=1); namespace App\EventSubscriber; use App\Entity\UserSystem\U2FKey; +use App\Entity\UserSystem\User; use Doctrine\ORM\EntityManagerInterface; use R\U2FTwoFactorBundle\Event\RegisterEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -63,6 +64,10 @@ final class U2FRegistrationSubscriber implements EventSubscriberInterface //Skip adding of U2F key on demo mode if (! $this->demo_mode) { $user = $event->getUser(); + if (!$user instanceof User) { + throw new \InvalidArgumentException("Only User objects can be registered for U2F!"); + } + $registration = $event->getRegistration(); $newKey = new U2FKey(); $newKey->fromRegistrationData($registration); diff --git a/src/Helpers/Trees/StructuralDBElementIterator.php b/src/Helpers/Trees/StructuralDBElementIterator.php index 285213b0..fe0ab0d4 100644 --- a/src/Helpers/Trees/StructuralDBElementIterator.php +++ b/src/Helpers/Trees/StructuralDBElementIterator.php @@ -26,6 +26,7 @@ namespace App\Helpers\Trees; use App\Entity\Base\StructuralDBElement; use ArrayIterator; +use Doctrine\Common\Collections\Collection; use RecursiveIterator; final class StructuralDBElementIterator extends ArrayIterator implements RecursiveIterator @@ -48,6 +49,15 @@ final class StructuralDBElementIterator extends ArrayIterator implements Recursi /** @var StructuralDBElement $element */ $element = $this->current(); - return new self($element->getSubelements()->toArray()); + $subelements = $element->getSubelements(); + if (is_array($subelements)) { + $array = $subelements; + } elseif ($subelements instanceof Collection) { + $array = $subelements->toArray(); + } else { + throw new \InvalidArgumentException('Invalid subelements type on $element!'); + } + + return new self($array); } } diff --git a/src/Services/Attachments/AttachmentReverseSearch.php b/src/Services/Attachments/AttachmentReverseSearch.php index ab3a7d18..10a08773 100644 --- a/src/Services/Attachments/AttachmentReverseSearch.php +++ b/src/Services/Attachments/AttachmentReverseSearch.php @@ -91,7 +91,7 @@ class AttachmentReverseSearch $this->cacheManager->remove($this->attachmentURLGenerator->absolutePathToAssetPath($file->getPathname())); $fs = new Filesystem(); - $fs->remove($file); + $fs->remove($file->getPathname()); return true; } diff --git a/src/Services/EntityImporter.php b/src/Services/EntityImporter.php index 5c6a4955..7cfb7a7a 100644 --- a/src/Services/EntityImporter.php +++ b/src/Services/EntityImporter.php @@ -25,6 +25,7 @@ declare(strict_types=1); namespace App\Services; use App\Entity\Base\StructuralDBElement; +use Symfony\Bundle\MakerBundle\Str; use function count; use Doctrine\ORM\EntityManagerInterface; use InvalidArgumentException; @@ -133,7 +134,7 @@ class EntityImporter $tmp = $this->validator->validate($entity); //When no validation error occured, persist entity to database (cascade must be set in entity) - if (0 === count($errors)) { + if (empty($tmp)) { $this->em->persist($entity); } else { //Log validation errors to global log. $errors[$entity->getFullPath()] = $tmp; @@ -210,7 +211,7 @@ class EntityImporter * This functions corrects the parent setting based on the children value of the parent. * * @param iterable $entities the list of entities that should be fixed - * @param null $parent the parent, to which the entity should be set + * @param null|StructuralDBElement $parent the parent, to which the entity should be set */ protected function correctParentEntites(iterable $entities, $parent = null): void { diff --git a/src/Services/PasswordResetManager.php b/src/Services/PasswordResetManager.php index 7657aa31..e83279c8 100644 --- a/src/Services/PasswordResetManager.php +++ b/src/Services/PasswordResetManager.php @@ -96,19 +96,19 @@ class PasswordResetManager /** * Sets the new password of the user with the given name, if the token is valid. * - * @param string $user The name of the user, which password should be reset + * @param string $username The name of the user, which password should be reset * @param string $token The token that should be used to reset the password * @param string $new_password The new password that should be applied to user * * @return bool Returns true, if the new password was applied. False, if either the username is unknown or the * token is invalid or expired. */ - public function setNewPassword(string $user, string $token, string $new_password): bool + public function setNewPassword(string $username, string $token, string $new_password): bool { //Try to find the user $repo = $this->em->getRepository(User::class); - /** @var User $user */ - $user = $repo->findOneBy(['name' => $user]); + /** @var User|null $user */ + $user = $repo->findOneBy(['name' => $username]); //If no user matching the name, show an error message if (null === $user) { diff --git a/src/Services/PermissionResolver.php b/src/Services/PermissionResolver.php index eb4dc78f..2b6a29c1 100644 --- a/src/Services/PermissionResolver.php +++ b/src/Services/PermissionResolver.php @@ -25,6 +25,7 @@ declare(strict_types=1); namespace App\Services; use App\Configuration\PermissionsConfiguration; +use App\Entity\UserSystem\Group; use App\Entity\UserSystem\User; use App\Security\Interfaces\HasPermissionsInterface; use Symfony\Component\Config\ConfigCache; @@ -109,6 +110,7 @@ class PermissionResolver return $allowed; } + /** @var HasPermissionsInterface $parent */ $parent = $user->getGroup(); while (null !== $parent) { //The top group, has parent == null //Check if our current element gives a info about disallow/allow diff --git a/src/Services/PricedetailHelper.php b/src/Services/PricedetailHelper.php index 6039549c..81c1bcca 100644 --- a/src/Services/PricedetailHelper.php +++ b/src/Services/PricedetailHelper.php @@ -191,7 +191,7 @@ class PricedetailHelper $val_base = $value; if (null !== $originCurrency) { //Without an exchange rate we can not calculate the exchange rate - if (0 === (float) $originCurrency->getExchangeRate()) { + if (0.0 === (float) $originCurrency->getExchangeRate()) { return null; }