Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
2b2fd22
DefineCacheTags
riasvdv Feb 3, 2026
dde24dd
Convert EVENT_REGISTER_SOURCES and EVENT_REGISTER_FIELD_LAYOUTS to La…
riasvdv Feb 3, 2026
684a6c6
Convert EVENT_REGISTER_PREVIEW_TARGETS to Laravel event
riasvdv Feb 3, 2026
cbc2736
Convert EVENT_REGISTER_ACTIONS to Laravel event
riasvdv Feb 3, 2026
3f2a44d
Convert EVENT_REGISTER_EXPORTERS to Laravel event
riasvdv Feb 3, 2026
2bbb5e4
Convert EVENT_RENDER to Laravel event
riasvdv Feb 3, 2026
4d2b622
Convert EVENT_DEFINE_KEYWORDS to Laravel event
riasvdv Feb 3, 2026
ee16f49
Convert DisplayedInIndex events to Laravel events
riasvdv Feb 3, 2026
22f5cf0
Convert Eagerloadable events to Laravel events
riasvdv Feb 3, 2026
f86a4b9
Convert EVENT_BEFORE_SAVE to Laravel event with backwards compatibility
riasvdv Feb 3, 2026
06b0827
Convert EVENT_AFTER_SAVE to Laravel event with backwards compatibility
riasvdv Feb 3, 2026
5b1615f
Convert EVENT_AFTER_PROPAGATE to Laravel event with backwards compati…
riasvdv Feb 3, 2026
95aea71
Convert remaining lifecycle events to Laravel events with backwards c…
riasvdv Feb 3, 2026
ed01fd4
Convert HasControlPanelUI events to Laravel events with backwards com…
riasvdv Feb 3, 2026
923fcb9
Convert HasRoutesAndUrls events to Laravel events with backwards comp…
riasvdv Feb 3, 2026
687d7cf
Convert Structurable events to Laravel events with backwards compatib…
riasvdv Feb 3, 2026
52c7ff0
Move deprecated authorization event constants to yii2-adapter
riasvdv Feb 3, 2026
608ebfc
Cleanup
riasvdv Feb 3, 2026
d7af878
Add deprecation notices
riasvdv Feb 3, 2026
2357b3f
fix-cs
riasvdv Feb 3, 2026
3e92087
Use legacy element in legacy tests
riasvdv Feb 3, 2026
d56340b
Fix event listeners
riasvdv Feb 3, 2026
85642f7
Fix test?
riasvdv Feb 3, 2026
fa3ef3e
Only assign once
riasvdv Feb 3, 2026
9ffc071
???
riasvdv Feb 3, 2026
1687ab6
Next
riasvdv Feb 3, 2026
af1eb65
Port User events
riasvdv Feb 3, 2026
70ba7c1
Asset events
riasvdv Feb 4, 2026
153325a
Make insert idempotent
riasvdv Feb 4, 2026
6a38e53
Entry events
riasvdv Feb 4, 2026
138ddfc
Replace last Yii event in src/
riasvdv Feb 4, 2026
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
113 changes: 24 additions & 89 deletions src/Asset/Elements/Asset.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@
use craft\errors\FsException;
use craft\errors\ImageTransformException;
use craft\errors\VolumeException;
use craft\events\AssetEvent;
use craft\events\DefineAssetUrlEvent;
use craft\events\GenerateTransformEvent;
use craft\gql\interfaces\elements\Asset as AssetInterface;
use craft\helpers\Assets;
use craft\helpers\Cp;
Expand All @@ -56,6 +53,11 @@
use craft\validators\AssetLocationValidator;
use craft\web\twig\AllowedInSandbox;
use CraftCms\Aliases\Aliases;
use CraftCms\Cms\Asset\Events\AfterGenerateTransform;
use CraftCms\Cms\Asset\Events\BeforeDefineAssetUrl;
use CraftCms\Cms\Asset\Events\BeforeGenerateTransform;
use CraftCms\Cms\Asset\Events\BeforeHandleFile;
use CraftCms\Cms\Asset\Events\DefineAssetUrl;
use CraftCms\Cms\Asset\Models\Asset as AssetModel;
use CraftCms\Cms\Asset\Validation\AssetRules;
use CraftCms\Cms\Cms;
Expand Down Expand Up @@ -128,40 +130,8 @@
* @property-read string|null $mimeType the file’s MIME type, if it can be determined
*/
#[Ruleset(AssetRules::class)]
final class Asset extends Element
class Asset extends Element
{
// Events
// -------------------------------------------------------------------------

/**
* @event AssetEvent The event that is triggered before an asset is uploaded to volume.
*/
public const string EVENT_BEFORE_HANDLE_FILE = 'beforeHandleFile';

/**
* @event GenerateTransformEvent The event that is triggered before a transform is generated for an asset.
*/
public const string EVENT_BEFORE_GENERATE_TRANSFORM = 'beforeGenerateTransform';

/**
* @event GenerateTransformEvent The event that is triggered after a transform is generated for an asset.
*/
public const string EVENT_AFTER_GENERATE_TRANSFORM = 'afterGenerateTransform';

/**
* @event DefineAssetUrlEvent The event that is triggered before defining the asset’s URL.
*
* @see getUrl()
*/
public const string EVENT_BEFORE_DEFINE_URL = 'beforeDefineUrl';

/**
* @event DefineAssetUrlEvent The event that is triggered when defining the asset’s URL.
*
* @see getUrl()
*/
public const string EVENT_DEFINE_URL = 'defineUrl';

// Location error codes
// -------------------------------------------------------------------------

Expand Down Expand Up @@ -2087,35 +2057,20 @@ public function getUrl(mixed $transform = null, ?bool $immediately = null): ?str

$transform ??= $this->_transform;

// Fire a 'beforeDefineUrl' event
if ($this->hasEventHandlers(self::EVENT_BEFORE_DEFINE_URL)) {
$event = new DefineAssetUrlEvent([
'transform' => $transform,
'asset' => $this,
]);
$this->trigger(self::EVENT_BEFORE_DEFINE_URL, $event);
$url = $event->url;
} else {
$url = null;
}
event($event = new BeforeDefineAssetUrl($this, $transform));

$url = $event->url;

// If DefineAssetUrlEvent::$url is set to null, only respect that if $handled is true
if ($url === null && ! ($event->handled ?? false)) {
// If BeforeDefineAssetUrl::$url is set to null, only respect that if $handled is true
if ($event->url === null && ! ($event->handled ?? false)) {
$url = $this->_url($transform, $immediately);
}

// Fire a 'defineUrl' event
if ($this->hasEventHandlers(self::EVENT_DEFINE_URL)) {
$event = new DefineAssetUrlEvent([
'url' => $url,
'transform' => $transform,
'asset' => $this,
]);
$this->trigger(self::EVENT_DEFINE_URL, $event);
// If DefineAssetUrlEvent::$url is set to null, only respect that if $handled is true
if ($event->url !== null || $event->handled) {
$url = $event->url;
}
event($event = new DefineAssetUrl($this, $transform, $url));

// If DefineAssetUrl::$url is set to null, only respect that if $handled is true
if ($event->url !== null || $event->handled) {
$url = $event->url;
}

return $url !== null ? Html::encodeSpaces($url) : $url;
Expand Down Expand Up @@ -2157,17 +2112,11 @@ private function _url(mixed $transform = null, ?bool $immediately = null): ?stri
$immediately = Cms::config()->generateTransformsBeforePageLoad;
}

// Fire a 'beforeGenerateTransform' event
if ($this->hasEventHandlers(self::EVENT_BEFORE_GENERATE_TRANSFORM)) {
$event = new GenerateTransformEvent([
'asset' => $this,
'transform' => $transform,
]);
$this->trigger(self::EVENT_BEFORE_GENERATE_TRANSFORM, $event);
// If a plugin set the url, we'll just use that.
if ($event->url !== null) {
return Html::encodeSpaces($event->url);
}
event($event = new BeforeGenerateTransform($this, $transform));

// If a plugin set the url, we'll just use that.
if ($event->url !== null) {
return Html::encodeSpaces($event->url);
}

$imageTransformer = $transform->getImageTransformer();
Expand All @@ -2183,15 +2132,7 @@ private function _url(mixed $transform = null, ?bool $immediately = null): ?stri
return null;
}

// Fire an 'afterGenerateTransform' event
if ($this->hasEventHandlers(self::EVENT_AFTER_GENERATE_TRANSFORM)) {
$event = new GenerateTransformEvent([
'asset' => $this,
'transform' => $transform,
'url' => $url,
]);
$this->trigger(self::EVENT_AFTER_GENERATE_TRANSFORM, $event);
}
event(new AfterGenerateTransform($this, $transform, $url));

return $url;
}
Expand Down Expand Up @@ -3120,14 +3061,8 @@ public function beforeSave(bool $isNew): bool
}

