fom/module-annotations

There is no license information available for the latest version (1.0.1) of this package.

N/A

1.0.1 2022-04-21 15:32 UTC

This package is auto-updated.

Last update: 2024-04-21 19:59:50 UTC


README

M2 Coding Standard M2 Mess Detector M2 PHPStan

Annotations for Magento 2

During the development of extensions, we often encounter a situation where some plugin or observer should be executed only on certain Magento versions and Magento editions. To solve this problem, we usually inject \Magento\Framework\App\ProductMetadataInterface and then use additional checks for versions and editions.

Annotations for Magento 2 will help solve this problem and provide flexible configuration for conditions combination.

Requirements

  • PHP >= 7.1
  • Magento Any Edition >= 2.3.0

How to install

Install via composer (recommended)

Run the following command in Magento 2 root folder:

composer require fom/module-annotations
php bin/magento setup:upgrade
php bin/magento setup:static-content:deploy

Developer Guide

In Magento 2, all plugins and observers using \Magento\Framework\App\ProductMetadataInterface to check the current version and edition still continue to be instantiated, executed, and use memory and processor. Annotations for Magento 2 module uses an optimized approach, plugins and observers that should not be executed for the current version and edition will be disabled at the stage of building the configuration of plugins and observers. This means that checking whether the plugin or the observer should be executed will be performed ONLY once, at the stage of cache building, which will slightly reduce stack traces, and this in turn should have a positive impact on performance.

Attributes (for PHP >= 8.0) or Doctrine Annotations (for PHP >= 7.1) are used to configure plugins and observers.

Annotations for Magento 2 provides two attribute classes:

Fom\Annotations\Attribute\Platform

The attribute is used to describe the edition, version, and comparison operator for the Magento. This attribute is repeatable, and can be added to the class several times.

Parameters:

Fom\Annotations\Attribute\Operator

The attribute is used if the Platform attribute has been added to the class several times, it is used to summarize the results obtained from Platform list. This attribute is optional and can be applied to a class only 1 time.

Parameters:

Examples

In the examples we will demonstrate observers, but the exact same declaration is used for plugins.

Observer with PHP8 Attributes

Let's disable observer for Any Magento Edition with versions lower than 2.4.4.

<?php

declare(strict_types=1);

namespace Vendor\Module\Observer;

use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;

#[
    \Fom\Annotations\Attribute\Platform(
        edition: \Fom\Annotations\Attribute\Platform::EDITION_ANY,
        version: '2.4.4',
        comparison: \Fom\Annotations\Attribute\Platform::COMPARISON_LESS_THAN
    ),
    \Fom\Annotations\Attribute\Operator(operator: \Fom\Annotations\Attribute\Operator::OPERATOR_AND)
]
class SomeKindOfActionObserver implements ObserverInterface
{
    public function execute(Observer $observer): void
    {
        // ...
    }
}

We can also import our attributes to use a short class name.

<?php

declare(strict_types=1);

namespace Vendor\Module\Observer;

use Fom\Annotations\Attribute\Operator;
use Fom\Annotations\Attribute\Platform;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;

#[
    Platform(
        edition: Platform::EDITION_ANY,
        version: '2.4.4',
        comparison: Platform::COMPARISON_LESS_THAN
    ),
    Operator(operator: Operator::OPERATOR_AND)
]
class SomeKindOfActionObserver implements ObserverInterface
{
    public function execute(Observer $observer): void
    {
        // ...
    }
}

Observer with Doctrine Annotations (PHP < 8.0).

Let's do the same, but with a docblock section to allow use for older PHP versions.

<?php

declare(strict_types=1);

namespace Vendor\Module\Observer;

use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;

/**
 * @\Fom\Annotations\Attribute\Platform(
 *     edition = \Fom\Annotations\Attribute\Platform::EDITION_ANY,
 *     version = "2.4.4",
 *     comparison = \Fom\Annotations\Attribute\Platform::COMPARISON_LESS_THAN
 * )
 * @\Fom\Annotations\Attribute\Operator(operator = \Fom\Annotations\Attribute\Operator::OPERATOR_AND)
 */
class SomeKindOfActionObserver implements ObserverInterface
{
    public function execute(Observer $observer): void
    {
        // ...
    }
}

