Skip to content

Commit 3763191

Browse files
authored
Merge pull request #68 from phenixphp/release/0.7.0
Release v0.7.0
2 parents 9c43d85 + 190cda1 commit 3763191

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1547
-49
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
# Release Notes for 0.7.x
11+
12+
## [v0.7.0 (2025-09-26)](https://github.com/phenixphp/framework/compare/0.6.0...0.7.0)
13+
14+
### Added
15+
16+
- Event system. ([#67](https://github.com/phenixphp/framework/pull/67))
17+
1018
# Release Notes for 0.6.x
1119

1220
## [v0.6.0 (2025-08-22)](https://github.com/phenixphp/framework/compare/0.5.2...0.6.0)

src/App.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
use Amp\Socket;
1313
use League\Container\Container;
1414
use League\Uri\Uri;
15+
use Mockery\LegacyMockInterface;
16+
use Mockery\MockInterface;
1517
use Monolog\Logger;
1618
use Phenix\Console\Phenix;
1719
use Phenix\Contracts\App as AppContract;
@@ -105,6 +107,11 @@ public static function make(string $key): object
105107
return self::$container->get($key);
106108
}
107109

110+
public static function fake(string $key, LegacyMockInterface|MockInterface $concrete): void
111+
{
112+
self::$container->extend($key)->setConcrete($concrete);
113+
}
114+
108115
public static function path(): string
109116
{
110117
return self::$path;

src/Console/Commands/MakeModel.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int
102102

103103
File::put($filePath, $stub);
104104

105-
$output->writeln(["<info>{$this->commonName()} successfully generated!</info>", self::EMPTY_LINE]);
105+
$outputPath = str_replace(base_path(), '', $filePath);
106+
107+
$output->writeln(["<info>{$this->commonName()} [{$outputPath}] successfully generated!</info>", self::EMPTY_LINE]);
106108

107109
return parent::SUCCESS;
108110
}

src/Console/Maker.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int
4848

4949
File::put($filePath, $stub);
5050

51-
$output->writeln(["<info>{$this->commonName()} successfully generated!</info>", self::EMPTY_LINE]);
51+
$outputPath = str_replace(base_path(), '', $filePath);
52+
53+
$output->writeln(["<info>{$this->commonName()} [{$outputPath}] successfully generated!</info>", self::EMPTY_LINE]);
5254

5355
return Command::SUCCESS;
5456
}

src/Database/Console/MakeSeeder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ protected function configure(): void
3636

3737
protected function outputDirectory(): string
3838
{
39-
return 'database' . DIRECTORY_SEPARATOR . 'seeds';
39+
return 'database' . DIRECTORY_SEPARATOR . 'seeders';
4040
}
4141

4242
protected function stub(): string

src/Events/AbstractEvent.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Phenix\Events;
6+
7+
use Phenix\Events\Contracts\Event as EventContract;
8+
9+
abstract class AbstractEvent implements EventContract
10+
{
11+
protected mixed $payload = null;
12+
13+
protected bool $propagationStopped = false;
14+
15+
public function getName(): string
16+
{
17+
return static::class;
18+
}
19+
20+
public function getPayload(): mixed
21+
{
22+
return $this->payload;
23+
}
24+
25+
public function isPropagationStopped(): bool
26+
{
27+
return $this->propagationStopped;
28+
}
29+
30+
public function stopPropagation(): void
31+
{
32+
$this->propagationStopped = true;
33+
}
34+
}

src/Events/AbstractListener.php

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Phenix\Events;
6+
7+
use Closure;
8+
use Phenix\Events\Contracts\Event;
9+
use Phenix\Events\Contracts\EventListener as EventListenerContract;
10+
11+
abstract class AbstractListener implements EventListenerContract
12+
{
13+
protected int $priority = 0;
14+
15+
protected bool $once = false;
16+
17+
abstract public function handle(Event $event): mixed;
18+
19+
public function setPriority(int $priority): self
20+
{
21+
$this->priority = $this->normalizePriority($priority);
22+
23+
return $this;
24+
}
25+
26+
public function getPriority(): int
27+
{
28+
return $this->priority;
29+
}
30+
31+
public function shouldHandle(Event $event): bool
32+
{
33+
return true;
34+
}
35+
36+
public function isOnce(): bool
37+
{
38+
return $this->once;
39+
}
40+
41+
public function setOnce(bool $once = true): self
42+
{
43+
$this->once = $once;
44+
45+
return $this;
46+
}
47+
48+
public function getHandler(): Closure|static|string
49+
{
50+
return $this;
51+
}
52+
53+
protected function normalizePriority(int $priority): int
54+
{
55+
return max(0, min($priority, 100));
56+
}
57+
}

src/Events/Console/MakeEvent.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Phenix\Events\Console;
6+
7+
use Phenix\Console\Maker;
8+
use Symfony\Component\Console\Attribute\AsCommand;
9+
use Symfony\Component\Console\Input\InputArgument;
10+
use Symfony\Component\Console\Input\InputOption;
11+
12+
#[AsCommand(
13+
name: 'make:event',
14+
description: 'Create a new event class'
15+
)]
16+
class MakeEvent extends Maker
17+
{
18+
protected function configure(): void
19+
{
20+
$this->addArgument('name', InputArgument::REQUIRED, 'The name of the event');
21+
22+
$this->addOption('force', 'f', InputOption::VALUE_NONE, 'Force to create event');
23+
}
24+
25+
protected function outputDirectory(): string
26+
{
27+
return 'app' . DIRECTORY_SEPARATOR . 'Events';
28+
}
29+
30+
protected function commonName(): string
31+
{
32+
return 'Event';
33+
}
34+
35+
protected function stub(): string
36+
{
37+
return 'event.stub';
38+
}
39+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Phenix\Events\Console;
6+
7+
use Phenix\Console\Maker;
8+
use Symfony\Component\Console\Attribute\AsCommand;
9+
use Symfony\Component\Console\Input\InputArgument;
10+
use Symfony\Component\Console\Input\InputOption;
11+
12+
#[AsCommand(
13+
name: 'make:listener',
14+
description: 'Create a new event listener class'
15+
)]
16+
class MakeListener extends Maker
17+
{
18+
protected function configure(): void
19+
{
20+
$this->addArgument('name', InputArgument::REQUIRED, 'The name of the listener');
21+
22+
$this->addOption('force', 'f', InputOption::VALUE_NONE, 'Force to create listener');
23+
}
24+
25+
protected function outputDirectory(): string
26+
{
27+
return 'app' . DIRECTORY_SEPARATOR . 'Listeners';
28+
}
29+
30+
protected function commonName(): string
31+
{
32+
return 'Event Listener';
33+
}
34+
35+
protected function stub(): string
36+
{
37+
return 'listener.stub';
38+
}
39+
}

src/Events/Contracts/Event.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Phenix\Events\Contracts;
6+
7+
interface Event
8+
{
9+
public function getName(): string;
10+
11+
public function getPayload(): mixed;
12+
13+
public function isPropagationStopped(): bool;
14+
15+
public function stopPropagation(): void;
16+
}

0 commit comments

Comments
 (0)