// Fire a 'beforeHandleFile' event if we're going to be doing any file operations in afterSave()
if (
(isset($this->newLocation) || isset($this->tempFilePath)) &&
$this->hasEventHandlers(self::EVENT_BEFORE_HANDLE_FILE)
) {
$this->trigger(self::EVENT_BEFORE_HANDLE_FILE, new AssetEvent([
'asset' => $this,
'isNew' => ! $this->id,
]));
if (isset($this->newLocation) || isset($this->tempFilePath)) {
event(new BeforeHandleFile($this, isNew: ! $this->id));
}

// Set the kind based on filename
Expand Down
20 changes: 20 additions & 0 deletions src/Asset/Events/AfterGenerateTransform.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace CraftCms\Cms\Asset\Events;

use craft\models\ImageTransform;
use CraftCms\Cms\Asset\Elements\Asset;

/**
* @event AfterGenerateTransform The event that is triggered after a transform is generated for an asset.
*/
final readonly class AfterGenerateTransform
{
public function __construct(
public Asset $asset,
public ImageTransform|string|array|null $transform,
public string $url,
) {}
}
25 changes: 25 additions & 0 deletions src/Asset/Events/BeforeDefineAssetUrl.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace CraftCms\Cms\Asset\Events;

use craft\models\ImageTransform;
use CraftCms\Cms\Asset\Elements\Asset;
use CraftCms\Cms\Element\Events\BeforeDefineUrl;

/**
* @event BeforeDefineAssetUrl The event that is triggered before defining the asset’s URL.
*
* @see getUrl()
*/
final class BeforeDefineAssetUrl extends BeforeDefineUrl
{
public function __construct(
public Asset $asset,
public ImageTransform|string|array|null $transform,
public ?string $url = null,
) {
parent::__construct($asset, $url);
}
}
20 changes: 20 additions & 0 deletions src/Asset/Events/BeforeGenerateTransform.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace CraftCms\Cms\Asset\Events;

use craft\models\ImageTransform;
use CraftCms\Cms\Asset\Elements\Asset;

/**
* @event BeforeGenerateTransform The event that is triggered before a transform is generated for an asset.
*/
final class BeforeGenerateTransform
{
public function __construct(
public Asset $asset,
public ImageTransform|string|array|null $transform,
public ?string $url = null,
) {}
}
18 changes: 18 additions & 0 deletions src/Asset/Events/BeforeHandleFile.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace CraftCms\Cms\Asset\Events;

use CraftCms\Cms\Asset\Elements\Asset;

/**
* @event BeforeHandleFile The event that is triggered before an asset is uploaded to volume.
*/
final class BeforeHandleFile
{
public function __construct(
public Asset $asset,
public bool $isNew,
) {}
}
25 changes: 25 additions & 0 deletions src/Asset/Events/DefineAssetUrl.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace CraftCms\Cms\Asset\Events;

use craft\models\ImageTransform;
use CraftCms\Cms\Asset\Elements\Asset;
use CraftCms\Cms\Element\Events\DefineUrl;

/**
* @event DefineAssetUrl The event that is triggered when defining the asset’s URL.
*
* @see getUrl()
*/
final class DefineAssetUrl extends DefineUrl
{
public function __construct(
public Asset $asset,
public ImageTransform|string|array|null $transform,
public ?string $url = null,
) {
parent::__construct($asset, $url);
}
}
46 changes: 46 additions & 0 deletions src/Cp/Events/RegisterCpNavItems.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

namespace CraftCms\Cms\Cp\Events;

/**
* @event RegisterCpNavItems The event that is triggered when registering control panel nav items.
*
* ```php
* use CraftCms\Cms\Cp\Events\RegisterCpNavItems;
* use Illuminate\Support\Facades\Event;
*
* Event::listen(
* function(RegisterCpNavItems $e) {
* $e->navItems[] = [
* 'label' => 'Item Label',
* 'url' => 'my-module',
* 'icon' => '/path/to/icon.svg',
* ];
* }
* );
* ```
*
* [[RegisterCpNavItems::$navItems]] is an array whose values are sub-arrays that define the nav items. Each sub-array can have the following keys:
*
* - `label` – The item’s label.
* - `url` – The URL or path of the control panel page the item should link to.
* - `icon` – The path to the SVG icon that should be used for the item.
* - `badgeCount` _(optional)_ – The badge count number that should be displayed next to the label.
* - `external` _(optional)_ – Set to `true` if the item links to an external URL.
* - `id` _(optional)_ – The ID of the `<li>` element. If not specified, it will default to `nav-`.
* - `subnav` _(optional)_ – A nested array of sub-navigation items that should be displayed if the main item is selected.
*
* The keys of the array should define the items’ IDs, and the values should be nested arrays with `label` and `url` keys, and optionally
* `badgeCount` and `external` keys.
*
* If a subnav is defined, subpages can specify which subnav item should be selected by defining a `selectedSubnavItem` variable that is set to
* the selected item’s ID (its key in the `subnav` array).
*/
final class RegisterCpNavItems
{
public function __construct(
public array $navItems,
) {}
}
11 changes: 4 additions & 7 deletions src/Cp/Navigation.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Craft;
use craft\helpers\UrlHelper;
use CraftCms\Cms\Config\GeneralConfig;
use CraftCms\Cms\Cp\Events\RegisterCpNavItems;
use CraftCms\Cms\Edition;
use CraftCms\Cms\Plugin\Plugins;
use CraftCms\Cms\Support\Facades\Sections;
Expand Down Expand Up @@ -162,13 +163,9 @@ public function getItems(): array
];
}

