Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Larasou's avatar

Previous and next buttons for episodes

Good morning all!

I have a site with videos, the videos are organized like for Laracasts: Series => Seasons => Episodes

When watching an "episode", I would like to put the links to go to the previous and next episodes.

My videos are ordered by date (published_at) and not by ID.

I would therefore like to retrieve the episode which is part of the same season, and which has the earliest date.

How can I do please?

0 likes
7 replies
Sinnbeck's avatar

Quick fix. Once you publish a series you have a job that gives them a value in an order column. Then you can easily add or subtract one. And you only need to "index" the series once

Larasou's avatar

Thanks for your answer, but I didn't quite understand. How do I proceed ?

Sinnbeck's avatar

@Larasou imagine you have 10 episodes in a series. You then get them and loop over them while setting their order

$episodes = Episode::where('series_id', 7)->latest('published_at')->get();
foreach ($episodes as $index => $episode) {
     $episode->update(['order' => $index + 1]);
}
Larasou's avatar

Thank you, thank you very much to all of you! I tested your solutions, but I was still not satisfied with the result. I wanted to retrieve the data index, but I didn't know how to do it. Then I remembered that I wanted to do it via JavaScript:

export default {
    name: "EpisodeShow",
    props: [ 'episode', 'episodes'],
    data() {
       return {
           next: '',
           previous: '',
       }
    },

    created() {
  		this.pages();
    },

    methods: {
        pages() {
            const episodes = this.orderBy(this.episodes, 'published_at');

            let index = episodes.findIndex(element => {
                return element.id === this.episode.id;
            });

            if (episodes[index-1]) {
               this.previous = episodes[index-1].path;
            }

            if (episodes[index+1]) {
               this.next = episodes[index+1].path;
            }

        },

    },
}

Is there a method in PHP or with Laravel to do the same thing?

Sinnbeck's avatar
Sinnbeck
Best Answer
Level 102

@Larasou Yeah should be easy to do

$episodes = Episode::where('series_id', 7)->latest('published_at')->get();
$index = $episodes->search($episode->id);

if (isset($episodes[$index-1] {
   $previous = $episodes[index-1];
}

if (isset($episodes[$index+1] {
   $next = $episodes[index-1];
}
1 like
anhhungno1's avatar

@Sinnbeck i have these how can i create next and previous button

Controller:

 public function getMovieOverview(Request $request, $movie)
    {
        /** @var Movie */
        $movie = Movie::fromCache()->find($movie);

        if (is_null($movie)) abort(404);

        $movie->generateSeoTags();

        $movie->increment('view_total', 1);
        $movie->increment('view_day', 1);
        $movie->increment('view_week', 1);
        $movie->increment('view_month', 1);

        $movie_related_cache_key = 'movie_related.' . $movie->id;
        $movie_related = Cache::get($movie_related_cache_key);
        if(is_null($movie_related)) {
            $movie_related = $movie->categories[0]->movies()->inRandomOrder()->limit(12)->get();
            Cache::put($movie_related_cache_key, $movie_related, setting('site_cache_ttl', 5 * 60));
        }

        return view('themes::themebptv.single', [
            'currentMovie' => $movie,
            'title' => $movie->getTitle(),
            'movie_related' => $movie_related
        ]);
    }

    public function getEpisode(Request $request, $movie, $slug, $id)
    {
        $movie = Movie::fromCache()->find($movie)->load('episodes');

        if (is_null($movie)) abort(404);

        /** @var Episode */
        $episode = $movie->episodes->when($id, function ($collection, $id) {
            return $collection->where('id', $id);
        })->firstWhere('slug', $slug);

        if (is_null($episode)) abort(404);

        $episode->generateSeoTags();

        $movie->increment('view_total', 1);
        $movie->increment('view_day', 1);
        $movie->increment('view_week', 1);
        $movie->increment('view_month', 1);

        $movie_related_cache_key = 'movie_related.' . $movie->id;
        $movie_related = Cache::get($movie_related_cache_key);
        if(is_null($movie_related)) {
            $movie_related = $movie->categories[0]->movies()->inRandomOrder()->limit(12)->get();
            Cache::put($movie_related_cache_key, $movie_related, setting('site_cache_ttl', 5 * 60));
        }

        return view('themes::themebptv.episode', [
            'currentMovie' => $movie,
            'movie_related' => $movie_related,
            'episode' => $episode,
            'title' => $episode->getTitle()
        ]);
    }

Và Routes:

Route::get(sprintf('/%s/{movie}/{episode}-{id}', config('ophim.routes.movie', 'phim')), [ThemeBptvController::class, 'getEpisode'])
        ->where(['movie' => '.+', 'episode' => '.+', 'id' => '[0-9]+'])->name('episodes.show');

Hope you can help me and thank you very much

Please or to participate in this conversation.