Skip to content

Commit f005a58

Browse files
Tigrovvjik
andauthored
Add Events (#428)
Co-authored-by: Sergei Predvoditelev <sergei@predvoditelev.ru>
1 parent 848eca8 commit f005a58

38 files changed

Lines changed: 1193 additions & 63 deletions

composer-require-checker.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
{
22
"symbol-whitelist": [
3+
"Psr\\EventDispatcher\\EventDispatcherInterface",
4+
"Psr\\EventDispatcher\\StoppableEventInterface",
35
"Psr\\Http\\Message\\ResponseInterface",
46
"Psr\\Http\\Message\\ServerRequestInterface",
57
"Psr\\Http\\Server\\MiddlewareInterface",
68
"Psr\\Http\\Server\\RequestHandlerInterface",
79
"Yiisoft\\Arrays\\ArrayableTrait",
10+
"Yiisoft\\EventDispatcher\\Dispatcher\\Dispatcher",
11+
"Yiisoft\\EventDispatcher\\Provider\\ListenerCollection",
12+
"Yiisoft\\EventDispatcher\\Provider\\Provider",
813
"Yiisoft\\Factory\\Factory"
914
]
1015
}

composer.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
"yiisoft/cache": "^3.0",
4545
"yiisoft/db-sqlite": "dev-master",
4646
"yiisoft/di": "^1.3",
47+
"yiisoft/event-dispatcher": "^1.1",
4748
"yiisoft/factory": "^1.3",
4849
"yiisoft/middleware-dispatcher": "^5.2"
4950
},
@@ -55,6 +56,7 @@
5556
"yiisoft/db-mssql": "For MSSQL database support",
5657
"yiisoft/db-oracle": "For Oracle database support",
5758
"yiisoft/factory": "For factory support",
59+
"yiisoft/event-dispatcher": "For events support",
5860
"yiisoft/middleware-dispatcher": "For middleware support"
5961
},
6062
"autoload": {

src/ActiveQuery.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -824,7 +824,7 @@ public function findByPk(array|float|int|string $values): array|ActiveRecordInte
824824
}
825825
}
826826

827-
return $this->setWhere(array_combine($primaryKey, $values))->one();
827+
return (clone $this)->andWhere(array_combine($primaryKey, $values))->one();
828828
}
829829

830830
public function on(array|string|null $value): static

src/Event/AbstractEvent.php

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yiisoft\ActiveRecord\Event;
6+
7+
use Psr\EventDispatcher\StoppableEventInterface;
8+
use Yiisoft\ActiveRecord\ActiveRecordInterface;
9+
10+
/**
11+
* Base class for events in Active Record models.
12+
*/
13+
abstract class AbstractEvent implements StoppableEventInterface
14+
{
15+
/** @var bool Whether the default action of the event should be prevented. */
16+
private bool $isDefaultPrevented = false;
17+
/** @var bool Whether the propagation of the event should be stopped. */
18+
private bool $isPropagationStopped = false;
19+
/** @var mixed The return value if the default action is prevented. */
20+
private mixed $returnValue = null;
21+
22+
/**
23+
* @param ActiveRecordInterface $model The target model associated with this event.
24+
*/
25+
public function __construct(
26+
public readonly ActiveRecordInterface $model,
27+
) {
28+
}
29+
30+
/**
31+
* Returns the value that will be returned by the method that triggered this event
32+
* if the {@see isDefaultPrevented() default action is prevented}.
33+
*/
34+
public function getReturnValue(): mixed
35+
{
36+
return $this->returnValue;
37+
}
38+
39+
/**
40+
* Checks if the default action associated with this event has been prevented.
41+
*/
42+
public function isDefaultPrevented(): bool
43+
{
44+
return $this->isDefaultPrevented;
45+
}
46+
47+
public function isPropagationStopped(): bool
48+
{
49+
return $this->isPropagationStopped;
50+
}
51+
52+
/**
53+
* Prevents the default action associated with this event from being executed.
54+
*
55+
* @see returnValue()
56+
*/
57+
public function preventDefault(): void
58+
{
59+
$this->isDefaultPrevented = true;
60+
}
61+
62+
/**
63+
* Sets the return value which will be returned by the method that triggered this event
64+
* if the {@see isDefaultPrevented() default action is prevented}.
65+
*
66+
* @see preventDefault()
67+
*/
68+
public function returnValue(mixed $returnValue): void
69+
{
70+
$this->returnValue = $returnValue;
71+
}
72+
73+
/**
74+
* Stops the propagation of the event to further listeners.
75+
* No further listeners will be notified after this method is called.
76+
*/
77+
public function stopPropagation(): void
78+
{
79+
$this->isPropagationStopped = true;
80+
}
81+
}