// Fire a 'registerCpNavItems' event
// @TODO Bring this back
// if ($this->hasEventHandlers(self::EVENT_REGISTER_CP_NAV_ITEMS)) {
// $event = new RegisterCpNavItemsEvent(['navItems' => $navItems]);
// $this->trigger(self::EVENT_REGISTER_CP_NAV_ITEMS, $event);
// $navItems = $event->navItems;
// }
event($event = new RegisterCpNavItems($navItems));

$navItems = $event->navItems;

// Figure out which item is selected, and normalize the items
$path = $this->request->getPathInfo();
Expand Down
23 changes: 3 additions & 20 deletions src/Element/Concerns/Cacheable.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace CraftCms\Cms\Element\Concerns;

use craft\events\DefineValueEvent;
use CraftCms\Cms\Element\Events\DefineCacheTags;

/**
* Cacheable provides cache tag management for elements.
Expand All @@ -16,15 +16,6 @@
*/
trait Cacheable
{
/**
* @event DefineValueEvent The event that is triggered when defining the cache tags that should be cleared when
* this element is saved.
*
* @see getCacheTags()
* @since 4.1.0
*/
public const EVENT_DEFINE_CACHE_TAGS = 'defineCacheTags';

/**
* Returns the cache tags that should be cleared when this element is saved.
*
Expand All @@ -34,17 +25,9 @@ trait Cacheable
*/
public function getCacheTags(): array
{
$cacheTags = $this->cacheTags();

// Fire a 'defineCacheTags' event
if ($this->hasEventHandlers(self::EVENT_DEFINE_CACHE_TAGS)) {
$event = new DefineValueEvent(['value' => $cacheTags]);
$this->trigger(self::EVENT_DEFINE_CACHE_TAGS, $event);

return $event->value;
}
event($event = new DefineCacheTags($this, $this->cacheTags()));

return $cacheTags;
return $event->tags;
}

/**
Expand Down
Loading
Loading