ewa / app /Services /ComicServices.php
df
test-laravel
40dca3b
<?php
namespace App\Services;
use App\Models\Chapter;
use App\Models\Comic as ComicModel;
use App\Models\Hashtag;
use App\Models\Tagged;
use Carbon\Carbon;
use Google_Service_Drive_DriveFile;
use Google_Service_Drive_Permission;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Storage;
class ComicServices extends BaseServices
{
private $url_update_link = "https://api-update-img-render.onrender.com/save-comic";
private $summaryContentServices;
private $taggedServices;
public function __construct(ComicModel $model, SummaryContentServices $summaryContentServices, TaggedServices $taggedServices)
{
$this->taggedServices = $taggedServices;
$this->summaryContentServices = $summaryContentServices;
parent::__construct($model);
}
public function index($request)
{
$limit = $request->get('limit', ComicModel::LIMIT_PAGE);
$query = ComicModel::query();
$hashtag = $request->get('hashtag');
if ($hashtag && $hashtag != 'null') {
$query = $query->whereHas('hashtags', function ($query) use ($hashtag) {
$query->where('hashtags.slug', $hashtag);
});
}
if (!empty($request['loading_hashtag'])) {
$query = $query->with('hashtags');
}
if (!empty($request['loading_tagged'])) {
$query = $query->with('taggeds');
}
$keyword = $request->get('keyword');
if ($keyword && $keyword != 'null') {
$query = $query->search($keyword);
}
$query = $query->with('chapters', function ($query) {
$query->orderBy('id', 'asc');
});
if(!$request->get('isBackend')){
$latestChapters = DB::table('chapters')
->select('comic_id', DB::raw('MAX(publish_at) as latest_chapter_updated_at'))
->groupBy('comic_id');
$query = $query
->joinSub($latestChapters, 'latest_chapters', function ($join) {
$join->on('comics.id', '=', 'latest_chapters.comic_id');
})
->orderBy('latest_chapter_updated_at', 'desc');
}
$query->orderBy('comics.id', 'desc');
$query->select('comics.*');
$data = $query->paginate($limit);
if (!$data->isEmpty()) {
// cal diff time
$data = $this->calDiffTime($data);
// sort
$data = $this->sortDataBy($data);
$data = $this->makeSkeletonColor($data);
}
return $data;
}
public function makeSkeletonColor($data)
{
$data->each(function ($item) {
$item['skeleton_bg_color'] = str_replace(")", ", 0.3)", $item->bg_color);
});
return $data;
}
public function calDiffTime($data)
{
$now = Carbon::now();
$data->each(function ($item) use ($now) {
if ($item ?->chapters->isNotEmpty()){
$latestItem = $item->chapters->reduce(function ($carry, $item) {
if (is_null($carry) || $item['publish_at'] > $carry['publish_at']) {
return $item;
}
return $carry;
});
$item['diff_time'] = $now->diffInMinutes($latestItem->publish_at);
$item['diff_time_to_sort'] = $now->diffInMinutes($latestItem->publish_at);
if ($item['diff_time'] <= 0) {
$item['diff_time'] = 'Mới cập nhật';
} else if ($item['diff_time'] <= 60) {
$item['diff_time'] = 'Cách đây ' . $item['diff_time'] . ' phút';
} else if ($item['diff_time'] <= 1440) {
$item['diff_time'] = 'Cách đây ' . round(($item['diff_time'] / 60), 0, PHP_ROUND_HALF_DOWN) . ' giờ';
} else if ($item['diff_time'] <= 10080) {
$item['diff_time'] = 'Cách đây ' . round(($item['diff_time'] / (60 * 24)), 0, PHP_ROUND_HALF_DOWN) . ' ngày';
} else if ($item['diff_time'] <= 40320) {
$item['diff_time'] = 'Cách đây ' . round(($item['diff_time'] / (60 * 24 * 7)), 0, PHP_ROUND_HALF_DOWN) . ' tuần';
} else {
$item['diff_time'] = 'Cách đây ' . round(($item['diff_time'] / (60 * 24 * 7 * 4)), 0, PHP_ROUND_HALF_DOWN) . ' tháng';
}
}else{
$item['diff_time_to_sort'] = 0;
$item['diff_time'] = 'Mới cập nhật';
}
});
return $data;
}
public function sortDataBy($data)
{
$data->setCollection(collect($data->items())->sortBy(function ($item) {
return $item['diff_time_to_sort'];
}));
return $data;
}
public function prepareHashtags($data)
{
foreach ($data as $comic) {
$idTag = $comic->taggeds->where('is_main_tag', 1)->first();
if ($idTag) {
$comic->hashtags->each(function ($item) use ($idTag) {
if ($idTag->hashtag_id == $item->id) {
$item['is_main_tag'] = true;
}
});
}
}
return $data;
}
public function save(array $attributes)
{
$entity = null;
if (!empty($attributes['comic_code'])) {
$entity = $this->model->where('comic_code', $attributes['comic_code'])->first();
if ($entity) {
if ($attributes['bg_color']) {
$attributes['tranfer_color'] = "background:linear-gradient(to bottom, rgba({$attributes['bg_color']},0) 2%, rgba({$attributes['bg_color']},0.7) 50%, rgba({$attributes['bg_color']}))";
$attributes['bg_color'] = "rgba({$attributes['bg_color']})";
} else {
$attributes['tranfer_color'] = '';
}
$entity->fill($attributes)->save();
$this->updateSummaryContents($attributes, $entity);
$this->updateTaggeds($attributes, $entity);
}
} else {
$attributes['comic_code'] = "COMIC-";
if ($attributes['bg_color']) {
$attributes['tranfer_color'] = "background:linear-gradient(to bottom, rgba({$attributes['bg_color']},0) 2%, rgba({$attributes['bg_color']},0.7) 50%, rgba({$attributes['bg_color']}))";
$attributes['bg_color'] = "rgba({$attributes['bg_color']})";
} else {
$attributes['tranfer_color'] = '';
}
$entity = $this->model->create($attributes);
$entity->comic_code = "COMIC-" . $entity->id;
$entity->save();
$this->addSummaryContents($attributes, $entity);
$this->addTaggeds($attributes, $entity);
}
if ($entity) {
$result['id'] = $entity->id;
$result['link_avatar'] = $this->getGGId($entity->link_avatar);
$result['link_comic_name'] = $this->getGGId($entity->link_comic_name);
$result['link_bg'] = $this->getGGId($entity->link_bg);
$result['link_banner'] = $this->getGGId($entity->link_banner);
$result['link_comic_small_name'] = $this->getGGId($entity->link_comic_small_name);
$json = json_encode($result);
Http::withBody($json, 'application/json')
->post($this->url_update_link);
}
return $entity;
}
public function updateSummaryContents($attributes, $entity)
{
$summayContent['id'] = $entity ?->summaryContents ?->id;
$summayContent['comic_id'] = $entity['id'];
$summayContent['content'] = $attributes['summary_contents'];
$this->summaryContentServices->save($summayContent);
}
public function addSummaryContents($attributes, $entity)
{
$summayContent['comic_id'] = $entity['id'];
$summayContent['content'] = $attributes['summary_contents'];
$this->summaryContentServices->save($summayContent);
}
public function updateTaggeds($attributes, $entity)
{
// lay ra tat cả tagged của entity
$oldTaggeds = $entity->hashtags->pluck('id')->all();
$listtemp = [];
if (isset($attributes['tagged'])) {
foreach ($attributes['tagged'] as $index => $tagged) {
if (in_array($tagged, $oldTaggeds)) {
$listtemp[] = $tagged;
} else {
$this->taggedServices->save(['comic_id' => $entity->id, 'hashtag_id' => $tagged]);
}
}
}
// lọc các id cần xóa
$listdelete = array_diff($oldTaggeds, $listtemp);
$this->taggedServices->deleteByComicIdandHashtagId($entity->id, $listdelete);
}
public function addTaggeds($attributes, $entity)
{
if (isset($attributes['tagged'])) {
foreach ($attributes['tagged'] as $index => $tagged) {
$this->taggedServices->save(['comic_id' => $entity->id, 'hashtag_id' => $tagged]);
}
}
}
public function createIdGG($driveService, $folderId, $newPermission, $field_name, $googleUrl, &$comic, &$file)
{
$fileToUpload = $this->postGGDrive($driveService, $file[$field_name]['file'], $folderId);
if ($fileToUpload) {
$driveService->permissions->create($fileToUpload->id, $newPermission);
$file[$field_name]['url'] = $googleUrl[0] . $fileToUpload->id . $googleUrl[1];
$comic[$field_name] = $file[$field_name]['url'];
$comic[$field_name.'_backup'] = $file[$field_name]['url'];
}
return $file;
}
public function uploadGGDrive($request, &$comic)
{
$file = [];
$file['link_banner']['file'] = $request->file('link_banner');
$file['link_video_banner']['file'] = $request->file('link_video_banner');
$file['link_video_banner_2']['file'] = $request->file('link_video_banner_2');
$file['link_avatar']['file'] = $request->file('link_avatar');
$file['link_comic_name']['file'] = $request->file('link_comic_name');
$file['link_comic_small_name']['file'] = $request->file('link_comic_small_name');
$file['link_bg']['file'] = $request->file('link_bg');
$driveService = Storage::disk('google');
$newPermission = app()->make('googlePermission');
$folderId = app()->make('googleFolderId');
$googleUrlImg[0] = "https://lh3.googleusercontent.com/d/";
$googleUrlImg[1] = "=w1000";
$googleUrlVideoWebm[0] = "https://drive.usercontent.google.com/download?id=";
$googleUrlVideoWebm[1] = "&export=download&type=video/webm";
$googleUrlVideoMov[0] = "https://drive.usercontent.google.com/download?id=";
$googleUrlVideoMov[1] = "&export=download&type=video/quicktime";
$this->createIdGG($driveService, $folderId, $newPermission, "link_avatar", $googleUrlImg, $comic, $file);
$this->createIdGG($driveService, $folderId, $newPermission, "link_banner", $googleUrlImg, $comic, $file);
$this->createIdGG($driveService, $folderId, $newPermission, "link_video_banner", $googleUrlVideoWebm, $comic, $file);
$this->createIdGG($driveService, $folderId, $newPermission, "link_video_banner_2", $googleUrlVideoMov, $comic, $file);
$this->createIdGG($driveService, $folderId, $newPermission, "link_comic_name", $googleUrlImg, $comic, $file);
$this->createIdGG($driveService, $folderId, $newPermission, "link_comic_small_name", $googleUrlImg, $comic, $file);
$this->createIdGG($driveService, $folderId, $newPermission, "link_bg", $googleUrlImg, $comic, $file);
// $fileToUpload = $this->postGGDrive($driveService, $file['link_avatar']['file'], $folderId);
// if ($fileToUpload) {
// $driveService->permissions->create($fileToUpload->id, $newPermission);
// $file['link_avatar']['url'] = 'https://lh3.googleusercontent.com/d/' . $fileToUpload->id . '=w1000';
// $comic['link_avatar'] = $file['link_avatar']['url'];
// }
//
//
// $fileToUpload = $this->postGGDrive($driveService, $file['link_comic_name']['file'], $folderId);
// if ($fileToUpload) {
// $driveService->permissions->create($fileToUpload->id, $newPermission);
// $file['link_comic_name']['url'] = 'https://lh3.googleusercontent.com/d/' . $fileToUpload->id . '=w1000';
// $comic['link_comic_name'] = $file['link_comic_name']['url'];
// }
//
//
// $fileToUpload = $this->postGGDrive($driveService, $file['link_bg']['file'], $folderId);
// if ($fileToUpload) {
// $driveService->permissions->create($fileToUpload->id, $newPermission);
// $file['link_bg']['url'] = 'https://lh3.googleusercontent.com/d/' . $fileToUpload->id . '=w1000';
// $comic['link_bg'] = $file['link_bg']['url'];
// }
//
//
// $fileToUpload = $this->postGGDrive($driveService, $file['link_banner']['file'], $folderId);
// if ($fileToUpload) {
// $driveService->permissions->create($fileToUpload->id, $newPermission);
// $file['link_banner']['url'] = 'https://lh3.googleusercontent.com/d/' . $fileToUpload->id . '=w1000';
// $comic['link_banner'] = $file['link_banner']['url'];
// }
//
// $fileToUpload = $this->postGGDrive($driveService, $file['link_video_banner']['file'], $folderId);
// if ($fileToUpload) {
// $driveService->permissions->create($fileToUpload->id, $newPermission);
// $file['link_video_banner']['url'] = 'https://drive.usercontent.google.com/download?id=' . $fileToUpload->id . '&export=download';
// $comic['link_video_banner'] = $file['link_video_banner']['url'];
// }
//
// $fileToUpload = $this->postGGDrive($driveService, $file['link_video_banner_2']['file'], $folderId);
// if ($fileToUpload) {
// $driveService->permissions->create($fileToUpload->id, $newPermission);
// $file['link_video_banner_2']['url'] = 'https://drive.usercontent.google.com/download?id=' . $fileToUpload->id . '&export=download';
// $comic['link_video_banner_2'] = $file['link_video_banner_2']['url'];
// }
//
//
// $fileToUpload = $this->postGGDrive($driveService, $file['link_comic_small_name']['file'], $folderId);
// if ($fileToUpload) {
// $driveService->permissions->create($fileToUpload->id, $newPermission);
// $file['link_comic_small_name']['url'] = 'https://lh3.googleusercontent.com/d/' . $fileToUpload->id . '=w1000';
// $comic['link_comic_small_name'] = $file['link_comic_small_name']['url'];
// }
return $file;
}
public function findByComicCode($comic_code)
{
return $this->model->where('comic_code', $comic_code)->first();
}
public function getAllComics()
{
$data = ComicModel::query();
$data = $data
->select('slug', 'id', 'comic_name');
$data = $data->with('chapters', function ($data) {
$data->select('comic_id', 'slug', 'chapter_name', 'id');
})->get();
return $data;
}
public function show($comicCode)
{
$data = ComicModel::query();
$data = $data->with('chapters', function ($query) {
$query->orderBy('id', 'asc');
})
->with('summaryContents')
->with('hashtags')
->where('comic_code', $comicCode)->first();
if (!empty($data)) {
$now = Carbon::now();
if ($data ?->chapters ?->last() ?->publish_at){
$data['diff_time'] = $now->diffInMinutes($data ?->chapters ?->last() ?->publish_at);
if ($data['diff_time'] <= 0) {
$data['diff_time'] = 'Mới cập nhật';
} else if ($data['diff_time'] <= 60) {
$data['diff_time'] = 'Cách đây ' . $data['diff_time'] . ' phút';
} else if ($data['diff_time'] <= 1440) {
$data['diff_time'] = 'Cách đây ' . round(($data['diff_time'] / 60), 0, PHP_ROUND_HALF_DOWN) . ' giờ';
} else {
$data['diff_time'] = 'Cách đây ' . round(($data['diff_time'] / (60 * 24)), 0, PHP_ROUND_HALF_DOWN) . ' ngày';
}
}else{
$data['diff_time'] = 'Mới cập nhật';
}
$data->chapters->each(function ($item) {
foreach (Chapter::TIME as $key => $value) {
if ($item[$value])
$item[$value] = Carbon::parse($item[$value])->tz(config('app.timezone'))->format('d/m/Y');
}
});
$data['skeleton_bg_color'] = str_replace(")", ", 0.3)", $data->bg_color);
}
return $data;
}
public function getRelationComic($comic_code, $limit = 10)
{
// lấy ra các hashtag của comic này
$comic = $this->findByComicCode($comic_code);
// nếu ko sợ việc lặp record thì dùng join sẽ nhanh hơn , nhưng trường hợp này , 2 bảng
// comic và hashtag là n-n với nhau nên sẽ xảy ra lặp >> ko dùng join
// $hashtags = $comic->hashtags->pluck('id')->toArray();
// dùng whereHas để lấy ra các hashtags có comic id
$hashtags = Hashtag::select('id')->whereHas('comics', function ($hashtags) use ($comic) {
$hashtags->where('comic_id', $comic->id);
});
// ở đây ta lấy ra array các id hashtag , thì lúc chạy query dưới sẽ nhanh hơn
// là tạo 1 câu query dài
$hashtags = $hashtags->get()->toArray();
$query = $this->model->whereIn('id', function ($query) use ($hashtags) {
$query->select('comic_id')->from('taggeds')->whereIn('hashtag_id', $hashtags);
});
$data = $query->limit($limit)->get();
if (!$data->isEmpty()) {
$data = $this->makeSkeletonColor($data);
}
return $data;
}
public function delete($comicCode)
{
$entity = $this->model
->where('comic_code', $comicCode)->first();
// xoa img tren ggdrive
$result = collect($entity)->only(['link_bg', 'link_avatar', 'link_comic_name', 'link_banner', 'link_comic_small_name',
'link_banner_backup','link_bg_backup','link_avatar_backup','link_comic_name_backup','link_comic_small_name_backup']);
$this->deteleGGDrive($result->toArray());
return !empty($entity) ? $entity->delete() : null;
}
}