[FEAT] refacto OrderAttributesRector (#2243)

* [FEAT] refacto OrderAttributesRector to allow strategy instead of specific array

* [DOC] update doc OrderAttributesRector

* [FIX] add option default value

* [REFACTO] create SpecificOrder folder

* [TU] add tu AlphabeticallOrder

* [FIX] use isAlphabetically instead of duplicate function logic

* [FIX] fix phpstan errors

* [FIX] fix NoNestedFuncCallRule ignore rule for OrderAttributesRector
This commit is contained in:
Lenny4 2022-05-09 06:44:14 -04:00 committed by GitHub
parent 97a33aa694
commit 4468743419
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 366 additions and 63 deletions

View File

@ -2068,21 +2068,45 @@ Order attributes by desired names
- class: [`Rector\CodingStyle\Rector\ClassMethod\OrderAttributesRector`](../rules/CodingStyle/Rector/ClassMethod/OrderAttributesRector.php)
#### 1) Order by specific namespace
```php
use Rector\CodingStyle\Rector\ClassMethod\OrderAttributesRector;
use Rector\Config\RectorConfig;
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->ruleWithConfiguration(OrderAttributesRector::class, ['First', 'Second']);
$rectorConfig->ruleWithConfiguration(OrderAttributesRector::class, [Annotation\First::class, Annotation\Second::class]);
};
```
```diff
+#[First]
#[Second]
-#[First]
+#[Annotation\First]
#[Annotation\Second]
-#[Annotation\First]
class Someclass
{
}
```
#### 2) Order alphabetically
```php
use Rector\CodingStyle\Rector\ClassMethod\OrderAttributesRector;
use Rector\Config\RectorConfig;
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->ruleWithConfiguration(OrderAttributesRector::class, [Rector\CodingStyle\Rector\ClassMethod::ALPHABETICALLY]);
};
```
```diff
+#[Annotation\AAttribute]
#[Annotation\BAttribute]
-#[Annotation\AAttribute]
class Someclass
{
}

View File

@ -385,6 +385,10 @@ parameters:
message: '#Use separate function calls with readable variable names#'
path: src/DependencyInjection/Loader/Configurator/RectorServiceConfigurator.php
-
message: '#Use separate function calls with readable variable names#'
path: rules/CodingStyle/Rector/ClassMethod/OrderAttributesRector.php
# on purpose to make use of worker paralle pattern
-
message: '#Instead of abstract class, use specific service with composition#'

View File

@ -0,0 +1,31 @@
<?php
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Fixture;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Source\AAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Source\BAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Source\CAttribute;
#[CAttribute]
#[AAttribute, BAttribute]
final class FirstFromMultipleAttrInAttrGroups
{
}
?>
-----
<?php
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Fixture;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Source\AAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Source\BAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Source\CAttribute;
#[AAttribute, BAttribute]
#[CAttribute]
final class FirstFromMultipleAttrInAttrGroups
{
}
?>

View File

@ -0,0 +1,33 @@
<?php
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Fixture;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Source\AAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Source\BAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Source\CAttribute;
#[CAttribute]
#[AAttribute]
#[BAttribute]
class OneAround
{
}
?>
-----
<?php
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Fixture;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Source\AAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Source\BAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Source\CAttribute;
#[AAttribute]
#[BAttribute]
#[CAttribute]
class OneAround
{
}
?>

View File

@ -0,0 +1,12 @@
<?php
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Fixture;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Source\AAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Source\BAttribute;
#[AAttribute]
#[BAttribute]
class SkipExpectedOrder
{
}

View File

@ -0,0 +1,15 @@
<?php
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Fixture;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Source\AAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Source\BAttribute;
/**
* @some
*/
#[AAttribute]
#[BAttribute]
class SkipExpectedOrderWithAround
{
}

View File

@ -0,0 +1,14 @@
<?php
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Fixture;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Source\AAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Source\BAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Source\CAttribute;
#[AAttribute]
#[BAttribute]
#[CAttribute]
class SkipExpectedOrderWithAround
{
}

View File

@ -0,0 +1,29 @@
<?php
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Fixture;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Source\AAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Source\BAttribute;
#[BAttribute]
#[AAttribute]
class Someclass
{
}
?>
-----
<?php
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Fixture;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Source\AAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Source\BAttribute;
#[AAttribute]
#[BAttribute]
class Someclass
{
}
?>

View File

@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder;
use Iterator;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
use Symplify\SmartFileSystem\SmartFileInfo;
final class OrderAttributesRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(SmartFileInfo $fileInfo): void
{
$this->doTestFileInfo($fileInfo);
}
/**
* @return Iterator<SmartFileInfo>
*/
public function provideData(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
}
public function provideConfigFilePath(): string
{
return __DIR__ . '/config/configured_rule.php';
}
}

View File

@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Source;
use Attribute;
#[Attribute]
final class AAttribute
{
}

View File

@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Source;
use Attribute;
#[Attribute]
final class BAttribute
{
}

View File

@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\AlphabeticallOrder\Source;
use Attribute;
#[Attribute]
final class CAttribute
{
}

View File

@ -0,0 +1,11 @@
<?php
declare(strict_types=1);
use Rector\CodingStyle\Rector\ClassMethod\OrderAttributesRector;
use Rector\Config\RectorConfig;
return static function (RectorConfig $rectorConfig): void {
$rectorConfig
->ruleWithConfiguration(OrderAttributesRector::class, [OrderAttributesRector::ALPHABETICALLY]);
};

View File

@ -1,10 +1,10 @@
<?php
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Fixture;
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Fixture;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Source\FirstAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Source\SecondAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Source\ThirdAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Source\FirstAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Source\SecondAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Source\ThirdAttribute;
#[ThirdAttribute]
#[FirstAttribute, SecondAttribute]
@ -16,11 +16,11 @@ final class FirstFromMultipleAttrInAttrGroups
-----
<?php
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Fixture;
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Fixture;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Source\FirstAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Source\SecondAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Source\ThirdAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Source\FirstAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Source\SecondAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Source\ThirdAttribute;
#[FirstAttribute, SecondAttribute]
#[ThirdAttribute]

View File

@ -1,10 +1,10 @@
<?php
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Fixture;
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Fixture;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Source\FirstAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Source\SecondAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Source\ThirdAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Source\FirstAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Source\SecondAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Source\ThirdAttribute;
#[ThirdAttribute]
#[FirstAttribute]
@ -17,11 +17,11 @@ class OneAround
-----
<?php
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Fixture;
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Fixture;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Source\FirstAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Source\SecondAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Source\ThirdAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Source\FirstAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Source\SecondAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Source\ThirdAttribute;
#[FirstAttribute]
#[SecondAttribute]

View File

@ -1,9 +1,9 @@
<?php
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Fixture;
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Fixture;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Source\FirstAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Source\SecondAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Source\FirstAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Source\SecondAttribute;
#[FirstAttribute]
#[SecondAttribute]

View File

@ -1,10 +1,9 @@
<?php
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Fixture;
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Fixture;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Source\FirstAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Source\SecondAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Source\ThirdAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Source\FirstAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Source\SecondAttribute;
/**
* @some

View File

@ -1,10 +1,10 @@
<?php
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Fixture;
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Fixture;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Source\FirstAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Source\SecondAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Source\ThirdAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Source\FirstAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Source\SecondAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Source\ThirdAttribute;
#[FirstAttribute]
#[SecondAttribute]

View File

@ -1,9 +1,9 @@
<?php
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Fixture;
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Fixture;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Source\FirstAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Source\SecondAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Source\FirstAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Source\SecondAttribute;
#[SecondAttribute]
#[FirstAttribute]
@ -15,10 +15,10 @@ class Someclass
-----
<?php
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Fixture;
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Fixture;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Source\FirstAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Source\SecondAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Source\FirstAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Source\SecondAttribute;
#[FirstAttribute]
#[SecondAttribute]

View File

@ -2,7 +2,7 @@
declare(strict_types=1);
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector;
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder;
use Iterator;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;

View File

@ -2,7 +2,7 @@
declare(strict_types=1);
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Source;
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Source;
#[\Attribute]
final class FirstAttribute

View File

@ -2,7 +2,7 @@
declare(strict_types=1);
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Source;
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Source;
#[\Attribute]
final class SecondAttribute

View File

@ -2,7 +2,7 @@
declare(strict_types=1);
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Source;
namespace Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Source;
#[\Attribute]
final class ThirdAttribute

View File

@ -4,8 +4,8 @@ declare(strict_types=1);
use Rector\CodingStyle\Rector\ClassMethod\OrderAttributesRector;
use Rector\Config\RectorConfig;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Source\FirstAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\Source\SecondAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Source\FirstAttribute;
use Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\Source\SecondAttribute;
return static function (RectorConfig $rectorConfig): void {
$rectorConfig

View File

@ -20,14 +20,16 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
use Webmozart\Assert\Assert;
/**
* @see \Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\OrderAttributesRectorTest
* @see \Rector\Tests\CodingStyle\Rector\ClassMethod\OrderAttributesRector\SpecificOrder\OrderAttributesRectorTest
*/
final class OrderAttributesRector extends AbstractRector implements ConfigurableRectorInterface
{
public const ALPHABETICALLY = 'alphabetically';
/**
* @var array<string, int>
* @var array<string, int>|array<string>
*/
private array $attributesOrderByName = [];
private array $configuration = [];
public function getRuleDefinition(): RuleDefinition
{
@ -40,7 +42,7 @@ class Someclass
{
}
CODE_SAMPLE
,
,
<<<'CODE_SAMPLE'
#[First]
#[Second]
@ -48,9 +50,28 @@ class Someclass
{
}
CODE_SAMPLE
,
,
['First', 'Second'],
),
new ConfiguredCodeSample(
<<<'CODE_SAMPLE'
#[BAttribute]
#[AAttribute]
class Someclass
{
}
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
#[AAttribute]
#[BAttribute]
class Someclass
{
}
CODE_SAMPLE
,
[self::ALPHABETICALLY],
),
]);
}
@ -80,17 +101,11 @@ CODE_SAMPLE
}
$originalAttrGroups = $node->attrGroups;
$currentAttrGroups = $originalAttrGroups;
usort($currentAttrGroups, function (
AttributeGroup $firstAttributeGroup,
AttributeGroup $secondAttributeGroup,
): int {
$firstAttributePosition = $this->resolveAttributeGroupPosition($firstAttributeGroup);
$secondAttributePosition = $this->resolveAttributeGroupPosition($secondAttributeGroup);
return $firstAttributePosition <=> $secondAttributePosition;
});
if ($this->isAlphabetically($this->configuration)) {
$currentAttrGroups = $this->sortAlphabetically($originalAttrGroups);
} else {
$currentAttrGroups = $this->sortBySpecificOrder($originalAttrGroups);
}
if ($currentAttrGroups === $originalAttrGroups) {
return null;
@ -103,18 +118,65 @@ CODE_SAMPLE
/**
* @param mixed[] $configuration
*/
public function configure(array $configuration): void
public function configure(array $configuration = [self::ALPHABETICALLY]): void
{
Assert::allString($configuration);
Assert::minCount($configuration, 1);
$this->attributesOrderByName = array_flip($configuration);
if ($this->isAlphabetically($configuration)) {
$this->configuration = $configuration;
} else {
$this->configuration = array_flip($configuration);
}
}
/**
* @param array<AttributeGroup> $originalAttrGroups
* @return array<AttributeGroup>
*/
private function sortAlphabetically(array $originalAttrGroups): array
{
usort($originalAttrGroups, function (
AttributeGroup $firstAttributeGroup,
AttributeGroup $secondAttributeGroup,
): int {
$currentNamespace = $this->getName($firstAttributeGroup->attrs[0]->name);
$nextNamespace = $this->getName($secondAttributeGroup->attrs[0]->name);
return strcmp($currentNamespace, $nextNamespace);
});
return $originalAttrGroups;
}
/**
* @param array<AttributeGroup> $originalAttrGroups
* @return array<AttributeGroup>
*/
private function sortBySpecificOrder(array $originalAttrGroups): array
{
usort($originalAttrGroups, function (
AttributeGroup $firstAttributeGroup,
AttributeGroup $secondAttributeGroup,
): int {
$firstAttributePosition = $this->resolveAttributeGroupPosition($firstAttributeGroup);
$secondAttributePosition = $this->resolveAttributeGroupPosition($secondAttributeGroup);
return $firstAttributePosition <=> $secondAttributePosition;
});
return $originalAttrGroups;
}
private function resolveAttributeGroupPosition(AttributeGroup $attributeGroup): int
{
$attrName = $this->getName($attributeGroup->attrs[0]->name);
return (int)($this->configuration[$attrName] ?? count($this->configuration));
}
// 1000 makes the attribute last, as positioned attributes have a higher priority
return $this->attributesOrderByName[$attrName] ?? 1000;
/**
* @param array<string, int>|array<string> $configuration
*/
private function isAlphabetically(array $configuration): bool
{
return count($configuration) === 1 &&
$configuration[0] === self::ALPHABETICALLY;
}
}