* @owner University of Latvia * @version 2.0.0 * @since 25.07.2018 * * @package Lu\LuCourseCatalogue\Controller */ class CourseController extends ActionController { /** * Frontend-Session * * @var \Lu\LuStudyCatalogue\Domain\Session\FrontendSessionHandler */ protected $frontendSession; /** * Frontend- or Backend-Session * The type of session is set automatically in initializeAction(). * * @var \Lu\LuStudyCatalogue\Domain\Session\SessionHandler */ protected $session; /** * Main language array * * @var array */ private $language; /** * Uri Builder object * * @var \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder */ private $uri_builder; /** * Selected page number * * @var int */ private $currentPage; /** * Filter array * * @var array */ private $filter; /** * Study Course ID * * @var int */ private $courseId; /** * Study program ID * * @var int */ private $programId; /** * MusicController constructor. * * Assign page ID */ public function __construct() { parent::__construct(); // Disable cache in case of missing chash in URL $GLOBALS['TSFE']->set_no_cache(); // Set language data $languageAspect = GeneralUtility::makeInstance(Context::class)->getAspect('language'); $this->language = [ 'id' => $languageAspect->getId(), 'iso' => $GLOBALS['TSFE']->sys_language_isocode, 'code' => $GLOBALS['TSFE']->sys_language_isocode == 'lv' ? 'lat' : 'eng', ]; } /** * List Action * * @return void */ public function listAction() { // Pre-define variables $data = []; $request = $this->request->getArguments(); $this->uri_builder = $this->controllerContext->getUriBuilder()->setCreateAbsoluteUri(true)->reset(); // Get current page @FIXME There has to be a better way! $this->currentPage = !empty($request['@widget_0']['currentPage']) ? (int)$request['@widget_0']['currentPage'] : 1; // Add filter options if (!empty($request['filter'])) { $this->filter = $request['filter']; } else { $this->filter = []; } $this->view->assign('filter', $this->filter); // Advanced filters with additional values $advFilter = []; foreach ($this->filter as $key => $item) { if (!in_array($key, ['nosaukums_lat', 'nosaukums_eng'])) { $advFilter[] = [ 'id' => md5($key.'_'.$item), 'key' => $key, 'name' => $item, ]; } } $this->view->assign('advFilter',$advFilter); // Switch $studyType = @$this->settings['studyType']; switch ($studyType) { case 'course_catalogue': $data['solr'] = $this->listCourse(); break; case 'course_catalogue_continue': $data['solr'] = $this->listCourseContinue(); break; case 'program_catalogue': $data['solr'] = $this->listProgram(); break; case 'program_catalogue_continue': $data['solr'] = $this->listProgramContinue(); break; } // Add custom JS $this->renderJs(); // Assign frontend page ID $this->view->assign('pageId', $GLOBALS['TSFE']->id); // Assign language element to view $this->view->assign('language', $this->language); // Assign final data element to view $this->view->assign('data', $data); } /** * Get route list data * * @return array */ private function listCourse(): array { // Pre-set models and values $DataHelper = new DataHelper(); $luisStudyTypes = new LuisStudyTypes(); $luisStudyTypes->setFullReturn(true); $luisStudyTypes->setLimit(!empty($this->settings['list']['paginate']['itemsPerPage']) ? $this->settings['list']['paginate']['itemsPerPage'] : 10); $luisStudyTypes->setPage($this->currentPage); $luisStudyTypes->setLanguageCode($this->language['code']); $luisStudyTypes->setFilter($this->filter); $luisStudyTypes->setRequestType('courseCatalogue'); // Fetch data from API endpoint $jsonData = $luisStudyTypes->fetch(); $data = $DataHelper->APIDecode($jsonData); // Fix facets fields $facets = []; if ($data['success'] && !empty($data['data'])) { foreach ($data['data']['facet_fields'] as $facet_name => $facet_fields) { $filter = $this->filter; unset($filter[$facet_name]); $tmp = [ 'title' => str_replace("_".$this->language['code'], "", $facet_name), 'data' => [], 'inFilter' => !empty($this->filter[$facet_name]) ? $this->filter[$facet_name] : false, ]; for ($k = 0; $k < count($facet_fields); $k += 2) { $tmp['data'][] = [ 'id' => md5($facet_name.'_'.$facet_fields[$k]), 'name' => $facet_fields[$k], ]; } $facets[] = $tmp; } $data['data']['facet_fields'] = $facets; // Fix language params foreach ($data['data']['docs'] as &$item) { $item['url'] = $this->uri_builder->reset()->uriFor('detail', ['course' => $item['kods']]); } // Add paginate object $data['data']['paginate'] = []; for ($k = 0; $k < $data['data']['numFound']; $k++) { $data['data']['paginate'][] = $k; } return (array)$data['data']; } // Return empty array, if no data found return [ 'error' => $data['data'] ? true : false, $data['data'] ?? [], ]; } /** * Get route list data * * @return array */ private function listCourseContinue(): array { // Pre-set models and values $DataHelper = new DataHelper(); $luisStudyTypes = new LuisStudyTypes(); $luisStudyTypes->setFullReturn(true); $luisStudyTypes->setLimit(!empty($this->settings['list']['paginate']['itemsPerPage']) ? $this->settings['list']['paginate']['itemsPerPage'] : 10); $luisStudyTypes->setPage($this->currentPage); $luisStudyTypes->setLanguageCode($this->language['code']); $luisStudyTypes->setFilter($this->filter); $luisStudyTypes->setRequestType('courseCatalogueContinuing'); // Fetch data from API endpoint $jsonData = $luisStudyTypes->fetch(); $data = $DataHelper->APIDecode($jsonData); // Fix facets fields $facets = []; if ($data['success'] && !empty($data['data'])) { foreach ($data['data']['facet_fields'] as $facet_name => $facet_fields) { $filter = $this->filter; unset($filter[$facet_name]); $tmp = [ 'title' => str_replace("_".$this->language['code'], "", $facet_name), 'data' => [], 'inFilter' => !empty($this->filter[$facet_name]) ? $this->filter[$facet_name] : false, ]; for ($k = 0; $k < count($facet_fields); $k += 2) { $tmp['data'][] = [ 'id' => md5($facet_name.'_'.$facet_fields[$k]), 'name' => $facet_fields[$k], ]; } $facets[] = $tmp; } $data['data']['facet_fields'] = $facets; // Fix language params foreach ($data['data']['docs'] as &$item) { $item['url'] = $this->uri_builder->reset()->uriFor('detail', ['course' => $item['kods']]); } // Add paginate object $data['data']['paginate'] = []; for ($k = 0; $k < $data['data']['numFound']; $k++) { $data['data']['paginate'][] = $k; } return (array)$data['data']; } // Return empty array, if no data found return [ 'error' => $data['data'] ? true : false, $data['data'] ?? [], ]; } /** * Get route list data * * @return array */ private function listProgram(): array { // Pre-set models and values $DataHelper = new DataHelper(); $luisStudyTypes = new LuisStudyTypes(); $luisStudyTypes->setFullReturn(true); $luisStudyTypes->setLimit(!empty($this->settings['list']['paginate']['itemsPerPage']) ? $this->settings['list']['paginate']['itemsPerPage'] : 10); $luisStudyTypes->setPage($this->currentPage); $luisStudyTypes->setLanguageCode($this->language['code']); $luisStudyTypes->setFilter($this->filter); $luisStudyTypes->setRequestType('programmeCatalogue'); // Fetch data from API endpoint $jsonData = $luisStudyTypes->fetch(); $data = $DataHelper->APIDecode($jsonData); // Fix facets fields $facets = []; if ($data['success'] && !empty($data['data'])) { foreach ($data['data']['facet_fields'] as $facet_name => $facet_fields) { $filter = $this->filter; unset($filter[$facet_name]); $tmp = [ 'title' => str_replace("_".$this->language['code'], "", $facet_name), 'data' => [], 'inFilter' => !empty($this->filter[$facet_name]) ? $this->filter[$facet_name] : false, ]; for ($k = 0; $k < count($facet_fields); $k += 2) { $tmp['data'][] = [ 'id' => md5($facet_name.'_'.$facet_fields[$k]), 'name' => $facet_fields[$k], ]; } $facets[] = $tmp; } $data['data']['facet_fields'] = $facets; // Fix language params foreach ($data['data']['docs'] as &$item) { $item['url'] = $this->uri_builder->reset()->uriFor('detail', ['program' => $item['id']]); } // Add paginate object $data['data']['paginate'] = []; for ($k = 0; $k < $data['data']['numFound']; $k++) { $data['data']['paginate'][] = $k; } return (array)$data['data']; } // Return empty array, if no data found return [ 'error' => $data['data'] ? true : false, $data['data'] ?? [], ]; } /** * Get route list data * * @return array */ private function listProgramContinue(): array { // Pre-set models and values $DataHelper = new DataHelper(); $luisStudyTypes = new LuisStudyTypes(); $luisStudyTypes->setFullReturn(true); $luisStudyTypes->setLimit(!empty($this->settings['list']['paginate']['itemsPerPage']) ? $this->settings['list']['paginate']['itemsPerPage'] : 10); $luisStudyTypes->setPage($this->currentPage); $luisStudyTypes->setLanguageCode($this->language['code']); $luisStudyTypes->setFilter($this->filter); $luisStudyTypes->setRequestType('programmeCatalogueContinuing'); // Fetch data from API endpoint $jsonData = $luisStudyTypes->fetch(); $data = $DataHelper->APIDecode($jsonData); // Fix facets fields $facets = []; if ($data['success'] && !empty($data['data'])) { foreach ($data['data']['facet_fields'] as $facet_name => $facet_fields) { $filter = $this->filter; unset($filter[$facet_name]); $tmp = [ 'title' => str_replace("_".$this->language['code'], "", $facet_name), 'data' => [], 'inFilter' => !empty($this->filter[$facet_name]) ? $this->filter[$facet_name] : false, ]; for ($k = 0; $k < count($facet_fields); $k += 2) { $tmp['data'][] = [ 'id' => md5($facet_name.'_'.$facet_fields[$k]), 'name' => $facet_fields[$k], ]; } // Add current facet count, that has content foreach ($tmp['data'] as $item) { if ($item['count'] > 0) { $tmp['count']++; } } $facets[] = $tmp; } $data['data']['facet_fields'] = $facets; // Fix language params foreach ($data['data']['docs'] as &$item) { $item['url'] = $this->uri_builder->reset()->uriFor('detail', ['program' => $item['id']]); } // Add paginate object $data['data']['paginate'] = []; for ($k = 0; $k < $data['data']['numFound']; $k++) { $data['data']['paginate'][] = $k; } return (array)$data['data']; } // Return empty array, if no data found return [ 'error' => $data['data'] ? true : false, $data['data'] ?? [], ]; } /** * Course/program detail view */ public function detailAction() { // Pre-define variables $data = []; $this->uri_builder = $this->controllerContext->getUriBuilder()->setCreateAbsoluteUri(true)->reset(); // Set course_id $this->courseId = $this->request->hasArgument('course') ? $this->request->getArgument('course') : 0; $this->programId = $this->request->hasArgument('program') ? $this->request->getArgument('program') : 0; // Switch $studyType = @$this->settings['studyType']; switch ($studyType) { case 'course_catalogue': $data['studyUrlUd'] = $this->settings['catalogues']['courseCatalogueId'] ?? null; $data['programUrlUd'] = $this->settings['catalogues']['programmeCatalogueId'] ?? null; $data['solr'] = $this->detailCourse(); break; case 'program_catalogue': $data['studyUrlUd'] = $this->settings['catalogues']['courseCatalogueId'] ?? null; $data['programUrlUd'] = $this->settings['catalogues']['programmeCatalogueId'] ?? null; $data['solr'] = $this->detailProgram(); break; case 'course_catalogue_continue': $data['studyUrlUd'] = $this->settings['catalogues']['courseCatalogueContinuingId'] ?? null; $data['programUrlUd'] = $this->settings['catalogues']['programmeCatalogueContinuingId'] ?? null; $data['solr'] = $this->detailCourseContinue(); break; case 'program_catalogue_continue': $data['studyUrlUd'] = $this->settings['catalogues']['courseCatalogueContinuingId'] ?? null; $data['programUrlUd'] = $this->settings['catalogues']['programmeCatalogueContinuingId'] ?? null; $data['solr'] = $this->detailProgramContinue(); break; } // Make adjustments if (!empty($data) && !empty($data['solr'])) { foreach ($data['solr'] as $key => $item) { // Add fix for `ekursi` f*ckup if (!empty($item['ekursi'])) { $tmp = []; @eval('$tmp = '.$item['ekursi'].';'); $data['solr'][$key]['ekursi_fix'] = $tmp; } // Create `prog_nosauk` urls if (!empty($item['prog_nosauk'])) { $tmp = []; foreach ($item['prog_nosauk'] as $prog) { $tmpUri = $this->uri_builder->reset(); // Check if custom site specified if ($data['programUrlUd']) { $tmpUri->setTargetPageUid($data['programUrlUd']); } // This is strange, but hey, I didn't design it ¯\_(ツ)_/¯ list($prog_name, $prog_id) = explode("(*;,)", $prog); $tmp[] = [ 'name' => $prog_name, 'code' => $prog_id, 'url' => $tmpUri->uriFor('detail', ['program' => $prog_id]), ]; } $data['solr'][$key]['prog_nosauk_fix'] = $tmp; } // Add fix for `studforma_info` if (!empty($item['studforma_info'])) { $data['solr'][$key]['studforma_info_fix'] = $this->studFormEval($item['studforma_info']); } // Add fix for `studiju_plans` if (!empty($item['studiju_plans'])) { $tmp = []; @eval('$tmp = '.$item['studiju_plans'].';'); // Add link to all elements foreach ($tmp as &$course) { if (!empty($course['kursi'])) { $tmpUri = $this->uri_builder->reset(); if ($data['studyUrlUd']) { $tmpUri->setTargetPageUid($data['studyUrlUd']); } foreach ($course['kursi'] as &$cour) { $cour['url'] = $tmpUri->uriFor('detail', ['course' => $cour['kods']]); } } } $data['solr'][$key]['studiju_plans_fix'] = $tmp; } } } // Override page title if (!empty($data['solr'][0]['nosaukums'])) { $GLOBALS['LU-OVERRIDES']['MainTitle'] = $data['solr'][0]['nosaukums']; } // Add custom JS $this->renderJs(); // Assign frontend page ID $this->view->assign('pageId', $GLOBALS['TSFE']->id); // Assign language element to view $this->view->assign('language', $this->language); // Assign final data element to view $this->view->assign('data', $data); } /** * Get detailed info about a course * * @return array */ public function detailCourse() { // Pre-set models and values $DataHelper = new DataHelper(); $luisStudyTypes = new LuisStudyTypes(); $luisStudyTypes->setLanguageCode($this->language['code']); $luisStudyTypes->setCode($this->courseId); $luisStudyTypes->setRequestType('detailCourse'); // Fetch data from API endpoint $jsonData = $luisStudyTypes->fetch(); $data = $DataHelper->APIDecode($jsonData); // Return result return (array)$data; } /** * Get detailed info about a course * * @return array */ public function detailCourseContinue() { // Pre-set models and values $DataHelper = new DataHelper(); $luisStudyTypes = new LuisStudyTypes(); $luisStudyTypes->setLanguageCode($this->language['code']); $luisStudyTypes->setCode($this->courseId); $luisStudyTypes->setRequestType('detailCourseContinue'); // Fetch data from API endpoint $jsonData = $luisStudyTypes->fetch(); $data = $DataHelper->APIDecode($jsonData); // Return result return (array)$data; } /** * Get detailed info about a course * * @return array */ public function detailProgram() { // Pre-set models and values $DataHelper = new DataHelper(); $luisStudyTypes = new LuisStudyTypes(); $luisStudyTypes->setLanguageCode($this->language['code']); $luisStudyTypes->setCode($this->programId); $luisStudyTypes->setRequestType('detailProgram'); // Fetch data from API endpoint $jsonData = $luisStudyTypes->fetch(); $data = $DataHelper->APIDecode($jsonData); // Return result return (array)$data; } /** * Get detailed info about a course * * @return array */ public function detailProgramContinue() { // Pre-set models and values $DataHelper = new DataHelper(); $luisStudyTypes = new LuisStudyTypes(); $luisStudyTypes->setLanguageCode($this->language['code']); $luisStudyTypes->setCode($this->programId); $luisStudyTypes->setRequestType('detailProgramContinue'); // Fetch data from API endpoint $jsonData = $luisStudyTypes->fetch(); $data = $DataHelper->APIDecode($jsonData); // Return result return (array)$data; } /** * Adds our own custom js */ private function renderJs() { $pageRenderer = GeneralUtility::makeInstance(PageRenderer::class); // Add jQuery UI $pageRenderer->addCssFile("//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"); $pageRenderer->addJsFooterFile("//code.jquery.com/jquery-1.12.4.js"); $pageRenderer->addJsFooterFile("//code.jquery.com/ui/1.12.1/jquery-ui.js"); // Add own JS $pageRenderer->addJsFooterFile("/typo3conf/ext/lu_study_catalogue/Resources/Public/JavaScript/scripts.js"); } /** * Evaluates study form data * * @param $studforma_info * * @return array */ private function studFormEval($studforma_info) { $studyFormsEvaledArray = []; foreach ($studforma_info as $studiju_forma_info) { //in solr studforma_info is keeped in form of php array definition string, eval it if (!empty($studiju_forma_info)) { eval('$studiju_formu_info_arr ='.$studiju_forma_info.';'); } else { $studiju_formu_info_arr = []; } // Get year from if (empty($maxSemStudVietuInfo)) { $maxSemStudVietuInfo = $this->getYearAndSeasonFromSemester($studiju_formu_info_arr['vietu_semestris_'.$this->language['code']]); } else { $currentSemester = $this->getYearAndSeasonFromSemester($studiju_formu_info_arr['vietu_semestris_'.$this->language['code']]); if ($currentSemester['year'] > $maxSemStudVietuInfo['year']) { $maxSemStudVietuInfo = $currentSemester; } } if (empty($maxSemStudMaksaInfo)) { $maxSemStudMaksaInfo = $this->getYearAndSeasonFromSemester($studiju_formu_info_arr['stud_maksas_semestris_'.$this->language['code']]); } else { $currentSemester = $this->getYearAndSeasonFromSemester($studiju_formu_info_arr['stud_maksas_semestris_'.$this->language['code']]); if ($currentSemester['year'] > $maxSemStudMaksaInfo['year']) { $maxSemStudMaksaInfo = $currentSemester; } } // Add to array $studiju_formu_info_arr['maxSemStudVietuInfo'] = $maxSemStudVietuInfo; $studiju_formu_info_arr['maxSemStudMaksaInfo'] = $maxSemStudMaksaInfo; $studiju_formu_info_arr['studFeeSemYear'] = $maxSemStudVietuInfo['year']; $studiju_formu_info_arr['studFeeSemSeason'] = $maxSemStudVietuInfo['season']; // Rename fields $studiju_formu_info_arr['nos'] = $studiju_formu_info_arr['nos_'.$this->language['code']]; $studiju_formu_info_arr['vietu_semestris'] = $studiju_formu_info_arr['vietu_semestris_'.$this->language['code']]; $studiju_formu_info_arr['stud_maksas_semestris'] = $studiju_formu_info_arr['stud_maksas_semestris_'.$this->language['code']]; $studiju_formu_info_arr['stud_organizacija'] = $studiju_formu_info_arr['stud_organizacija_'.$this->language['code']]; $studiju_formu_info_arr['uznems_sem_1'] = trim($studiju_formu_info_arr['uznems_sem_1_'.$this->language['code']]); $studiju_formu_info_arr['uznems_sem_2'] = trim($studiju_formu_info_arr['uznems_sem_2_'.$this->language['code']]); // Assign values $studyFormsEvaledArray[] = $studiju_formu_info_arr; } return $studyFormsEvaledArray; } /** * Recieves year and season from semester data * * @param $semester * * @return array */ private function getYearAndSeasonFromSemester($semester) { $yearAndSeason = explode('.', $semester); if ((int)trim($yearAndSeason[0]) == 0) { $yearAndSeason = explode(' ', $semester); if ((int)trim($yearAndSeason[1]) != 0) { $yearAndSeason['year'] = (int)trim($yearAndSeason[1]); $yearAndSeason['season'] = trim($yearAndSeason[0]); } } else { $yearAndSeason['year'] = (int)trim($yearAndSeason[0]); $yearAndSeason['season'] = trim($yearAndSeason[1]); } unset($yearAndSeason[0]); unset($yearAndSeason[1]); return $yearAndSeason; } }