Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ECP-9489] Implement PHPStan and fix relevant issues #2843

Open
wants to merge 65 commits into
base: main
Choose a base branch
from

Conversation

candemiralp
Copy link
Member

@candemiralp candemiralp commented Jan 3, 2025

Description

This PR implements automated PHPStan analysis as a part of the workflows. As Magento 2 has its own limitations, we have decided to use bitexpert/phpstan-magento extension to provide platform specific requirements.

Besides implementing PHPStan to the workflows, major issues having Level 0 severity have been fixed. Mainly,

  • Repositories have been used to load & save entities instead of the entity class' themselves.
  • Dynamic property declarations have been refactored.
  • Unit tests have been updated.

Tested scenarios

  • Test workflows
  • All payment flows including partial payments
  • All modification flows including partial payments

Copy link

Please retry analysis of this Pull-Request directly on SonarQube Cloud

Copy link

Please retry analysis of this Pull-Request directly on SonarQube Cloud


if (isset($paymentFormFields) && isset($paymentFormFields
[AdyenPayByLinkDataAssignObserver::PBL_EXPIRY_DATE])) {
if (isset($paymentFormFields[AdyenPayByLinkDataAssignObserver::PBL_EXPIRY_DATE])) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this work as expected if $paymentFormFields is not defined?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the first isset() is redundant. The result will be same even if $paymentFormFields is not defined. isset() first checks the existence of the variable and then checks (multi-dimensional) array keys.

Comment on lines -134 to -142
/** @var AdyenCreditmemoModel $currAdyenCreditmemo */
$currAdyenCreditmemo = $adyenCreditmemoLoader->load(
$adyenCreditmemo[CreditmemoInterface::ENTITY_ID],
CreditmemoInterface::ENTITY_ID
);

if ($currAdyenCreditmemo->getCreditmemoId() !== null) {
continue;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't see why is this being removed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @acampos1916! Thanks for the heads-up!

The beginning of the loop is redundant now. $currAdyenCreditmemo was used to store AdyenCreditMemo object generated by the factory $adyenCreditmemoLoader with the entityId. It became redundant as adyenCreditmemoRepository already returns an AdyenCreditMemo object. We don't need to use object factory to build the entity anymore.

However, the following code snippet shouldn't have been removed. This must be used to identify and skip the already linked Adyen creditmemos. I will re-introduce this snippet.

 if ($currAdyenCreditmemo->getCreditmemoId() !== null) {
                    continue;
                }

@@ -146,7 +140,7 @@ public function createInvoice(Order $order, Notification $notification, bool $is
throw $e;
}

$invoiceAutoMail = (bool)$this->scopeConfig->isSetFlag(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it safe to remove (bool) here? Will isSetFlag always return a boolean?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isSetFlag() method returns bool. It looks like type casting is redundant here.


public function getOrderPaymentStatus(string $orderId, string $cartId): string
{
$quoteIdMask = $this->quoteIdMaskFactory->create()->load($cartId, 'masked_id');
$quoteId = $quoteIdMask->getQuoteId();
$quoteId = $this->maskedQuoteIdToQuoteId->execute($cartId);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this always be an INT? So that intval below works as expected

Copy link
Member Author

@candemiralp candemiralp Feb 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

execute() method always return int if there is an associated cart. If the cart can't be found, it throws NoSuchEntityException.

I believe the type int is safe. But, your question raised another point in my mind. As NoSuchEntityException is not caught here, the application will break unexpectedly. Formerly, quoteIdMaskFactory used to return null which throws __("The entity that was requested doesn't exist. Verify the entity and try again.") safely in the if condition.

Wrapping the execute() method with a try-catch block and catching NoSuchEntityException exception would be nice in favour of throwing the same exception as before.

throw new NotFoundException(
                __("The entity that was requested doesn't exist. Verify the entity and try again.")
            );

What would you think about this conversion?

/*
* Load resource model Adyen\Payment\Model\ResourceModel\Notification manually
* as Magento\Framework\Model\AbstractModel::_getResource() method has been deprecated.
* ObjectManager has been used due to dependencies not being loaded timely manner on entity classes.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it strictly necessary? Let's review this one

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @acampos1916, thank you for the review!

It created a circular dependency if DI patter is used. I would be happy if we can revisit that approach together.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants