Skip to main content
The SummonerEmoteController handles HTTP requests for the summoner emote catalog with search, filtering, and administrative CRUD operations.

Overview

Located at source/app/Http/Controllers/SummonerEmoteController.php, this controller:
  • Displays paginated emote catalog (72 emotes per page)
  • Filters by title
  • Sorts by emote ID (newest first)
  • Implements 1-hour caching with query-specific cache keys
  • Provides full CRUD operations with authorization
  • Returns JSON responses for API operations

Class Definition

namespace App\Http\Controllers;

use App\Models\SummonerEmote;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Spatie\QueryBuilder\QueryBuilder;

class SummonerEmoteController extends Controller
{
    // Controller methods
}

Routes

Defined in source/routes/web.php:55:
Route::get('emotes', static fn () => (new SummonerEmoteController)->index())
    ->name('assets.emotes.index');

Methods

index()

Displays a filterable, paginated listing of summoner emotes.
public function index()
{
    $cacheKey = 'emotes_' . md5(serialize(request()->query()));

    $emotes = Cache::remember($cacheKey, 60 * 60, function () {
        return QueryBuilder::for(SummonerEmote::class)
            ->allowedFilters('title')
            ->defaultSort('-emote_id')
            ->paginate(72)
            ->appends(request()->query());
    });

    return view('emotes.index', ['emotes' => $emotes]);
}

Query Parameters

filter[title]
string
Filter by emote title (exact match)Example: ?filter[title]=Happy
page
integer
default:"1"
Page number for pagination (72 emotes per page)Example: ?page=2

Return Value

view
Illuminate\View\View
Rendered emotes.index Blade template

View Data

emotes
LengthAwarePaginator<SummonerEmote>
Paginated collection of summoner emotes (72 per page)

Cache Strategy

Emotes are cached for 1 hour with a unique cache key per query combination using MD5 hash of serialized query parameters.
Cache Key Format: emotes_{md5_hash_of_query} Examples:
  • emotes_d41d8cd98f00b204e9800998ecf8427e (no filters)
  • emotes_b2e4a8f9c1d6e5f4a3b2c1d0e9f8a7b6 (with filters)

Default Sorting

->defaultSort('-emote_id')
Emotes are sorted by emote_id in descending order (newest emotes first). The - prefix indicates descending sort.

Usage Examples

GET /emotes

show()

Returns a specific emote (JSON response).
public function show(SummonerEmote $summonerEmote)
{
    return $summonerEmote;
}

Parameters

summonerEmote
SummonerEmote
required
SummonerEmote model instance (automatically resolved via route model binding)

Return Value

emote
SummonerEmote
Individual summoner emote model as JSON
This method returns JSON directly, not a view. Useful for API endpoints.

store()

Creates a new summoner emote (requires authorization).
public function store(Request $request)
{
    $this->authorize('create', SummonerEmote::class);

    $request->validate([
        'emote_id' => ['required', 'integer'],
        'title' => ['required'],
        'image' => ['required'],
    ]);

    return SummonerEmote::create($request->validated());
}

Authorization

This method requires the user to be authorized to create SummonerEmote records. Unauthorized requests will receive a 403 Forbidden response.

Validation Rules

emote_id
integer
required
Riot Games API emote ID
title
string
required
Emote display title/name
image
string
required
CDN URL for the emote image

Return Value

emote
SummonerEmote
Newly created SummonerEmote model instance (JSON)

update()

Updates an existing summoner emote (requires authorization).
public function update(Request $request, SummonerEmote $summonerEmote)
{
    $this->authorize('update', $summonerEmote);

    $request->validate([
        'emote_id' => ['required', 'integer'],
        'title' => ['required'],
        'image' => ['required'],
    ]);

    $summonerEmote->update($request->validated());

    return $summonerEmote;
}

Authorization

This method requires the user to be authorized to update the specific SummonerEmote. Unauthorized requests will receive a 403 Forbidden response.

Parameters

summonerEmote
SummonerEmote
required
Emote to update (resolved via route model binding)

Validation Rules

emote_id
integer
required
Riot Games API emote ID
title
string
required
Emote display title/name
image
string
required
CDN URL for the emote image

Return Value

emote
SummonerEmote
Updated SummonerEmote model instance (JSON)

destroy()

Deletes a summoner emote (requires authorization).
public function destroy(SummonerEmote $summonerEmote)
{
    $this->authorize('delete', $summonerEmote);

    $summonerEmote->delete();

    return response()->json();
}

Authorization

This method requires the user to be authorized to delete the specific SummonerEmote. Unauthorized requests will receive a 403 Forbidden response.

Parameters

summonerEmote
SummonerEmote
required
Emote to delete (resolved via route model binding)

Return Value

response
JsonResponse
Empty JSON response with 200 status code

Authorization

Unlike the SummonerIconController, this controller implements Laravel’s authorization policies:
$this->authorize('create', SummonerEmote::class);
$this->authorize('update', $summonerEmote);
$this->authorize('delete', $summonerEmote);
Authorization policies should be defined in app/Policies/SummonerEmotePolicy.php to control who can create, update, and delete emotes.

Spatie Query Builder

This controller uses Spatie Query Builder for filtering:
QueryBuilder::for(SummonerEmote::class)
    ->allowedFilters('title')
    ->defaultSort('-emote_id')
    ->paginate(72)

Allowed Filters

Column: titleType: Exact matchExample: ?filter[title]=Happy Face matches emotes with exactly “Happy Face” as the title

Pagination

perPage
integer
default:"72"
Number of emotes displayed per page
Pagination URLs:
/emotes?page=1
/emotes?page=2&filter[title]=Dance

Differences from SummonerIconController

Authorization

Emote controller has authorization checks on CRUD operations

Fewer Filters

Only title filtering (no esports or year filters)

JSON Responses

show() returns JSON instead of a view

Simpler Data

Emotes have simpler schema than icons

Performance Considerations

Query-Specific Caching

Each unique query combination gets its own cache key

1-Hour Cache

Emotes cached for 1 hour per query

Large Pages

72 emotes per page reduces number of requests

Indexed Queries

Ensure title column is indexed for fast filtering

SummonerEmote Model

View the SummonerEmote model API reference

Assets Feature

Learn about the game assets browsing feature

Icon Controller

View the icon controller documentation

Architecture

Understand the MVC architecture

Build docs developers (and LLMs) love