156 lines
4.7 KiB
PHP
156 lines
4.7 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Bo;
|
|
|
|
use App\Enums\ExcludeTypeEnum;
|
|
use App\Http\Controllers\Controller;
|
|
use App\Http\Requests\Bo\Ajax\ExcludeTopMediaRequest;
|
|
use App\Jobs\InstaGetTopMediasJob;
|
|
use App\Lib\Instagram\Objects\TopMedia;
|
|
use App\Models\InstaMedia;
|
|
use App\Models\InstaMediaExclusion;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Collection;
|
|
use Illuminate\Support\Facades\Cache;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\View\View;
|
|
|
|
class TopMediaController extends Controller
|
|
{
|
|
/**
|
|
* Show paginated Top Media List
|
|
*
|
|
* @param \Illuminate\Http\Request $request
|
|
* @return \Illuminate\View\View
|
|
*/
|
|
public function index(Request $request): View
|
|
{
|
|
/** @var \Illuminate\Database\Eloquent\Builder $topMediaList */
|
|
$topMediaList = InstaMedia::query();
|
|
$ranking = $this->getRanking();
|
|
|
|
if ($request->search) {
|
|
$this->searchQuery(
|
|
$topMediaList,
|
|
$request->search,
|
|
null,
|
|
'insta_id',
|
|
'username',
|
|
'permalink'
|
|
);
|
|
} //end if
|
|
|
|
$this->sortQuery($topMediaList);
|
|
$searchFields = trans('Id Instagram, Participant, Lien');
|
|
$topMediaList->orderBy('updated_at', 'DESC');
|
|
$topMediaList = $topMediaList->paginate();
|
|
|
|
return \view('bo.pages.top-media.index', \compact('topMediaList', 'searchFields', 'ranking'));
|
|
}
|
|
|
|
/**
|
|
* Show the refresh vue component
|
|
*
|
|
* @return \Illuminate\View\View
|
|
*/
|
|
public function refresh(): View
|
|
{
|
|
return \view('bo.pages.top-media.refresh');
|
|
}
|
|
|
|
// * Ajax Methods.
|
|
|
|
/**
|
|
* Fetch Insta media list from api
|
|
*
|
|
* @param boolean $refresh
|
|
* @return \Illuminate\Http\JsonResponse
|
|
*/
|
|
public function fetch(bool $refresh = false): JsonResponse
|
|
{
|
|
$responseData = [
|
|
'ready' => false
|
|
];
|
|
if (
|
|
Cache::get('top_media_job_fetch_dispatched') or
|
|
Cache::get('top_media_job_fetch_running')
|
|
) {
|
|
return response()->json($responseData);
|
|
}
|
|
|
|
if (empty(Cache::get('top_media_ajax_fetch')) or $refresh) {
|
|
\dispatch(new InstaGetTopMediasJob())->onConnection('database');
|
|
Cache::put('top_media_job_fetch_dispatched', true);
|
|
return response()->json($responseData);
|
|
}
|
|
$responseData['ready'] = true;
|
|
$responseData['data'] = Cache::get('top_media_ajax_fetch');
|
|
return \response()->json($responseData);
|
|
}
|
|
|
|
/**
|
|
* Fetch Media Picture Object
|
|
*
|
|
* @param string $ig_media_hash
|
|
* @return \Illuminate\Http\JsonResponse
|
|
*/
|
|
public function fetchPicture(string $ig_media_hash): JsonResponse
|
|
{
|
|
return \response()->json(Cache::remember(
|
|
"media_picture_ajax_fetch{$ig_media_hash}",
|
|
// * 3H cache
|
|
3 * 60 * 60,
|
|
fn () => InstaMedia::fetchInstagramMediaPictures($ig_media_hash)
|
|
));
|
|
}
|
|
|
|
/**
|
|
* Save the new list
|
|
*
|
|
* @return \Illuminate\Http\RedirectResponse
|
|
*/
|
|
public function save(): JsonResponse
|
|
{
|
|
return DB::transaction(function () {
|
|
/** @var \Illuminate\Support\Collection<\App\Lib\Instagram\Objects\TopMedia> */
|
|
$igMediaList = Cache::get('top_media_ajax_fetch');
|
|
// * 'Truncate' our list to preserve only the desired media amount.
|
|
// Dont use truncate here because it implies a commit.
|
|
InstaMedia::query()->delete();
|
|
|
|
$igMediaList->map(function (TopMedia $ig_media) {
|
|
(new InstaMedia((array)$ig_media))->saveOrFail();
|
|
});
|
|
|
|
\session()->flash('success', trans('Le classement à bien été mis à jour'));
|
|
return \response()->json();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Exclude a top Media or a username
|
|
*
|
|
* @param \App\Http\Requests\Bo\Ajax\ExcludeTopMediaRequest $request
|
|
* @return \Illuminate\Http\JsonResponse
|
|
*/
|
|
public function exclude(ExcludeTopMediaRequest $request): JsonResponse
|
|
{
|
|
$excludeData = [
|
|
'type' => $request->insta_id ? ExcludeTypeEnum::post : ExcludeTypeEnum::user,
|
|
'value' => $request->insta_id ?: $request->username
|
|
];
|
|
InstaMediaExclusion::query()->firstOrCreate($excludeData, $excludeData)->saveOrFail();
|
|
return \response()->json($excludeData);
|
|
}
|
|
|
|
/**
|
|
* Get Actual ranking
|
|
*
|
|
* @return \Illuminate\Support\Collection<App\Models\InstaMedia>
|
|
*/
|
|
private function getRanking(): Collection
|
|
{
|
|
return InstaMedia::query()->orderBy('id')->pluck('insta_id')->flip();
|
|
}
|
|
}
|