src/Event/AfterCreateQuery.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yiisoft\ActiveRecord\Event;
6+
7+
use Yiisoft\ActiveRecord\ActiveQueryInterface;
8+
use Yiisoft\ActiveRecord\ActiveRecordInterface;
9+
10+
/**
11+
* Event triggered after the query has been created for the {@see ActiveRecordInterface} model.
12+
*
13+
* @see ActiveRecordInterface::query()
14+
*/
15+
final class AfterCreateQuery extends AbstractEvent
16+
{
17+
public function __construct(
18+
ActiveRecordInterface $model,
19+
public readonly ActiveQueryInterface $query,
20+
) {
21+
parent::__construct($model);
22+
}
23+
}

src/Event/AfterDelete.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yiisoft\ActiveRecord\Event;
6+
7+
use Yiisoft\ActiveRecord\ActiveRecordInterface;
8+
9+
/**
10+
* Event triggered after the record has been deleted from the database.
11+
*
12+
* @see ActiveRecordInterface::delete()
13+
*/
14+
final class AfterDelete extends AbstractEvent
15+
{
16+
/**
17+
* @param ActiveRecordInterface $model The model that was deleted.
18+
* @param int $count Number of deleted rows.
19+
*/
20+
public function __construct(ActiveRecordInterface $model, public int &$count)
21+
{
22+
parent::__construct($model);
23+
}
24+
}

src/Event/AfterInsert.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yiisoft\ActiveRecord\Event;
6+
7+
use Yiisoft\ActiveRecord\ActiveRecordInterface;
8+
9+
/**
10+
* Event triggered after the record has been inserted into the database.
11+
*
12+
* @see ActiveRecordInterface::insert
13+
*/
14+
final class AfterInsert extends AbstractEvent
15+
{
16+
/**
17+
* @param ActiveRecordInterface $model The model that has been inserted.
18+
* @param bool $isSuccessful Whether the insert operation is successful.
19+
*/
20+
public function __construct(ActiveRecordInterface $model, public bool &$isSuccessful)
21+
{
22+
parent::__construct($model);
23+
}
24+
}

src/Event/AfterPopulate.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yiisoft\ActiveRecord\Event;
6+
7+
use Yiisoft\ActiveRecord\ActiveRecordInterface;
8+
9+
/**
10+
* Event triggered after the model has been populated with data.
11+
*
12+
* @see ActiveRecordInterface::populate()
13+
*/
14+
final class AfterPopulate extends AbstractEvent
15+
{
16+
/**
17+
* @param ActiveRecordInterface $model The model that has been populated.
18+
* @param array $data The data used to populate the model.
19+
*/
20+
public function __construct(ActiveRecordInterface $model, public readonly array $data)
21+
{
22+
parent::__construct($model);
23+
}
24+
}

src/Event/AfterSave.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yiisoft\ActiveRecord\Event;
6+
7+
use Yiisoft\ActiveRecord\ActiveRecordInterface;
8+
9+
/**
10+
* Event triggered after the model has been saved to the database.
11+
*
12+
* @see ActiveRecordInterface::afterSave()
13+
*/
14+
final class AfterSave extends AbstractEvent
15+
{
16+
/**
17+
* @param ActiveRecordInterface $model The model that was saved.
18+
* @param bool $isSuccessful Whether the save operation was successful.
19+
*/
20+
public function __construct(ActiveRecordInterface $model, public bool &$isSuccessful)
21+
{
22+
parent::__construct($model);
23+
}
24+
}

src/Event/AfterUpdate.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yiisoft\ActiveRecord\Event;
6+
7+
use Yiisoft\ActiveRecord\ActiveRecordInterface;
8+
9+
/**
10+
* Event triggered after the record has been updated in the database.
11+
*
12+
* @see ActiveRecordInterface::update()
13+
*/
14+
final class AfterUpdate extends AbstractEvent
15+
{
16+
/**
17+
* @param ActiveRecordInterface $model The model that was updated.
18+
* @param int $count The number of rows that were updated.
19+
*/
20+
public function __construct(ActiveRecordInterface $model, public int &$count)
21+
{
22+
parent::__construct($model);
23+
}
24+
}

0 commit comments

Comments
 (0)