File: D:/HostingSpaces/SBogers10/ste.komma.pro/app/Trainings/TrainingService.php
<?php
namespace App\Trainings;
use App\Base\Service;
use App\Console\Commands\GetTrainingsFromC4;
use App\Locations\Models\Location;
use App\SteLanguages\Models\SteLanguage;
use App\Trainings\Resources\Training;
use App\Types\TrainingFilter;
use App\Types\TrainingFilterOption;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
final class TrainingService extends Service
{
/**
* Get the Trainings from the cache
* Possible trigger the Artisan command if cache is empty (should be impossible)
*
* @param bool $isCallback
* @return mixed
*/
private function getTrainingsFromCache($isCallback = false)
{
if( Cache::has('trainings') ) {
return Cache::get('trainings');
}
// On the second run of this function we crash
if($isCallback) throw new \BadMethodCallException(self::class.': Something wrong with the C4 import. Because training do not get filled into the cache.');
/** @var GetTrainingsFromC4 $loadFromC4Command */
$loadFromC4Command = app(GetTrainingsFromC4::class);
$loadFromC4Command->handle(false);
return $this->getTrainingsFromCache(true);
}
/**
* Get the amount of upcoming trainings
*
* @param int $amount
* @return mixed
*/
public function getUpcomingTrainings(int $amount = null)
{
$trainings = $this->getTrainingsFromCache()
->sortBy('start_date');
if(isset($amount)) return $trainings->take($amount);
return $trainings;
}
public function getTrainingForFilters(array $filters)
{
$trainings = $this->getTrainingsFromCache();
foreach ($filters as $key => $value)
{
switch ($key) {
case 'levels':
$trainings = $trainings->whereIn('filterable_level', $value);
continue 2;
case 'type':
$trainings = $trainings->whereIn('training_type', $value);
continue 2;
case 'amountOfWeeks':
$trainings = $trainings->whereIn('amount_of_weeks', $value);
continue 2;
case 'eachWeek':
$trainings = $trainings->whereIn('lessons_each_week', $value);
continue 2;
case 'locations':
$trainings = $trainings->whereIn('location_id', $value);
continue 2;
case 'languages':
$trainings = $trainings->where('language_id', $value);
continue 2;
}
}
return $trainings;
}
/**
* @param string $c4Id
* @return Training|null
*/
public function getTrainingByC4Id(string $c4Id): ?Training
{
$c4Training = $this->getTrainingsFromCache()
->where('c4_id', $c4Id)
->first();
if(!$c4Training) abort(404);
// Try to find training in kms
$kmsTraining = \App\Trainings\Models\Training::where('c4_id', $c4Id)
->with('translation')
->first();
if($kmsTraining) $c4Training->translation = $kmsTraining->translation;
return $c4Training;
}
/**
* Make filters out of the Training related attributes
*
* @return Collection
*/
public function getFilters(): Collection
{
$filters = collect();
$trainings = $this->getTrainingsFromCache();
$counters = [];
$loadedLanguages = [];
$steLanguages = collect();
$locations = collect();
foreach ($trainings as $training)
{
if(!isset($counters[$training->training_type])) $counters[$training->training_type] = 1;
else $counters[$training->training_type]++;
if(!isset($loadedLanguages[$training->api_response->taal_code])) $loadedLanguages[$training->api_response->taal_code] = 1;
else $loadedLanguages[$training->api_response->taal_code]++;
if($steLanguages->where('id', $training->language->id)->count() == 0) $steLanguages->push($training->language);
if($locations->where('id', $training->location->id)->count() == 0) $locations->push($training->location);
}
debug($counters);
debug($loadedLanguages);
// Languages
$languageFilter = new TrainingFilter('languages', __('site/trainings.filters.language'), TrainingFilter::FILTER_TYPE_SELECT);
$languageFilterOption = new TrainingFilterOption(__('site/trainings.all_languages'), 0);
$languageFilter->addOption($languageFilterOption);
foreach ($steLanguages as $steLanguage) {
$languageFilterOption = new TrainingFilterOption($steLanguage->translation->name, $steLanguage->id);
$languageFilter->addOption($languageFilterOption);;
}
$filters->push($languageFilter);
// Locations
$locationFilter = new TrainingFilter('locations', __('site/trainings.filters.location'));
$locationFilter->setIcon('pin-icon');
foreach ($locations as $location) {
if($location->id === Location::ONLINE_ID) $locationFilterOption = new TrainingFilterOption($location->name, $location->id);
else $locationFilterOption = new TrainingFilterOption($location->name . ', ' . $location->city , $location->id);
$locationFilter->addOption($locationFilterOption);;
}
$filters->push($locationFilter);
// Levels
$levelFilter = new TrainingFilter('levels', __('site/trainings.filters.level'), TrainingFilter::FILTER_TYPE_LEVEL);
foreach (Training::$filterLevels as $level) $levelFilter->addOption(new TrainingFilterOption($level, $level));
$levelFilter->addExtraData('groupNames', [
'a' => __('site/trainings.levelNames.a'),
'b' => __('site/trainings.levelNames.b'),
'c' => __('site/trainings.levelNames.c'),
]);
$filters->push($levelFilter);
// Type
$typeFilter = new TrainingFilter('type', __('site/trainings.filters.type'));
$uniqueTrainingTypes = $trainings->unique('training_type')->sortBy('training_type')->pluck('training_type')->toArray();
foreach (config('c4.preferred_type_order') as $c4Type) {
if(!in_array($c4Type, $uniqueTrainingTypes)) continue;
if(app('translator')->has('site/trainings.c4.' . $c4Type, null, false)) $label = app('translator')->get('site/trainings.c4.' . $c4Type, [], null, false);
else $label = $c4Type;
$typeFilter->addOption(new TrainingFilterOption($label, $c4Type));
}
$uniqueTrainingTypes = array_diff($uniqueTrainingTypes, config('c4.preferred_type_order'));
foreach ($uniqueTrainingTypes as $type) {
if(empty($type)) continue; // Skip the 'None'
if(app('translator')->has('site/trainings.c4.' . $type, null, false)) $label = app('translator')->get('site/trainings.c4.' . $type, [], null, false);
else $label = $type;
$typeFilter->addOption(new TrainingFilterOption($label, $type));
}
$filters->push($typeFilter);
// Day
// $dayFilter = new TrainingFilter('days', __('site/trainings.filters.day'));
// for ($d = 1; $d <= 7; $d++) $dayFilter->addOption(new TrainingFilterOption( strtoupper(__('calendar.day_names_min.' . $d)), $d));
// $filters->push($dayFilter);
// Amount of weeks
// $amountOfWeeksFilter = new TrainingFilter('amountOfWeeks', __('site/trainings.filters.amount_of_weeks'));
// $uniqueAmountOfWeeks = $trainings->unique('amount_of_weeks')->sortBy('amount_of_weeks')->pluck('amount_of_weeks');
// foreach ($uniqueAmountOfWeeks as $amountOfWeeksOption) $amountOfWeeksFilter->addOption(new TrainingFilterOption($amountOfWeeksOption . ' ' . __('calendar.weeks'), $amountOfWeeksOption));
// $filters->push($amountOfWeeksFilter);
// // Trainings each week
// $trainingsEachWeekFilter = new TrainingFilter('eachWeek', __('site/trainings.filters.each_week'));
// $uniqueTrainingsEachWeek = $trainings->unique('lessons_each_week')->sortBy('lessons_each_week')->pluck('lessons_each_week');
// foreach ($uniqueTrainingsEachWeek as $trainingsEachWeek) {
// (app()->getLocale() == 'nl') ? $label = $trainingsEachWeek : $label = __('site/trainings.c4.' . $trainingsEachWeek);
// $trainingsEachWeekFilter->addOption(new TrainingFilterOption($label, $trainingsEachWeek));
// }
// $filters->push($trainingsEachWeekFilter);
return $filters;
}
/**
* Get training or make if not present in the database
*
* @param SteLanguage $language
* @param string $level
* @return Training
*/
public function firstOrNew(SteLanguage $language, string $level): Training
{
$training = Training::where('ste_language_id', $language->id)
->where('level', $level)
->with('translations', 'steLanguage')
->first();
if( isset($training) && $training->translations->count() < sizeof(config('languages.available')) ) {
\Log::warning('C4 import: Not all translations are filled in for the Training "' . strtoupper($language->iso_2) . ' | '. $level . '". We should notify the project owner to contact STE about filling all the translations for this KMS Training.');
}
if(!isset($training)) {
\Log::warning('C4 import: Training not found for language "' . $language->iso_2 . '" and level "'. $level . '". We have created a training, but we should notify the project owner to contact STE about filling the KMS Training for this fresh created training.');
$training = Training::create([
'ste_language_id' => $language->id,
'level' => $level
]);
}
return $training;
}
}