›
›
›
  1. docs
  2. ›
  3. byrcsc/laravel-mentions
1.x
Browse documentationOpenClose

Getting started

  • Introduction
  • Installation and setup
  • Quick start

Core concepts

  • Mention records
  • Parsing text
  • Resolving targets
  • Synchronization

Operations

  • Scan multiple attributes
  • Use markup mentions
  • Mention groups
  • Querying mentions
  • React to lifecycle events
  • Control synchronization
  • Extend the package

Reference

  • Configuration
  • Public API
  • Published assets
  • Testing
  • Troubleshooting

Getting started

  • Introduction
  • Installation and setup
  • Quick start

Core concepts

  • Mention records
  • Parsing text
  • Resolving targets
  • Synchronization

Operations

  • Scan multiple attributes
  • Use markup mentions
  • Mention groups
  • Querying mentions
  • React to lifecycle events
  • Control synchronization
  • Extend the package

Reference

  • Configuration
  • Public API
  • Published assets
  • Testing
  • Troubleshooting

byrcsc/laravel-mentions · 1.x

Resolving targets.

Match parsed handles or target IDs to the Eloquent models they name.

A parsed handle such as jane is still text. A resolver looks up the Eloquent model for that handle. If no configured lookup finds a model, the candidate remains unresolved. Synchronization does not create a mention row for it.

Resolve handles by column

The default ColumnMentionResolver receives a model class and column from one resolver definition:

'resolvers' => [
    'users' => [
        'model' => App\Models\User::class,
        'column' => 'username',
    ],
],

It lowercases candidate handles for comparison and uses Laravel's case-insensitive orWhereLike() for the database query. Literal % and _ characters in a handle remain literal instead of acting as SQL wildcards.

The resolver queries all candidates together. One configured resolver issues one target lookup query for its candidate batch, not one query per handle.

Resolver order decides conflicts

The resolver map preserves configuration order. If users and teams both use the handle shared, the first definition that finds it wins:

'resolvers' => [
    'users' => [
        'model' => App\Models\User::class,
        'column' => 'username',
    ],
    'teams' => [
        'model' => App\Models\Team::class,
        'column' => 'slug',
    ],
],

Place the target type with the desired precedence first.

Resolve markup by ID

Markup candidates bypass handle lookup. Their data-mention-type value selects a resolver key. The resolver passes data-mention-id to whereKey():

<span data-mention-type="teams" data-mention-id="01JTEAM"> @engineering </span>

If you omit the type, the package uses the first resolver definition containing model. A class-string-only custom resolver cannot supply that fallback mapping.

The resolver groups ID candidates by model class, so each target model receives one lookup query for its IDs.

Unresolved candidates

An unknown handle, missing ID, unknown markup type, or invalid target model stays in ResolutionResult::$unresolved. Synchronization skips it without throwing.

Call syncMentions() when your application needs to inspect those misses:

$result = $comment->syncMentions();

foreach ($result->unresolved as $candidate) {
    logger()->notice('Mention target not found', [
        'raw' => $candidate->raw,
        'handle' => $candidate->handle,
        'target_id' => $candidate->targetId,
        'target_type' => $candidate->targetType,
    ]);
}

What to read next

  • Synchronization to see how resolved targets become records.
  • Mention groups to configure several target classes.
  • Extend the package to write a tenant-aware resolver.
PreviousParsing textNextSynchronization
View source

On this page

  1. Resolve handles by column
  2. Resolver order decides conflicts
  3. Resolve markup by ID
  4. Unresolved candidates
  5. What to read next