Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Rector\Symfony\Tests\CodeQuality\Rector\Class_\EventListenerToEventSubscriberRector\Fixture;

use Symfony\Component\Workflow\Attribute\AsAnnounceListener;

class WorkflowAnnounceListener
{
#[AsAnnounceListener(workflow: 'order')]
public function onAnnounce()
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Rector\Symfony\Tests\CodeQuality\Rector\Class_\EventListenerToEventSubscriberRector\Fixture;

use Symfony\Component\Workflow\Attribute\AsCompletedListener;

class WorkflowCompletedListener
{
#[AsCompletedListener(workflow: 'order')]
public function onCompleted()
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Rector\Symfony\Tests\CodeQuality\Rector\Class_\EventListenerToEventSubscriberRector\Fixture;

use Symfony\Component\Workflow\Attribute\AsEnterListener;

class WorkflowEnterListener
{
#[AsEnterListener(workflow: 'order')]
public function onEnter()
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Rector\Symfony\Tests\CodeQuality\Rector\Class_\EventListenerToEventSubscriberRector\Fixture;

use Symfony\Component\Workflow\Attribute\AsEnteredListener;

class WorkflowEnteredListener
{
#[AsEnteredListener(workflow: 'order')]
public function onEntered()
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Rector\Symfony\Tests\CodeQuality\Rector\Class_\EventListenerToEventSubscriberRector\Fixture;

use Symfony\Component\Workflow\Attribute\AsGuardListener;

#[AsGuardListener(workflow: 'order')]
class OrderGuardListener
{
public function __invoke()
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Rector\Symfony\Tests\CodeQuality\Rector\Class_\EventListenerToEventSubscriberRector\Fixture;

use Symfony\Component\Workflow\Attribute\AsLeaveListener;

class WorkflowLeaveListener
{
#[AsLeaveListener(workflow: 'order')]
public function onLeave()
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace Rector\Symfony\Tests\CodeQuality\Rector\Class_\EventListenerToEventSubscriberRector\Fixture;

use Symfony\Component\Workflow\Attribute\AsTransitionListener;

class TransactionWorkflowListener
{
#[AsTransitionListener(workflow: 'transaction', transition: 'pay')]
public function onPay()
{
}

#[AsTransitionListener(workflow: 'transaction', transition: 'complete')]
public function onComplete()
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,21 @@ final class EventListenerToEventSubscriberRector extends AbstractRector
*/
private const string LISTENER_MATCH_REGEX = '#^(.*?)(Listener)?$#';

/**
* @var string[]
*/
private const array LISTENER_ATTRIBUTES = [
SymfonyAttribute::AS_EVENT_LISTENER,
// Symfony Workflow attributes (Symfony 7.1+)
SymfonyAttribute::AS_ANNOUNCE_LISTENER,
SymfonyAttribute::AS_COMPLETED_LISTENER,
SymfonyAttribute::AS_ENTER_LISTENER,
SymfonyAttribute::AS_ENTERED_LISTENER,
SymfonyAttribute::AS_GUARD_LISTENER,
SymfonyAttribute::AS_LEAVE_LISTENER,
SymfonyAttribute::AS_TRANSITION_LISTENER,
];

/**
* @var EventNameToClassAndConstant[]
*/
Expand Down Expand Up @@ -168,20 +183,25 @@ private function changeListenerToSubscriberWithMethods(Class_ $class, array $eve

/**
* @see https://symfony.com/doc/current/event_dispatcher.html#event-dispatcher_event-listener-attributes
* @see https://symfony.com/doc/current/workflow.html
*/
private function hasAsListenerAttribute(Class_ $class): bool
{
if ($this->phpAttributeAnalyzer->hasPhpAttribute($class, SymfonyAttribute::AS_EVENT_LISTENER)) {
return true;
foreach (self::LISTENER_ATTRIBUTES as $attribute) {
if ($this->phpAttributeAnalyzer->hasPhpAttribute($class, $attribute)) {
return true;
}
}

foreach ($class->getMethods() as $classMethod) {
if (! $classMethod->isPublic()) {
continue;
}

if ($this->phpAttributeAnalyzer->hasPhpAttribute($classMethod, SymfonyAttribute::AS_EVENT_LISTENER)) {
return true;
foreach (self::LISTENER_ATTRIBUTES as $attribute) {
if ($this->phpAttributeAnalyzer->hasPhpAttribute($classMethod, $attribute)) {
return true;
}
}
}

Expand Down
15 changes: 15 additions & 0 deletions src/Enum/SymfonyAttribute.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,21 @@ final class SymfonyAttribute

public const string AS_EVENT_LISTENER = 'Symfony\Component\EventDispatcher\Attribute\AsEventListener';

// Workflow listener attributes (Symfony 7.1+)
public const string AS_ANNOUNCE_LISTENER = 'Symfony\Component\Workflow\Attribute\AsAnnounceListener';

public const string AS_COMPLETED_LISTENER = 'Symfony\Component\Workflow\Attribute\AsCompletedListener';

public const string AS_ENTER_LISTENER = 'Symfony\Component\Workflow\Attribute\AsEnterListener';

public const string AS_ENTERED_LISTENER = 'Symfony\Component\Workflow\Attribute\AsEnteredListener';

public const string AS_GUARD_LISTENER = 'Symfony\Component\Workflow\Attribute\AsGuardListener';

public const string AS_LEAVE_LISTENER = 'Symfony\Component\Workflow\Attribute\AsLeaveListener';

public const string AS_TRANSITION_LISTENER = 'Symfony\Component\Workflow\Attribute\AsTransitionListener';

public const string ROUTE = 'Symfony\Component\Routing\Attribute\Route';

public const string IS_GRANTED = 'Symfony\Component\Security\Http\Attribute\IsGranted';
Expand Down