1
0
mirror of https://github.com/flarum/core.git synced 2025-08-13 20:04:24 +02:00

Compare commits

...

4 Commits

Author SHA1 Message Date
dependabot[bot]
5bf7a5ae53 chore(deps): bump nanoid from 3.3.7 to 3.3.8
Bumps [nanoid](https://github.com/ai/nanoid) from 3.3.7 to 3.3.8.
- [Release notes](https://github.com/ai/nanoid/releases)
- [Changelog](https://github.com/ai/nanoid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ai/nanoid/compare/3.3.7...3.3.8)

---
updated-dependencies:
- dependency-name: nanoid
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-16 21:02:08 +00:00
Sami Mazouz
9fe17b3c24 perf(mentions): only access related mentions if loaded 2024-12-13 13:06:36 +01:00
Sami Mazouz
4dce4d40a3 fix(regression): phpstan errors 2024-12-13 13:06:08 +01:00
Sami Mazouz
a81d13e26c fix: beta.1 early bugs 2024-12-12 21:27:57 +01:00
12 changed files with 89 additions and 30 deletions

View File

@@ -25,9 +25,13 @@ class FormatGroupMentions
public function __invoke(Renderer $renderer, mixed $context, string $xml): string
{
return Utils::replaceAttributes($xml, 'GROUPMENTION', function ($attributes) use ($context) {
$group = ($context instanceof AbstractModel && $context->isRelation('mentionsGroups'))
? $context->mentionsGroups->find($attributes['id']) // @phpstan-ignore-line
: Group::find($attributes['id']);
/** @var Group|null $group */
$group = match (true) {
$context instanceof AbstractModel && $context->isRelation('mentionsGroups') => $context->relationLoaded('mentionsGroups')
? $context->mentionsGroups->find($attributes['id']) // @phpstan-ignore-line
: $context->mentionsGroups()->find($attributes['id']), // @phpstan-ignore-line
default => Group::query()->find($attributes['id']),
};
if ($group) {
$attributes['groupname'] = $group->name_plural;

View File

@@ -31,9 +31,13 @@ class FormatPostMentions
public function __invoke(Renderer $renderer, mixed $context, string $xml): string
{
return Utils::replaceAttributes($xml, 'POSTMENTION', function ($attributes) use ($context) {
$post = ($context instanceof AbstractModel && $context->isRelation('mentionsPosts'))
? $context->mentionsPosts->find($attributes['id']) // @phpstan-ignore-line
: Post::find($attributes['id']);
/** @var Post|null $post */
$post = match (true) {
$context instanceof AbstractModel && $context->isRelation('mentionsPosts') => $context->relationLoaded('mentionsPosts')
? $context->mentionsPosts->find($attributes['id']) // @phpstan-ignore-line
: $context->mentionsPosts()->find($attributes['id']), // @phpstan-ignore-line
default => Post::query()->find($attributes['id']),
};
if ($post && $post->user) {
$attributes['displayname'] = $post->user->display_name;

View File

@@ -21,9 +21,12 @@ class FormatTagMentions
{
return Utils::replaceAttributes($xml, 'TAGMENTION', function ($attributes) use ($context) {
/** @var Tag|null $tag */
$tag = ($context instanceof AbstractModel && $context->isRelation('mentionsTags'))
? $context->mentionsTags->find($attributes['id']) // @phpstan-ignore-line
: Tag::query()->find($attributes['id']);
$tag = match (true) {
$context instanceof AbstractModel && $context->isRelation('mentionsTags') => $context->relationLoaded('mentionsTags')
? $context->mentionsTags->find($attributes['id']) // @phpstan-ignore-line
: $context->mentionsTags()->find($attributes['id']), // @phpstan-ignore-line
default => Tag::query()->find($attributes['id']),
};
if ($tag) {
$attributes['deleted'] = false;

View File

@@ -27,9 +27,13 @@ class FormatUserMentions
public function __invoke(Renderer $renderer, mixed $context, string $xml): string
{
return Utils::replaceAttributes($xml, 'USERMENTION', function ($attributes) use ($context) {
$user = ($context instanceof AbstractModel && $context->isRelation('mentionsUsers'))
? $context->mentionsUsers->find($attributes['id']) // @phpstan-ignore-line
: User::find($attributes['id']);
/** @var User|null $user */
$user = match (true) {
$context instanceof AbstractModel && $context->isRelation('mentionsUsers') => $context->relationLoaded('mentionsUsers')
? $context->mentionsUsers->find($attributes['id']) // @phpstan-ignore-line
: $context->mentionsUsers()->find($attributes['id']), // @phpstan-ignore-line
default => User::query()->find($attributes['id']),
};
$attributes['deleted'] = false;

View File

@@ -34,9 +34,13 @@ class UnparsePostMentions
protected function updatePostMentionTags(mixed $context, string $xml): string
{
return Utils::replaceAttributes($xml, 'POSTMENTION', function ($attributes) use ($context) {
$post = ($context instanceof AbstractModel && $context->isRelation('mentionsPosts'))
? $context->mentionsPosts->find($attributes['id']) // @phpstan-ignore-line
: Post::find($attributes['id']);
/** @var Post|null $post */
$post = match (true) {
$context instanceof AbstractModel && $context->isRelation('mentionsPosts') => $context->relationLoaded('mentionsPosts')
? $context->mentionsPosts->find($attributes['id']) // @phpstan-ignore-line
: $context->mentionsPosts()->find($attributes['id']), // @phpstan-ignore-line
default => Post::query()->find($attributes['id']),
};
if ($post && $post->user) {
$attributes['displayname'] = $post->user->display_name;

View File

@@ -29,9 +29,12 @@ class UnparseTagMentions
{
return Utils::replaceAttributes($xml, 'TAGMENTION', function (array $attributes) use ($context) {
/** @var Tag|null $tag */
$tag = ($context instanceof AbstractModel && $context->isRelation('mentionsTags'))
? $context->mentionsTags->find($attributes['id']) // @phpstan-ignore-line
: Tag::query()->find($attributes['id']);
$tag = match (true) {
$context instanceof AbstractModel && $context->isRelation('mentionsTags') => $context->relationLoaded('mentionsTags')
? $context->mentionsTags->find($attributes['id']) // @phpstan-ignore-line
: $context->mentionsTags()->find($attributes['id']), // @phpstan-ignore-line
default => Tag::query()->find($attributes['id']),
};
if ($tag) {
$attributes['tagname'] = $tag->name;

View File

@@ -34,9 +34,13 @@ class UnparseUserMentions
protected function updateUserMentionTags(mixed $context, string $xml): string
{
return Utils::replaceAttributes($xml, 'USERMENTION', function ($attributes) use ($context) {
$user = ($context instanceof AbstractModel && $context->isRelation('mentionsUsers'))
? $context->mentionsUsers->find($attributes['id']) // @phpstan-ignore-line
: User::find($attributes['id']);
/** @var User|null $user */
$user = match (true) {
$context instanceof AbstractModel && $context->isRelation('mentionsUsers') => $context->relationLoaded('mentionsUsers')
? $context->mentionsUsers->find($attributes['id']) // @phpstan-ignore-line
: $context->mentionsUsers()->find($attributes['id']), // @phpstan-ignore-line
default => User::query()->find($attributes['id']),
};
$attributes['displayname'] = $user?->display_name ?? $this->translator->trans('core.lib.username.deleted_text');

View File

@@ -15,7 +15,7 @@
"jquery": "^3.6.0",
"jquery.hotkeys": "^0.1.0",
"mithril": "^2.2",
"nanoid": "^3.1.30",
"nanoid": "^3.3.8",
"punycode": "^2.1.1",
"textarea-caret": "^3.1.0",
"throttle-debounce": "^3.0.1"

View File

@@ -40,7 +40,7 @@ trait HasHooks
return $callable;
}
protected function callBeforeHook(Context $context): void
public function callBeforeHook(Context $context): void
{
foreach ($this->before as $before) {
$before = $this->resolveCallable($before, $context);
@@ -48,7 +48,7 @@ trait HasHooks
}
}
protected function callAfterHook(Context $context, mixed $data): mixed
public function callAfterHook(Context $context, mixed $data): mixed
{
foreach ($this->after as $after) {
$after = $this->resolveCallable($after, $context);

View File

@@ -54,4 +54,37 @@ class Collection extends BaseCollection
return parent::loadAggregate($relations, $column, $function);
});
}
/**
* The original Laravel logic uses ->whereNotNull() which is an abstraction that unnecessarily causes
* attribute mutators to run, so if a mutator relies on an eager loaded relationship, the mutator
* will be executed before the call to ->loadMissing() is over.
*
* We replace it with a simple ->where(fn (mixed $relation) => $relation !== null) to avoid this issue.
*/
protected function loadMissingRelation(BaseCollection $models, array $path): void
{
$relation = array_shift($path);
$name = explode(':', key($relation))[0];
if (is_string(reset($relation))) {
$relation = reset($relation);
}
// @phpstan-ignore-next-line
$models->filter(fn ($model) => ! is_null($model) && ! $model->relationLoaded($name))->load($relation);
if (empty($path)) {
return;
}
$models = $models->pluck($name)->filter();
if ($models->first() instanceof \Illuminate\Support\Collection) {
$models = $models->collapse();
}
$this->loadMissingRelation(new static($models), $path);
}
}

View File

@@ -22,7 +22,7 @@ class Console implements ExtenderInterface
/**
* Add a command to the console.
*
* @param class-string<AbstractCommand> $command: ::class attribute of command class, which must extend \Flarum\Console\AbstractCommand.
* @param class-string<AbstractCommand|\Illuminate\Console\Command> $command: ::class attribute of command class, which must extend \Flarum\Console\AbstractCommand.
* @return self
*/
public function command(string $command): self
@@ -35,7 +35,7 @@ class Console implements ExtenderInterface
/**
* Schedule a command to run on an interval.
*
* @param class-string<AbstractCommand> $command: ::class attribute of command class, which must extend Flarum\Console\AbstractCommand.
* @param class-string<AbstractCommand|\Illuminate\Console\Command> $command: ::class attribute of command class, which must extend Flarum\Console\AbstractCommand.
* @param (callable(\Illuminate\Console\Scheduling\Event $event): void)|class-string $callback
*
* The callback can be a closure or invokable class, and should accept:

View File

@@ -3878,10 +3878,10 @@ ms@^2.1.3:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
nanoid@^3.1.30:
version "3.3.7"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8"
integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==
nanoid@^3.3.8:
version "3.3.8"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.8.tgz#b1be3030bee36aaff18bacb375e5cce521684baf"
integrity sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==
natural-compare@^1.4.0:
version "1.4.0"