per_page) || is_null($request)) { $pagination = 5; } else { $pagination = $request->per_page; } return SmartBlock::searchFilter($request) ->with(['creator', 'tracks', 'tracks.file', 'criteria']) ->paginate($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([ 'name' => $request->name, 'creator_id' => $user->id, 'description' => $request->description, 'length' => $length, ]); $this->saveCriteria($dbSmartBlock, $criteria); //ToDo: save content return $dbSmartBlock->with(['criteria', '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, Request $request) { if ($block_id === 0 && count($request->criteria) === 0) { throw new BadMethodCallException('If block_id is 0 criteria array must be passed as parameter'); } if ($block_id > 0) { $smartBlock = SmartBlock::whereId($block_id)->first(); $criteria = $smartBlock->criteria; } else { $criteria = new \Illuminate\Database\Eloquent\Collection(); foreach($request->criteria as $key => $criterion) { $criteria->push(new SmartBlockCriteria($criterion)); } $criteria->push(new SmartBlockCriteria([ 'criteria' => 'limit', 'modifier' => $request->limit['type'], 'value' => $request->limit['quantity'], ])); $criteria->push(new SmartBlockCriteria([ 'criteria' => 'repeat_tracks', 'modifier' => 'N/A', 'value' => intval($request->repeat_tracks), ])); $criteria->push(new SmartBlockCriteria([ 'criteria' => 'overflow_tracks', 'modifier' => 'N/A', 'value' => intval($request->overflow_tracks), ])); $criteria->push(new SmartBlockCriteria([ 'criteria' => 'sort', 'modifier' => 'N/A', 'value' => $request->sort ])); } //dd($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(round($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', ]); } }