Skip to content

Commit

Permalink
feat(history): allow #[TagStamp] to be added to parent classes/inte…
Browse files Browse the repository at this point in the history
…rfaces
  • Loading branch information
kbond committed Nov 25, 2024
1 parent 005e050 commit 747bb44
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 43 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ add your own in one of two ways:

$bus->dispatch(new MyMessage(), [new TagStamp('tag-1'), new TagStamp('tag-2')])
```
2. Add the `TagStamp` as a class attribute to your message:
2. Add the `TagStamp` as a class attribute to your message (and parent class/interface):
```php
use Zenstruck\Messenger\Monitor\Stamp\TagStamp;

Expand All @@ -164,6 +164,8 @@ add your own in one of two ways:
{
}
```
> [!TIP]
> You can also add the `TagStamp` attribute to parent classes/interfaces.

#### `messenger:monitor:purge` Command

Expand Down
4 changes: 1 addition & 3 deletions src/EventListener/ReceiveMonitorStampListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,7 @@ private function isMonitoringDisabled(Envelope $envelope): bool
}
}

$stamp = $envelope->last(DisableMonitoringStamp::class) ?? DisableMonitoringStamp::getFor($messageClass);

if (!$stamp) {
if (!$stamp = DisableMonitoringStamp::firstFrom($envelope)) {
return false;
}

Expand Down
8 changes: 2 additions & 6 deletions src/History/Model/Tags.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,8 @@ static function(string $tag): array {
*/
private static function parseFrom(Envelope $envelope): \Traversable
{
foreach ((new \ReflectionClass($envelope->getMessage()))->getAttributes(TagStamp::class) as $attribute) {
yield $attribute->newInstance()->value;
}

foreach ($envelope->all(TagStamp::class) as $tag) {
yield $tag->value; // @phpstan-ignore-line
foreach (TagStamp::from($envelope) as $tag) {
yield $tag->value;
}
}
}
62 changes: 62 additions & 0 deletions src/Stamp/AttributeStamp.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

/*
* This file is part of the zenstruck/messenger-monitor-bundle package.
*
* (c) Kevin Bond <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Zenstruck\Messenger\Monitor\Stamp;

use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\Stamp\StampInterface;

/**
* @author Kevin Bond <[email protected]>
*/
abstract class AttributeStamp implements StampInterface
{
/**
* @internal
*
* @return static[]
*/
final public static function from(Envelope $envelope): iterable
{
foreach ($envelope->all(static::class) as $stamp) {
yield $stamp; // @phpstan-ignore generator.valueType
}

$original = $reflection = new \ReflectionClass($envelope->getMessage());

while (false !== $reflection) {

foreach ($reflection->getAttributes(static::class) as $attribute) {
yield $attribute->newInstance();
}

$reflection = $reflection->getParentClass();
}

foreach ($original->getInterfaces() as $refInterface) {
foreach ($refInterface->getAttributes(static::class) as $attribute) {
yield $attribute->newInstance();
}
}
}

/**
* @internal
*/
final public static function firstFrom(Envelope $envelope): ?static
{
foreach (self::from($envelope) as $stamp) {
return $stamp;
}

return null;
}
}
30 changes: 1 addition & 29 deletions src/Stamp/DisableMonitoringStamp.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,41 +11,13 @@

namespace Zenstruck\Messenger\Monitor\Stamp;

use Symfony\Component\Messenger\Stamp\StampInterface;

/**
* @author Kevin Bond <[email protected]>
*/
#[\Attribute(\Attribute::TARGET_CLASS)]
final class DisableMonitoringStamp implements StampInterface
final class DisableMonitoringStamp extends AttributeStamp
{
public function __construct(public readonly bool $onlyWhenNoHandler = false)
{
}

/**
* @internal
*
* @param class-string $class
*/
public static function getFor(string $class): ?self
{
$original = $reflection = new \ReflectionClass($class);

while (false !== $reflection) {
if ($attributes = $reflection->getAttributes(self::class)) {
return $attributes[0]->newInstance();
}

$reflection = $reflection->getParentClass();
}

foreach ($original->getInterfaces() as $refInterface) {
if ($attributes = $refInterface->getAttributes(self::class)) {
return $attributes[0]->newInstance();
}
}

return null;
}
}
3 changes: 1 addition & 2 deletions src/Stamp/TagStamp.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,14 @@

namespace Zenstruck\Messenger\Monitor\Stamp;

use Symfony\Component\Messenger\Stamp\StampInterface;
use Symfony\Component\Scheduler\Messenger\ScheduledStamp;
use Zenstruck\Messenger\Monitor\Schedule\TaskInfo;

/**
* @author Kevin Bond <[email protected]>
*/
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::IS_REPEATABLE)]
final class TagStamp implements StampInterface, \Stringable
final class TagStamp extends AttributeStamp implements \Stringable
{
public function __construct(
public readonly string $value,
Expand Down
14 changes: 12 additions & 2 deletions tests/Unit/History/Model/TagsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public function create_from_envelope(): void
new TagStamp('qux'),
]);

$this->assertSame(['from', 'attribute', 'bar', 'foo', 'baz', 'qux'], (new Tags($envelope))->all());
$this->assertSame(['foo', 'bar', 'baz', 'qux', 'from', 'attribute', 'abstract', 'interface'], (new Tags($envelope))->all());
}

/**
Expand All @@ -104,9 +104,19 @@ public function expand(): void
}
}

#[TagStamp('interface')]
interface InterfaceMessage
{
}

#[TagStamp('abstract')]
abstract class AbstractMessage implements InterfaceMessage
{
}

#[TagStamp('from')]
#[TagStamp('attribute')]
#[TagStamp('bar')]
class TestMessage
class TestMessage extends AbstractMessage
{
}

0 comments on commit 747bb44

Please sign in to comment.