You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tivi_kemana_saja_laravel/app/Models/ApkUpdate.php

140 lines
5.2 KiB
PHP

<?php
namespace App\Models;
use App\Helper\Common;
use App\Helper\FileHelper;
use App\Helper\JSONResponse;
use App\Helper\Traits\Models\CanMultiOrderBy;
use App\Helper\Traits\Models\CanMultiSearch;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\File;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
class ApkUpdate extends Model {
use HasFactory;
use CanMultiSearch;
use CanMultiOrderBy;
protected $table = 'apk_updates';
protected $hidden = ['file'];
protected $appends = ['file_url'];
// ---------------------------------------------------------------------------------------
// -- RELATED TO SCOPE
public function scopeNewest(Builder $query){
return $query->orderByDesc('version_code');
}
// -- END RELATED TO SCOPE
// ---------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------
// -- RELATED TO GET DATA
public static function getLatest(){ return self::latest('version_code')->first(); }
// -- END RELATED TO GET DATA
// ---------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------
// -- RELATED TO MODIFICATION DATA FROM REQUEST
public static function upsertFromRequest(Request $request) {
$request->validate([
'id' => 'nullable|integer|exists:App\Models\ApkUpdate,id',
'name' => 'required|string',
'file' => 'required_without:id|file|' . FileHelper::convertToStrLaraValidation(FileHelper::$allowedApkExtensions),
'version_code' => 'required|integer|min:1',
'change_note' => 'nullable|string'
], [
'file' => ['required_without' => 'The file field is required.']
]);
$delOldDbFileLocation = '';
$newDbFileLocation = '';
try {
// save photo
if($request->file) $newDbFileLocation = self::saveFile($request->file)['db_url'];
// try to upsert data
DB::beginTransaction();
$apkUpdate = null;
if(!$request->id) $apkUpdate = new ApkUpdate();
else $apkUpdate = ApkUpdate::findOrFail($request->id);
// del old db file location if has old file
if($newDbFileLocation) {
if($apkUpdate->file) $delOldDbFileLocation = $apkUpdate->file;
$apkUpdate->file = $newDbFileLocation;
}
$apkUpdate->name = $request->name;
$apkUpdate->version_code = $request->version_code;
$apkUpdate->change_note = $request->change_note;
$apkUpdate->save();
// delete old file if exist
if($delOldDbFileLocation) self::deleteFile($delOldDbFileLocation);
DB::commit();
return JSONResponse::Success();
} catch (\Throwable $th) {
DB::rollBack();
if($newDbFileLocation) self::deleteFile($newDbFileLocation);
throw $th;
}
}
public static function deleteFromRequest(Request $request) {
$request->validate(['id' => 'required|integer|exists:App\Models\ApkUpdate,id']);
try {
DB::beginTransaction();
$apkUpdate = ApkUpdate::findOrFail($request->id);
$oldDbFile = $apkUpdate->file;
$apkUpdate->delete();
if($oldDbFile) self::deleteFile($oldDbFile);
DB::commit();
return JSONResponse::Success();
} catch (\Throwable $th) {
DB::rollBack();
throw $th;
}
}
// -- END RELATED TO MODIFICATION DATA FROM REQUEST
// ---------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------
// -- FILE UTILITIES
protected function fileUrl(): Attribute {
return Attribute::make(
fn() => $this->file ? Storage::disk('s3')->url($this->file) : ''
);
}
private static function fileFolder() { return env('STORAGE_FOLDER', 'tivi') . '/apk-upload'; }
public static function saveFile($file) {
if (!$file->isValid()) throw new \Exception('File is not valid');
//Save file to local data
$fileName = self::getFileName($file);
$path = self::fileFolder();
Storage::disk('s3')->put($path . '/' . $fileName, file_get_contents(new File($file)), 'public');
return ['db_url' => "$path/$fileName"];
}
private static function getFileName($file) {
$tz = Carbon::now()->timestamp;
$extension = $file->getClientOriginalExtension();
$name = "$tz-" . Common::generateRandomString();
return "$name.$extension";
}
public static function deleteFile($dbUrl) { Storage::disk('s3')->delete($dbUrl); }
// -- END FILE UTILITIES
// ---------------------------------------------------------------------------------------
}