We can still import our attributes to use a short class name.

<?php

declare(strict_types=1);

namespace Vendor\Module\Observer;

use Fom\Annotations\Attribute\Operator;
use Fom\Annotations\Attribute\Platform;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;

/**
 * @Platform(
 *     edition = Platform::EDITION_ANY,
 *     version = "2.4.4",
 *     comparison = Platform::COMPARISON_LESS_THAN
 * )
 * @Operator(operator = Operator::OPERATOR_AND)
 */
class SomeKindOfActionObserver implements ObserverInterface
{
    public function execute(Observer $observer): void
    {
        // ...
    }
}

Observer with a combined declaration, PHP 8 Attribute and Doctrine annotations, allowing this module to be used with different PHP versions.

We have to use the one-line PHP8 Attribute notation. In this case, our PHP8 Attribute will be interpreted as a comment for older PHP versions, since it starts with #.

<?php

declare(strict_types=1);

namespace Vendor\Module\Observer;

use Fom\Annotations\Attribute\Operator;
use Fom\Annotations\Attribute\Platform;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;

/**
 * @Platform(
 *     edition = Platform::EDITION_ANY,
 *     version = "2.4.4",
 *     comparison = Platform::COMPARISON_LESS_THAN
 * )
 * @Operator(operator = Operator::OPERATOR_AND)
 */
#[Platform(edition: Platform::EDITION_ANY, version: '2.4.4', comparison: Platform::COMPARISON_LESS_THAN), Operator(operator: Operator::OPERATOR_AND)]
class SomeKindOfActionObserver implements ObserverInterface
{
    public function execute(Observer $observer): void
    {
        // ...
    }
}

Example without using the Operator attribute

Since Operator is equal to Operator::OPERATOR_AND by default, we can omit it in the following cases:

We use only one platform condition

<?php

declare(strict_types=1);

namespace Vendor\Module\Observer;

use Fom\Annotations\Attribute\Operator;
use Fom\Annotations\Attribute\Platform;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;

#[
    Platform(
        edition: Platform::EDITION_ANY,
        version: '2.4.4',
        comparison: Platform::COMPARISON_LESS_THAN
    )
]
class SomeKindOfActionObserver implements ObserverInterface
{
    public function execute(Observer $observer): void
    {
        // ...
    }
}

We use several platform conditions, but all their conditions must be satisfied at the same time

<?php

declare(strict_types=1);

namespace Vendor\Module\Observer;

use Fom\Annotations\Attribute\Platform;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;

#[
    Platform(
        edition: Platform::EDITION_COMMERCE,
        version: '2.4.4',
        comparison: Platform::COMPARISON_LESS_THAN
    ),
    Platform(
        edition: Platform::EDITION_B2B,
        version: '2.4.4',
        comparison: Platform::COMPARISON_LESS_THAN
    )
]
class SomeKindOfActionObserver implements ObserverInterface
{
    public function execute(Observer $observer): void
    {
        // ...
    }
}

Example of using Operator::OPERATOR_AND

In rare cases, we may need to use specific conditions when a plugin or an observer must work on different versions and editions at the same time, in this case we can describe several necessary platform conditions and summarize them using Operator::OPERATOR_AND. In this case, if at least one of the conditions is met, our observer or plugin will be executed.

In the example below, the observer will be executed on Magento Community Edition = 2.4.3 or on Magento Commerce Edition = 2.4.2, on any other versions or editions, this observer will be disabled.

<?php

declare(strict_types=1);

namespace Vendor\Module\Observer;

use Fom\Annotations\Attribute\Operator;
use Fom\Annotations\Attribute\Platform;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;

#[
    Platform(
        edition: Platform::EDITION_COMMUNITY,
        version: '2.4.3',
        comparison: Platform::COMPARISON_EQUAL
    ),
    Platform(
        edition: Platform::EDITION_COMMERCE,
        version: '2.4.2',
        comparison: Platform::COMPARISON_LESS_THAN
    ),
    Operator(operator: Operator::OPERATOR_OR)
]
class SomeKindOfActionObserver implements ObserverInterface
{
    public function execute(Observer $observer): void
    {
        // ...
    }
}

Additional Tools

Copyright

Copyright © FriendsOfMagento