sintonia_webapp/app/Http/Controllers/SmartBlockController.php

194 lines
6.2 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Filters\FileFilters;
use App\Helpers\LengthFormatter;
use App\Models\File;
use App\Models\SmartBlock;
use App\Models\SmartBlockContent;
use App\Models\SmartBlockCriteria;
use DateInterval;
use DateTime;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
class SmartBlockController extends Controller
{
/**
* Retrieve a list of smart blocks, with optional filters,
* defined in app/Filters/FileFilters
* @return string
*/
public function index(FileFilters $filters) {
if (!isset($filters->per_page) || is_null($filters)) {
$pagination = 20;
} else {
$pagination = $filters->per_page;
}
return File::filter($filters)->cursorPaginate($pagination)->toJson();
}
/**
* Method used to store a new smart block
* @param Request $request
* @return mixed
*/
public function store(Request $request) {
return $this->save($request);
}
/**
* Method used to update a smart block
* @param Request $request
* @param $id
* @return mixed
*/
public function update(Request $request, $id) {
return $this->save($request, $id);
}
/**
* Delete a smart block, cleaning also cc_blockcontent and cc_blockcriteria
* @param $id
* @return int
*/
public function delete($id) {
return SmartBlock::with(['content', 'criteria'])::destroy($id);
}
/**
* Save a new or updated smart block, with content and criteria
* @param Request $request
* @param $id
* @return mixed string
*/
public function save(Request $request, $id = null) {
$user = Auth::user();
$request->validate([
'name' => 'required|string',
'type' => 'required|string',
'length' => 'required|string',
'length_type' => 'required|string',
'criteria' => 'required|array'
]);
$criteria = $request->criteria;
$length = ($request->length_type == 'time') ? new LengthFormatter($request->length) : null;
$dbSmartBlock = SmartBlock::firstOrNew(['id' => $id]);
$dbSmartBlock->fill(new Request([
'name' => $request->name,
'creator_id' => $user->id,
'description' => $request->description,
'length' => $length,
]));
$this->saveCriteria($dbSmartBlock, $criteria);
return $dbSmartBlock->with('criteria')->with('content')->get()->toJson();
}
/**
* Save Smart Block Criteria to database
* @param SmartBlock $smartBlock
* @param array $criteria
* @return void
*/
private function saveCriteria(SmartBlock $smartBlock, array $criteria): void {
$ids = [];
foreach($criteria as $criterion) {
$ids[] = SmartBlockCriteria::updateOrCreate([
'criteria' => $criterion['name'],
'block_id' => $smartBlock->id,
],
[
'modifier' => $criterion['modifier'],
'value' => $criterion['value'],
'extra' => $criterion['extra'], //ToDo: understand this field
'criteriagroup' => $criterion['criteriagroup'],
]);
}
if (!empty($ids)) {
SmartBlockCriteria::whereNotIn('id', $ids)->delete();
}
}
/**
* @param int $block_id
* @param int|null $instance_id
* @return mixed json string
* @throws \DateMalformedIntervalStringException
*/
public function getTrackList(int $block_id, int $instance_id = null) {
$smartBlock = SmartBlock::whereId($block_id)->first();
$criteria = $smartBlock->criteria;
$files = File::smartBlockFilter($criteria)->get();
return $this->criteriaLimit($criteria, $files);
}
/**
* Loop through files if limit criteria is based on total length and stop
* to loop when total length is reached
* @param Collection $criteria
* @param Collection $files
* @return mixed json string
* @throws \DateMalformedIntervalStringException
*/
private function criteriaLimit(Collection $criteria, Collection $files) {
$limit = $criteria->where('criteria', 'limit')->first();
$overflow = $criteria->where('criteria', 'overflow_tracks')->first()->value;
//If limit is not based on sum tracks length is already done in query by filters
if (is_null($limit) || !in_array($limit->modifier, ['hours', 'minutes'])) {
return $files->toJson();
}
//If limit is based on sum tracks length, use them as DateInterval
$interval = DateInterval::createFromDateString($limit->value.' '.$limit->modifier);
$totLengthFromToday = new DateTime();
$intervalFromToday = clone $totLengthFromToday;
$intervalFromToday = $intervalFromToday->add($interval);
$list = collect();
foreach ($files as $file) {
$fileLength = new LengthFormatter($file->length);
$totLengthFromToday->add(DateInterval::createFromDateString($fileLength->toSeconds().' seconds'));
if ($totLengthFromToday < $intervalFromToday) {
$list->push($file);
} else {
if ($overflow) {
$list->push($file);
break;
}
break;
}
}
return $list->toJson();
//ToDo: add limit from instance length
}
/**
* Save preview Smart Block Content
* ToDo: understand when we need to use it
* @param File $file
* @param int $block_id
* @param int $position
* @return void
*/
private function saveContent(File $file, int $block_id, int $position = 0) {
SmartBlockContent::create([
'block_id' => $block_id,
'file_id' => $file->id,
'position' => $position,
'trackoffset' => 0, //ToDo: understand this field
'cliplength' => $file->length,
'cuein' => $file->cuein,
'cueout' => $file->cueout,
'fadein' => '00:00:00', //ToDo: add fadein/fadeout
'fadeout' => '00:00:00',
]);
}
}