Fix checkGenericClassInNonGenericObjectType PHPStan errors

This commit removes the checkGenericClassInNonGenericObjectType flag
from PHPStan configuration files and fixes all associated errors in our
code base.

[MAILPOET-3236]
This commit is contained in:
Rodrigo Primo
2021-07-28 15:08:39 -03:00
committed by Veljko V
parent f0dc0b3556
commit e59992cc16
16 changed files with 51 additions and 26 deletions

View File

@ -13,10 +13,10 @@ abstract class Repository {
/** @var EntityManager */
protected $entityManager;
/** @var ClassMetadata */
/** @var ClassMetadata<object> */
protected $classMetadata;
/** @var DoctrineEntityRepository */
/** @var DoctrineEntityRepository<T> */
protected $doctrineRepository;
/** @var string[] */

View File

@ -25,6 +25,9 @@ class TablePrefixMetadataFactory extends ClassMetadataFactory {
$this->setProxyClassNameResolver(new ProxyClassNameResolver());
}
/**
* @return ClassMetadata<object>
*/
public function getMetadataFor($className) {
$classMetadata = parent::getMetadataFor($className);
if (isset($this->prefixedMap[$classMetadata->getName()])) {
@ -42,6 +45,9 @@ class TablePrefixMetadataFactory extends ClassMetadataFactory {
return $classMetadata;
}
/**
* @param ClassMetadata<object> $classMetadata
*/
public function addPrefix(ClassMetadata $classMetadata) {
if (!$classMetadata->isInheritanceTypeSingleTable() || $classMetadata->getName() === $classMetadata->rootEntityName) {
$classMetadata->setPrimaryTable([

View File

@ -131,25 +131,25 @@ class NewsletterEntity {
/**
* @ORM\OneToMany(targetEntity="MailPoet\Entities\NewsletterEntity", mappedBy="parent")
* @var NewsletterEntity[]|ArrayCollection
* @var ArrayCollection<int, NewsletterEntity>
*/
private $children;
/**
* @ORM\OneToMany(targetEntity="MailPoet\Entities\NewsletterSegmentEntity", mappedBy="newsletter", orphanRemoval=true)
* @var NewsletterSegmentEntity[]|ArrayCollection
* @var ArrayCollection<int, NewsletterSegmentEntity>
*/
private $newsletterSegments;
/**
* @ORM\OneToMany(targetEntity="MailPoet\Entities\NewsletterOptionEntity", mappedBy="newsletter", orphanRemoval=true)
* @var NewsletterOptionEntity[]|ArrayCollection
* @var ArrayCollection<int, NewsletterOptionEntity>
*/
private $options;
/**
* @ORM\OneToMany(targetEntity="MailPoet\Entities\SendingQueueEntity", mappedBy="newsletter")
* @var SendingQueueEntity[]|ArrayCollection
* @var ArrayCollection<int, SendingQueueEntity>
*/
private $queues;
@ -404,21 +404,21 @@ class NewsletterEntity {
}
/**
* @return NewsletterEntity[]|ArrayCollection
* @return ArrayCollection<int, NewsletterEntity>
*/
public function getChildren() {
return $this->children;
}
/**
* @return NewsletterSegmentEntity[]|ArrayCollection
* @return ArrayCollection<int, NewsletterSegmentEntity>
*/
public function getNewsletterSegments() {
return $this->newsletterSegments;
}
/**
* @return NewsletterOptionEntity[]|ArrayCollection
* @return ArrayCollection<int, NewsletterOptionEntity>
*/
public function getOptions() {
return $this->options;
@ -437,7 +437,7 @@ class NewsletterEntity {
}
/**
* @return SendingQueueEntity[]|ArrayCollection
* @return ArrayCollection<int, SendingQueueEntity>
*/
public function getQueues() {
return $this->queues;
@ -453,6 +453,9 @@ class NewsletterEntity {
return $this->queues->matching($criteria)->first() ?: null;
}
/**
* @return Collection<int, SendingQueueEntity>
*/
private function getUnfinishedQueues(): Collection {
$criteria = new Criteria();
$expr = Criteria::expr();

View File

@ -50,7 +50,7 @@ class NewsletterLinkEntity {
* If we didn't specify extra lazy the function would load all clicks and count them. This way it uses a single count query.
* @ORM\OneToMany(targetEntity="MailPoet\Entities\StatisticsClickEntity", mappedBy="link", fetch="EXTRA_LAZY")
*
* @var StatisticsClickEntity[]|ArrayCollection
* @var ArrayCollection<int, StatisticsClickEntity>
*/
private $clicks;

View File

@ -50,7 +50,7 @@ class SegmentEntity {
/**
* @ORM\OneToMany(targetEntity="MailPoet\Entities\DynamicSegmentFilterEntity", mappedBy="segment")
* @var DynamicSegmentFilterEntity[]|ArrayCollection
* @var ArrayCollection<int, DynamicSegmentFilterEntity>
*/
private $dynamicFilters;
@ -121,7 +121,7 @@ class SegmentEntity {
}
/**
* @return DynamicSegmentFilterEntity[]|ArrayCollection
* @return ArrayCollection<int, DynamicSegmentFilterEntity>
*/
public function getDynamicFilters() {
return $this->dynamicFilters;

View File

@ -48,7 +48,7 @@ class StatisticsClickEntity {
/**
* @ORM\OneToMany(targetEntity="MailPoet\Entities\StatisticsWooCommercePurchaseEntity", mappedBy="click", fetch="EXTRA_LAZY")*
* @var StatisticsWooCommercePurchaseEntity[]|ArrayCollection
* @var ArrayCollection<int, StatisticsWooCommercePurchaseEntity>
*/
private $wooCommercePurchases;
@ -140,7 +140,7 @@ class StatisticsClickEntity {
}
/**
* @return StatisticsWooCommercePurchaseEntity[]|ArrayCollection
* @return ArrayCollection<int, StatisticsWooCommercePurchaseEntity>
*/
public function getWooCommercePurchases() {
return $this->wooCommercePurchases;

View File

@ -139,7 +139,7 @@ class SubscriberEntity {
/**
* @ORM\OneToMany(targetEntity="MailPoet\Entities\SubscriberSegmentEntity", mappedBy="subscriber")
* @var iterable<SubscriberSegmentEntity>&Collection
* @var Collection<int, SubscriberSegmentEntity>
*/
private $subscriberSegments;
@ -395,7 +395,7 @@ class SubscriberEntity {
}
/**
* @return Collection
* @return Collection<int, SubscriberSegmentEntity>
*/
public function getSubscriberSegments() {
return $this->subscriberSegments;

View File

@ -36,8 +36,8 @@ class AbandonedCartContent {
$optionField = $newsletterOption->getOptionField();
return $optionField && $optionField->getName() === 'event';
})->first();
if ($groupOption->getValue() !== WooCommerceEmail::SLUG
|| $eventOption->getValue() !== AbandonedCart::SLUG
if (($groupOption instanceof NewsletterOptionEntity && $groupOption->getValue() !== WooCommerceEmail::SLUG)
|| ($eventOption instanceof NewsletterOptionEntity && $eventOption->getValue() !== AbandonedCart::SLUG)
) {
// Do not display the block if not an AbandonedCart email
return [];

View File

@ -111,8 +111,10 @@ class SegmentsRepository extends Repository {
// We want to remove redundant filters before update
while ($segment->getDynamicFilters()->count() > count($filtersData)) {
$filterEntity = $segment->getDynamicFilters()->last();
$segment->getDynamicFilters()->removeElement($filterEntity);
$this->entityManager->remove($filterEntity);
if ($filterEntity) {
$segment->getDynamicFilters()->removeElement($filterEntity);
$this->entityManager->remove($filterEntity);
}
}
foreach ($filtersData as $key => $filterData) {
if ($filterData instanceof DynamicSegmentFilterData) {

View File

@ -54,6 +54,9 @@ class ImportExportRepository {
$this->filterHandler = $filterHandler;
}
/**
* @return ClassMetadata<object>
*/
protected function getClassMetadata(string $className): ClassMetadata {
return $this->entityManager->getClassMetadata($className);
}

View File

@ -4,6 +4,9 @@ namespace MailPoet\Tasks\Subscribers;
use MailPoet\Models\ScheduledTaskSubscriber;
/**
* @implements \Iterator<null, array>
*/
class BatchIterator implements \Iterator, \Countable {
private $taskId;
private $batchSize;

View File

@ -20,10 +20,10 @@ class ApiPanel implements IBarPanel {
/** @var array */
protected $requestData;
/** @var ReflectionClass */
/** @var ReflectionClass<APIEndpoint> */
protected $endpointReflection;
public function __construct($endpoint, $requestMethod, $requestData) {
public function __construct(APIEndpoint $endpoint, $requestMethod, $requestData) {
$this->endpoint = $endpoint;
$this->requestMethod = $requestMethod;
$this->requestData = $requestData;

View File

@ -32,7 +32,6 @@ parameters:
maximumNumberOfProcesses: 4
# exclude level 6 errors
checkGenericClassInNonGenericObjectType: false
checkMissingIterableValueType: false
checkMissingTypehints: false

View File

@ -28,7 +28,6 @@ parameters:
objectManagerLoader: create-entity-manager.php
# exclude level 6 errors
checkGenericClassInNonGenericObjectType: false
checkMissingIterableValueType: false
# analysis of templates is extremely slow, let's skip them for now

View File

@ -112,6 +112,7 @@ class NewsletterSaveControllerTest extends \MailPoetTest {
return $optionField && $optionField->getName() === 'schedule';
})->first();
assert($scheduleOption instanceof NewsletterOptionEntity); // PHPStan
expect($scheduleOption->getValue())->equals('0 14 * * 1');
// schedule should be recalculated when options change
@ -123,6 +124,7 @@ class NewsletterSaveControllerTest extends \MailPoetTest {
return $optionField && $optionField->getName() === 'schedule';
})->first();
assert($scheduleOption instanceof NewsletterOptionEntity); // PHPStan
expect($scheduleOption->getValue())->equals('* * * * *');
}
@ -165,6 +167,7 @@ class NewsletterSaveControllerTest extends \MailPoetTest {
return $optionField && $optionField->getName() === 'schedule';
})->first();
expect($task1->getScheduledAt())->notEquals($currentTime);
assert($scheduleOption instanceof NewsletterOptionEntity); // PHPStan
expect($task1->getScheduledAt())->equals(Scheduler::getNextRunDate($scheduleOption->getValue()));
expect($task2->getScheduledAt())->null();
}
@ -187,7 +190,11 @@ class NewsletterSaveControllerTest extends \MailPoetTest {
$newsletter = $this->saveController->save($newsletterData);
expect(count($newsletter->getNewsletterSegments()))->equals(1);
expect($newsletter->getNewsletterSegments()->first()->getSegment()->getName())->equals('Segment 1');
$newsletterSegment = $newsletter->getNewsletterSegments()->first();
assert($newsletterSegment instanceof NewsletterSegmentEntity); // PHPStan
$segment = $newsletterSegment->getSegment();
assert($segment instanceof SegmentEntity); // PHPStan
expect($segment->getName())->equals('Segment 1');
}
public function testItDeletesSendingQueueAndSetsNewsletterStatusToDraftWhenItIsUnscheduled() {

View File

@ -6,6 +6,9 @@ class HtmlParser {
private $allowedHtml5Tags = ['<figure', '<figcaption'];
/**
* @return \DOMNodeList<\DOMNode>
*/
public function findByXpath(string $html, string $xpath): \DOMNodeList {
$isHtml5 = str_replace($this->allowedHtml5Tags, '', $html) !== $html;
$dom = new \DOMDocument();