HEX
Server: LiteSpeed
System: Linux s1049.use1.mysecurecloudhost.com 4.18.0-477.27.2.lve.el8.x86_64 #1 SMP Wed Oct 11 12:32:56 UTC 2023 x86_64
User: xedaptot (3356)
PHP: 8.3.31
Disabled: NONE
Upload Files
File: //home/xedaptot/iphim.naniguide.com/app/Http/Controllers/RelatedVideosController.php
<?php

namespace App\Http\Controllers;

use App\Episode;
use App\Services\Titles\Retrieve\GetRelatedTitles;
use App\Title;
use App\Video;
use Common\Core\BaseController;
use Common\Settings\Settings;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Http\Request;
use Illuminate\Support\Str;

class RelatedVideosController extends BaseController
{
    /**
     * @var Title
     */
    private $title;

    /**
     * @var Request
     */
    private $request;

    /**
     * @var Video
     */
    private $video;
    /**
     * @var Episode
     */
    private $episode;

    /**
     * @var Settings
     */
    private $settings;

    /**
     * @param Request $request
     * @param Title $title
     * @param Video $video
     * @param Episode $episode
     * @param Settings $settings
     */
    public function __construct(
        Request $request,
        Title $title,
        Video $video,
        Episode $episode,
        Settings $settings
    ) {
        $this->title = $title;
        $this->request = $request;
        $this->video = $video;
        $this->episode = $episode;
        $this->settings = $settings;
    }

    public function index()
    {
        $seasonNum = $this->request->get('season');
        $episodeNum = $this->request->get('episode');
        $titleId = $this->request->get('titleId');

        if ($seasonNum && $episodeNum && app(Settings::class)->get('player.show_next_episodes')) {
            $videos = $this->videosByEpisode($titleId, $seasonNum, $episodeNum);
        } else {
            $videos = $this->videosByTags($titleId);
        }

        return $this->success(['videos' => $videos]);
    }

    private function videosByEpisode($titleId, $seasonNum, $episodeNum)
    {
        list($col, $direction) = explode(':', app(Settings::class)->get('streaming.default_sort'));

        $prevSeasonNum = $seasonNum - 1;
        $nextSeasonNum = $seasonNum + 1;

        $videos = $this->video
            ->with('title', 'captions', 'episode')
            ->where('title_id', $titleId)
            ->where('approved', true)
            ->where('category', 'full')
            ->whereNotNull('episode_id')
            ->whereIn('season_num', [$seasonNum, $nextSeasonNum, $prevSeasonNum])
            ->orderBy($col, $direction)
            ->groupBy(['season_num', 'episode_num'])
            ->get();

        if ($videos->isEmpty()) {
            return [];
        }

        $grouped = $videos->groupBy('season_num')->map(function(Collection $videos, $seasonNum) use($prevSeasonNum, $nextSeasonNum) {
            if ($seasonNum === $prevSeasonNum) {
                return $videos->sortByDesc('episode_num')->first();
            } else if ($seasonNum === $nextSeasonNum) {
                return $videos->sortByDesc('episode_num')->last();
            } else {
                // current season episodes
                return $videos->sortBy('season')->sortBy('episode_num');
            }
        });

        $videos = $grouped->get($seasonNum)->values();

        // make sure prev season last episode appears first
        if ($prevSeason = $grouped->get($prevSeasonNum)) {
            $videos->prepend($prevSeason);
        }

        // make sure next season first episode appears last
        if ($nextSeason = $grouped->get($nextSeasonNum)) {
            $videos->push($nextSeason);
        }

        $videos->transform(function(Video $video) {
            $episode = $video->episode;
            $sNum = $episode->season_number < 10 ? ('0' . $episode->season_number) : $episode->season_number;
            $eNum = $episode->episode_number < 10 ? ('0' . $episode->episode_number)  : $episode->episode_number;
            $video->name = "(s{$sNum}e{$eNum}) - {$episode->name}";
            $video->description = Str::limit($episode->description, 35);
            $video->thumbnail = $episode->poster;
            $video->setRelation('episode', null);
            return $video;
        });

        return $videos->values();
    }

    private function videosByTags($titleId)
    {
        $title = $this->title
            ->with('keywords', 'genres')
            ->findOrFail($titleId);

        $related = app(GetRelatedTitles::class)->execute($title);
        $videos = [];

        if ($related->isNotEmpty()) {
            $related->load(['videos' => function(HasMany $builder) {
                $contentType = $this->settings->get('streaming.video_panel_content');
                if ($contentType === 'all') return;
                if ($contentType === 'full') {
                    $builder->where('category', 'full');
                } else if ($contentType === 'short') {
                    $builder->where('category', '!=', 'full');
                } else {
                    $builder->where('category', $contentType);
                }
            }]);
            $videos = $related->map(function(Title $title) {
                if ($video = $title->videos->first()) {
                    $video = $title->videos->first();
                    $title->setRelation('videos', []);
                    $video->title = $title;
                    return $video;
                }
            })->filter()->values();
        }

        return $videos;
    }
}