entityTypeManager = $entityTypeManager; $this->entity_query = $entity_query; $connection = Database::getConnection(); $this->connection = $connection; $language = \Drupal::languageManager()->getCurrentLanguage()->getId(); $this->language = $language; $currentuser = \Drupal::currentUser()->id(); $this->currentuser = $currentuser; $this->logger = $loggerChannel->get('epal'); } public static function create(ContainerInterface $container) { return new static( $container->get('entity_type.manager'), $container->get('entity.query'), $container->get('database'), $container->get('logger.factory') ); } public function createDistribution(Request $request) { $numDistributions = 3; $sizeOfBlock = 1000000; // POST method is checked if (!$request->isMethod('POST')) { return $this->respondWithStatus([ "message" => t("Method Not Allowed") ], Response::HTTP_METHOD_NOT_ALLOWED); } // user validation $authToken = $request->headers->get('PHP_AUTH_USER'); $users = $this->entityTypeManager->getStorage('user')->loadByProperties(array('name' => $authToken)); $user = reset($users); if (!$user) { return $this->respondWithStatus([ 'message' => t("User not found"), ], Response::HTTP_FORBIDDEN); } // user role validation if (false === in_array('ministry', $user->getRoles())) { return $this->respondWithStatus([ 'message' => t("User Invalid Role"), ], Response::HTTP_FORBIDDEN); } // check where distribution can be done now ($capacityDisabled / $directorViewDisabled settings) $config_storage = $this->entityTypeManager->getStorage('epal_config'); $epalConfigs = $config_storage->loadByProperties(array('id' => 1)); $epalConfig = reset($epalConfigs); if (!$epalConfig) { return $this->respondWithStatus([ 'message' => t("EpalConfig Enity not found"), ], Response::HTTP_FORBIDDEN); } else { $capacityDisabled = $epalConfig->lock_school_capacity->getString(); $directorViewDisabled = $epalConfig->lock_school_students_view->getString(); $applicantsResultsDisabled = $epalConfig->lock_results->getString(); if ($capacityDisabled !== "1" || $directorViewDisabled !== "1" || $applicantsResultsDisabled !== "1") { return $this->respondWithStatus([ 'message' => t("capacityDisabled and / or directorViewDisabled settings are false"), ], Response::HTTP_FORBIDDEN); } } $transaction = $this->connection->startTransaction(); try { // initialize/empty epal_student_class if there are already data in it! if ($this->initializeResults() === self::ERROR_DB) { $transaction->rollback(); return $this->respondWithStatus([ "message" => t("Unexpected Error in initializeResults function") ], Response::HTTP_INTERNAL_SERVER_ERROR); } if (($limitUp_class = $this->retrieveCapacityLimitUp("1")) === self::ERROR_DB) { $transaction->rollback(); return $this->respondWithStatus([ "message" => t("Unexpected Error in retrieveCapacityLimitUp function") ], Response::HTTP_INTERNAL_SERVER_ERROR); } // print_r("
ΑΝΩΤΑΤΟ ΟΡΙΟ ΜΑΘΗΤΩΝ: " . $limitUp_class); while ($this->choice_id <= $numDistributions) { if ($this->choice_id === 1) { // υπολογισμός πλήθους για να καθοριστεί ο αριθμός των fetches που θα κάνουμε με συγκεκριμένο sizeOfBlock $sCon = $this->connection->select('epal_student', 'eStudent') ->fields('eStudent', array('id')); $numData = $sCon->countQuery()->execute()->fetchField(); //print_r("
numData: " . $numData); $num = 1; $j = 1; while ($num <= $numData) { //print_r("
FETCH: " . $j); $sCon = $this->connection->select('epal_student', 'eStudent') ->fields('eStudent', array('id', 'currentclass', 'currentepal', 'second_period')) ->condition('eStudent.id', 1 + $sizeOfBlock * ($j-1), '>=') ->condition('eStudent.id', $j * $sizeOfBlock, '<='); $epalStudents = $sCon->execute()->fetchAll(\PDO::FETCH_OBJ); if ($this->locateStudent($this->choice_id, $epalStudents) === self::ERROR_DB) { $transaction->rollback(); return $this->respondWithStatus([ "message" => t("Unexpected Error in locateStudent function") ], Response::HTTP_INTERNAL_SERVER_ERROR); } $num = $num + sizeof($epalStudents); $j = $j + 1; } } else { // $this->choice_id !== 1 if (sizeof($this->pendingStudents) != 0) { $sCon = $this->connection->select('epal_student', 'eStudent') ->fields('eStudent', array('id', 'currentclass', 'currentepal', 'second_period')) ->condition('eStudent.id', $this->pendingStudents, 'IN'); $epalStudents = $sCon->execute()->fetchAll(\PDO::FETCH_OBJ); if ($this->locateStudent($this->choice_id, $epalStudents) === self::ERROR_DB) { $transaction->rollback(); return $this->respondWithStatus([ "message" => t("Unexpected Error in locateStudent function") ], Response::HTTP_INTERNAL_SERVER_ERROR); } } else { // αν δεν υπάρχουν εκκρεμότητες, μην συνεχίζεις με άλλο πέρασμα break; } } // Για κάθε σχολείο βρες τα τμήματα // Για κάθε τμήμα βρες αν χωράνε και διευθέτησε (checkCapacityAndArrange) // checkCapacityAndArrange (school_id, class_id, sectorORcourse_id, limitUp, schoolCapacity) $sCon = $this->connection->select('eepal_school_field_data', 'eSchool') ->fields('eSchool', array('id', 'capacity_class_a', 'operation_shift')); $eepalSchools = $sCon->execute()->fetchAll(\PDO::FETCH_OBJ); foreach ($eepalSchools as $eepalSchool) { if ($this->checkCapacityAndArrange($eepalSchool->id, "1", "-1", $limitUp_class, $eepalSchool->capacity_class_a) === self::ERROR_DB) { $transaction->rollback(); return $this->respondWithStatus([ "message" => t("Unexpected Error in checkCapacityAndArrange function") ], Response::HTTP_INTERNAL_SERVER_ERROR); } $sCon = $this->connection->select('eepal_sectors_in_epal_field_data', 'eSchool') ->fields('eSchool', array('epal_id', 'sector_id', 'capacity_class_sector')) ->condition('eSchool.epal_id', $eepalSchool->id, '='); $eepalSectorsInEpal = $sCon->execute()->fetchAll(\PDO::FETCH_OBJ); foreach ($eepalSectorsInEpal as $eepalSecInEp) { if ($this->checkCapacityAndArrange($eepalSchool->id, "2", $eepalSecInEp->sector_id, $limitUp_class, $eepalSecInEp->capacity_class_sector) === self::ERROR_DB) { $transaction->rollback(); return $this->respondWithStatus([ "message" => t("Unexpected Error in checkCapacityAndArrange function") ], Response::HTTP_INTERNAL_SERVER_ERROR); } } $sCon = $this->connection->select('eepal_specialties_in_epal_field_data', 'eSchool') ->fields('eSchool', array('epal_id', 'specialty_id', 'capacity_class_specialty')) ->condition('eSchool.epal_id', $eepalSchool->id, '='); $eepalSpecialtiesInEpal = $sCon->execute()->fetchAll(\PDO::FETCH_OBJ); foreach ($eepalSpecialtiesInEpal as $eepalSpecialInEp) { //Γ' Λυκείου if ($this->checkCapacityAndArrange($eepalSchool->id, "3", $eepalSpecialInEp->specialty_id, $limitUp_class, $eepalSpecialInEp->capacity_class_specialty) === self::ERROR_DB) { $transaction->rollback(); return $this->respondWithStatus([ "message" => t("Unexpected Error in checkCapacityAndArrange function") ], Response::HTTP_INTERNAL_SERVER_ERROR); } //Δ' Λυκείου if ($eepalSchool->operation_shift === "ΕΣΠΕΡΙΝΟ") { if ($this->checkCapacityAndArrange($eepalSchool->id, "4", $eepalSpecialInEp->specialty_id, $limitUp_class, $eepalSpecialInEp->capacity_class_specialty) === self::ERROR_DB) { $transaction->rollback(); return $this->respondWithStatus([ "message" => t("Unexpected Error in checkCapacityAndArrange function") ], Response::HTTP_INTERNAL_SERVER_ERROR); } } } } //end for each school/department $this->choice_id++; } //end while if ($this->findSmallClasses() === self::ERROR_DB) { $transaction->rollback(); return $this->respondWithStatus([ "message" => t("Unexpected Error in findSmallClasses function AFTER initial Distribution!") ], Response::HTTP_INTERNAL_SERVER_ERROR); // αν αποτύχει, δεν γίνεται rollback. --> Λύση: διαγραφή των όποιων αποτελεσμάτων // if ($this->initializeResults() === self::ERROR_DB) { // return $this->respondWithStatus([ // "message" => t("Unexpected Error in initializeResults function AFTER findSmallClasses call Function") // ], Response::HTTP_INTERNAL_SERVER_ERROR); // } } } catch (\Exception $e) { $this->logger->warning($e->getMessage()); $transaction->rollback(); return $this->respondWithStatus([ "message" => t("An unexpected problem occured in createDistribution Method") ], Response::HTTP_INTERNAL_SERVER_ERROR); } return $this->respondWithStatus([ 'message' => "Distribution has made successfully", ], Response::HTTP_OK); } public function locateStudent($choice_id, &$epalStudents) { $epal_dist_id = -1; $specialization_id = -1; try { foreach ($epalStudents as $epalStudent) { //print_r("
ΚΑΤΑΝΟΜΗ ΜΑΘΗΤΩΝ ΝΟ: " . $choice_id); //print_r("
ΜΑΘΗΤΗΣ: " . $epalStudent->id); $clCon = $this->connection->select('epal_student_epal_chosen', 'epals') ->fields('epals', array('student_id', 'epal_id', 'choice_no')) ->condition('epals.student_id', $epalStudent->id, '=') ->condition('epals.choice_no', $choice_id, '='); $epalSchoolsChosen = $clCon->execute()->fetchAll(\PDO::FETCH_OBJ); if (sizeof($epalSchoolsChosen) !== 0) { $epalSchoolChos = reset($epalSchoolsChosen); //print_r(" SCHOOL_ID:" . $epalSchoolChos->epal_id . " STUDENT_ID " . $epalStudent->id); $epal_dist_id = $epalSchoolChos->epal_id; if ($epalStudent->currentclass === "2") { $clCon = $this->connection->select('epal_student_sector_field', 'sectors') ->fields('sectors', array('student_id', 'sectorfield_id')) ->condition('sectors.student_id', $epalStudent->id, '='); $epalSectorChosen = $clCon->execute()->fetchAll(\PDO::FETCH_OBJ); $epalSecChos = reset($epalSectorChosen); } //Δ'Λυκείου - Γ' Λυκείου elseif ($epalStudent->currentclass === "3" || $epalStudent->currentclass === "4") { $clCon = $this->connection->select('epal_student_course_field', 'courses') ->fields('courses', array('student_id', 'coursefield_id')) ->condition('courses.student_id', $epalStudent->id, '='); $epalCourseChosen = $clCon->execute()->fetchAll(\PDO::FETCH_OBJ); $epalCourChos = reset($epalCourseChosen); } if ($epalStudent->currentclass === "2") { $specialization_id = $epalSecChos->sectorfield_id; } //Δ'Λυκείου - Γ' Λυκείου elseif ($epalStudent->currentclass === "3" || $epalStudent->currentclass === "4") { $specialization_id = $epalCourChos->coursefield_id; } else { $specialization_id = -1; } $timestamp = strtotime(date("Y-m-d")); $this->connection->insert('epal_student_class')->fields( array( 'id' => $this->globalCounterId++, 'uuid' => \Drupal::service('uuid')->generate(), 'langcode' => $this->language, 'user_id' => $this->currentuser, 'student_id'=> $epalStudent->id, 'epal_id'=> $epal_dist_id, 'currentclass' => $epalStudent->currentclass, 'currentepal' => $epalStudent->currentepal, 'specialization_id' => $specialization_id, //'points' => $epalStudent->points, 'distribution_id' => $choice_id, 'finalized' => 1, 'second_period' => $epalStudent->second_period, 'status' => 1, 'created' => $timestamp, 'changed' => $timestamp ) )->execute(); } //end if } //foreach } catch (\Exception $e) { $this->logger->warning($e->getMessage()); return self::ERROR_DB; } return self::SUCCESS; } public function retrieveCapacityLimitUp($className) { try { $clCon = $this->connection->select('epal_class_limits', 'classLimits') ->fields('classLimits', array('limit_up')) ->condition('classLimits.name', $className, '='); $results = $clCon->execute()->fetchAll(\PDO::FETCH_OBJ); $row = reset($results); } catch (\Exception $e) { $this->logger->warning($e->getMessage()); return self::ERROR_DB; } return $row->limit_up; } public function checkCapacityAndArrange($epalId, $classId, $secCourId, $limitup, $capacity) { if (!isset($capacity)) { //print_r("
ΜΠΗΚΑ!!! "); //print_r("
ΣΧΟΛΕΙΟ: " . $epalId . " ΤΑΞΗ: " . $classId . " ΤΟΜΕΑΣ/ΕΙΔΙΚΟΤΗΤΑ: " . $secCourId . " ΧΩΡΗΤΙΚΟΤΗΤΑ: " . $capacity); $capacity = 0; } try { $clCon = $this->connection->select('epal_student_class', 'studentClass') ->fields('studentClass', array('epal_id', 'student_id', 'points', 'currentepal', 'currentclass', 'specialization_id')) ->condition('studentClass.epal_id', $epalId, '=') ->condition('studentClass.currentclass', $classId, '=') ->condition('studentClass.specialization_id', $secCourId, '='); $epalStudentClass = $clCon->execute()->fetchAll(\PDO::FETCH_OBJ); $limit = $limitup * $capacity; if (sizeof($epalStudentClass) > $limit) { //print_r("
ΥΠΕΡΧΕΙΛΙΣΗ!"); //foreach ($epalStudentClass as $epalStudCl) { //Υπολογισμός μορίων του μαθητή και (πιθανή) αποθήκευσή τους //ΣΗΜΕΙΩΣΗ: Ο υπoλογισμός γίνεται στο front-end //} $this->makeSelectionOfStudents($epalStudentClass, $limit); } else { //αφαίρεσε όσους μαθητές βρίσκονται στον πίνακα εκκρεμοτήτων foreach ($epalStudentClass as $epalStudCl) { if ($this->choice_id !== 1) { ////διέγραψε τον μαθητή από τον πίνακα εκκρεμοτήτων (αν βρίσκεται εκεί) $this->removeFromPendingStudents($epalStudCl->student_id); } } } } // end try catch (\Exception $e) { $this->logger->warning($e->getMessage()); return self::ERROR_DB; } return self::SUCCESS; } public function removeFromPendingStudents($val) { if (($key = array_search($val, $this->pendingStudents)) !== false) { unset($this->pendingStudents[$key]); } //$this->pendingStudents = array_diff($this->pendingStudents, array($val)); } public function makeSelectionOfStudents_VERSION_WITH_POINTS(&$students, $limit) { //συνάρτηση επιλογής μαθητών σε περίπτωση υπερχείλισης // (1) έχουν απόλυτη προτεραιότητα όσοι ήδη φοιτούσαν στο σχολείο (σε περίπτωση που φοιτούσαν περισσότεροι από την χωρητικότητα, τους δεχόμαστε όλους) // (2) αν απομένουν κενές θέσεις, επέλεξε από τους εναπομείναντες μαθητές αυτούς με τα περισσότερα μόρια. Σε περίπτωση ισοβαθμίας δεχόμαστε όλους όσους ισοβαθμούν. foreach ($students as $student) { $student->student_id; //print_r("
STUDENT_ID:" . $student->student_id); } //εύρεση αριθμού μαθητών που ήδη φοιτούσαν στο σχολείο $cnt = 0; foreach ($students as $student) { if ($student->currentepal === $student->epal_id) { $cnt++; if ($this->choice_id !== 1) { ////διέγραψε τον μαθητή από τον πίνακα εκκρεμοτήτων (αν βρίσκεται εκεί) $this->removeFromPendingStudents($student->student_id); } } } //print_r("
#ΕΓΓΡΑΦΩΝ ΠΟΥ ΟΙ ΜΑΘΗΤΕΣ ΦΟΙΤΟΥΣΑΝ ΗΔΗ:" . $cnt); $newlimit = $limit - $cnt; //print_r("
ΑΝΩΤΑΤΟ ΟΡΙΟ ΜΑΘΗΤΩΝ:" . $limit); //print_r("
#ΜΑΘΗΤΩΝ ΓΙΑ ΝΑ ΕΠΙΛΕΓΟΥΝ ΜΕ ΜΟΡΙΑ:" . $newlimit); $points_arr = []; foreach ($students as $student) { if ($student->currentepal !== $student->epal_id) { $points_arr[] = $student->points; } } rsort($points_arr); //for ($i=0; $i < sizeof($points_arr); $i++) //print_r("
ΜΟΡΙΑ ΜΕΤΑ ΤΗΝ ΤΑΞΙΝΟΜΙΣΗ: " . $points_arr[$i]); //print_r("
ΟΡΙΟ ΜΟΡΙΩΝ: " . $points_arr[$newlimit-1]); $transaction = $this->connection->startTransaction(); foreach ($students as $student) { if ($student->currentepal !== $student->epal_id) { if ($student->points < $points_arr[$newlimit-1]) { //print_r("
ΣΕ ΕΚΚΡΕΜΟΤΗΤΑ - ΔΙΑΓΡΑΦΗ: " . $student->student_id); //βάλε τον μαθητή στον πίνακα εκκρεμοτήτων και διέγραψέ τον από τον προσωρινό πίνακα αποτελεσμάτων array_push($this->pendingStudents, $student->student_id); try { $this->connection->delete('epal_student_class') ->condition('student_id', $student->student_id) ->execute(); } catch (\Exception $e) { $this->logger->warning($e->getMessage()); $transaction->rollback(); return $this->respondWithStatus([ "message" => t("An unexpected problem occured during DELETE proccess in makeSelectionOfStudents Method of Distribution") ], Response::HTTP_INTERNAL_SERVER_ERROR); } } else { if ($this->choice_id !== 1) { //διέγραψε τον μαθητή από τον πίνακα εκκρεμοτήτων (αν βρίσκεται εκεί) $this->removeFromPendingStudents($student->student_id); } } } } return $this->respondWithStatus([ "message" => t("makeSelectionOfStudents Method of Distribution has made successfully") ], Response::HTTP_OK); } public function makeSelectionOfStudents(&$students, $limit) { // συνάρτηση επιλογής μαθητών σε περίπτωση υπερχείλισης // (1) έχουν απόλυτη προτεραιότητα όσοι ήδη φοιτούσαν στο σχολείο (σε περίπτωση που φοιτούσαν περισσότεροι από την χωρητικότητα, τους δεχόμαστε όλους) // (2) αν απομένουν κενές θέσεις,...τοποθέτησε και όλους τους άλλους!!. //αν capacity = 0, ..διέγραψέ τους από εκεί που τοποθετήθηκαν προσωρινά if ($limit === 0) { foreach ($students as $student) { array_push($this->pendingStudents, $student->student_id); try { $this->connection->delete('epal_student_class') ->condition('student_id', $student->student_id) ->execute(); } catch (\Exception $e) { $this->logger->warning($e->getMessage()); return self::ERROR_DB; } } return self::SUCCESS; } // εύρεση αριθμού μαθητών που ήδη φοιτούσαν στο σχολείο $cnt = 0; foreach ($students as $student) { if ($student->currentepal === $student->epal_id) { $cnt++; if ($this->choice_id !== 1) { // διέγραψε τον μαθητή από τον πίνακα εκκρεμοτήτων (αν βρίσκεται εκεί) // Κάτι τέτοιο δεν είναι δυνατό πια! (έκδοση χωρίς μόρια..) $this->removeFromPendingStudents($student->student_id); } } } //print_r("
#ΕΓΓΡΑΦΩΝ ΠΟΥ ΟΙ ΜΑΘΗΤΕΣ ΦΟΙΤΟΥΣΑΝ ΗΔΗ:" . $cnt); $newlimit = $limit - $cnt; //print_r("
ΑΝΩΤΑΤΟ ΟΡΙΟ ΜΑΘΗΤΩΝ:" . $limit); //Αν δεν απέμειναν θέσεις (δηλαδή αν η χωρητικότητα είναι μικρότερη ή ίση από το πλήθος μαθητών που ήδη φοιτούν στο σχολείο) //τότε διέγραψέ τους από τον προσωρινό πίνακα αποτελεσμάτων και βάλε τους στον στον πίνακα εκκρεμοτήτων foreach ($students as $student) { if ($student->currentepal !== $student->epal_id) { if ($newlimit <= 0) { //print_r("
ΣΕ ΕΚΚΡΕΜΟΤΗΤΑ - ΔΙΑΓΡΑΦΗ: " . $student->student_id); array_push($this->pendingStudents, $student->student_id); try { $this->connection->delete('epal_student_class') ->condition('student_id', $student->student_id) ->execute(); } catch (\Exception $e) { $this->logger->warning($e->getMessage()); return self::ERROR_DB; } } // endif new limit else { // $newlimit > 0 if ($this->choice_id !== 1) { $this->removeFromPendingStudents($student->student_id); } } } // endif currentepal } // end foreach return self::SUCCESS; } private function respondWithStatus($arr, $s) { $res = new JsonResponse($arr); $res->setStatusCode($s); return $res; } private function initializeResults() { //initialize/empty epal_student_class if there are already data in it! try { $this->connection->delete('epal_student_class')->execute(); } catch (\Exception $e) { $this->logger->warning($e->getMessage()); return self::ERROR_DB; } return self::SUCCESS; } private function findSmallClasses() { //Για κάθε σχολείο βρες τα ολιγομελή τμήματα $sCon = $this->connection->select('eepal_school_field_data', 'eSchool') ->fields('eSchool', array('id', 'metathesis_region','operation_shift')); $eepalSchools = $sCon->execute()->fetchAll(\PDO::FETCH_OBJ); foreach ($eepalSchools as $eepalSchool) { //isSmallClass (school_id, class_id, sectorORcourse_id, school_category_metathesis) // Α' τάξη if ($this->isSmallClass($eepalSchool->id, "1", "-1", $eepalSchool->metathesis_region) === self::SMALL_CLASS) { //print_r("
ΚΛΗΣΗ markStudentsInSmallClass: SCHOOL_ID: " . $eepalSchool->id . " CLASSID: " . "1 " . "SECTOR/COURSE ID: " . "-1 "); if ($this->markStudentsInSmallClass($eepalSchool->id, "1", "-1") === self::ERROR_DB) { return self::ERROR_DB; } } // Β' τάξη $sCon = $this->connection->select('eepal_sectors_in_epal_field_data', 'eSchool') ->fields('eSchool', array('epal_id', 'sector_id')) ->condition('eSchool.epal_id', $eepalSchool->id, '='); $eepalSectorsInEpal = $sCon->execute()->fetchAll(\PDO::FETCH_OBJ); foreach ($eepalSectorsInEpal as $eepalSecInEp) { if ($this->isSmallClass($eepalSchool->id, "2", $eepalSecInEp->sector_id, $eepalSchool->metathesis_region) === self::SMALL_CLASS) { if ($this->markStudentsInSmallClass($eepalSchool->id, "2", $eepalSecInEp->sector_id) === self::ERROR_DB) { return self::ERROR_DB; } } } // Γ' τάξη $sCon = $this->connection->select('eepal_specialties_in_epal_field_data', 'eSchool') ->fields('eSchool', array('epal_id', 'specialty_id')) ->condition('eSchool.epal_id', $eepalSchool->id, '='); $eepalSpecialtiesInEpal = $sCon->execute()->fetchAll(\PDO::FETCH_OBJ); foreach ($eepalSpecialtiesInEpal as $eepalSpecialInEp) { if ($this->isSmallClass($eepalSchool->id, "3", $eepalSpecialInEp->specialty_id, $eepalSchool->metathesis_region) === self::SMALL_CLASS) { if ($this->markStudentsInSmallClass($eepalSchool->id, "3", $eepalSpecialInEp->specialty_id) === self::ERROR_DB) { return self::ERROR_DB; } } } // Δ' τάξη if ($eepalSchool->operation_shift === "ΕΣΠΕΡΙΝΟ") { $sCon = $this->connection->select('eepal_specialties_in_epal_field_data', 'eSchool') ->fields('eSchool', array('epal_id', 'specialty_id')) ->condition('eSchool.epal_id', $eepalSchool->id, '='); $eepalSpecialtiesInEpal = $sCon->execute()->fetchAll(\PDO::FETCH_OBJ); foreach ($eepalSpecialtiesInEpal as $eepalSpecialInEp) { if ($this->isSmallClass($eepalSchool->id, "4", $eepalSpecialInEp->specialty_id, $eepalSchool->metathesis_region) === self::SMALL_CLASS) { if ($this->markStudentsInSmallClass($eepalSchool->id, "4", $eepalSpecialInEp->specialty_id) === self::ERROR_DB) { return self::ERROR_DB; } } } } //end if ΕΣΠΕΡΙΝΟ } //end for each school/department return self::SUCCESS; } //end function private function isSmallClass($schoolId, $classId, $sectorOrcourseId, $regionId) { $limitDown = $this->retrieveLimitDown($classId, $regionId); if ($limitDown === self::NO_CLASS_LIMIT_DOWN) { return self::NO_CLASS_LIMIT_DOWN; } elseif ($limitDown === self::ERROR_DB) { return self::ERROR_DB; } $numStudents = $this->countStudents($schoolId, $classId, $sectorOrcourseId); if ($numStudents === self::ERROR_DB) { return self::ERROR_DB; } //Αν $numStudents == 0, γύρισε false, ώστε να μη γίνει περιττή κλήση στην markStudentsInSmallClass if (($numStudents < $limitDown) && ($numStudents > 0)) { return self::SMALL_CLASS; } else { return self::NON_SMALL_CLASS; } } private function retrieveLimitDown($classId, $regionId) { try { $sCon = $this->connection->select('epal_class_limits', 'eClassLimit') ->fields('eClassLimit', array('limit_down')) ->condition('eClassLimit.name', $classId, '=') ->condition('eClassLimit.category', $regionId, '='); $classLimits = $sCon->execute()->fetchAll(\PDO::FETCH_OBJ); if (sizeof($classLimits) === 1) { $classLimit = reset($classLimits); return $classLimit->limit_down; } else { return self::NO_CLASS_LIMIT_DOWN; } } //end try catch (\Exception $e) { $this->logger->warning($e->getMessage()); return self::ERROR_DB; } } //end function private function countStudents($schoolId, $classId, $sectorOrcourseId) { try { $sCon = $this->connection->select('epal_student_class', 'eStudent') ->fields('eStudent', array('id')) ->condition('eStudent.epal_id', $schoolId, '=') ->condition('eStudent.currentclass', $classId, '=') ->condition('eStudent.specialization_id', $sectorOrcourseId, '='); return $sCon->countQuery()->execute()->fetchField(); } catch (\Exception $e) { $this->logger->warning($e->getMessage()); return self::ERROR_DB; } } private function markStudentsInSmallClass($schoolId, $classId, $sectorOrcourseId) { try { $query = $this->connection->update('epal_student_class'); $query->fields(['finalized' => 0]); $query->condition('epal_id', $schoolId); $query->condition('currentclass', $classId); if ($sectorOrcourseId !== "-1") { $query->condition('specialization_id', $sectorOrcourseId); } $query->execute(); } catch (\Exception $e) { $this->logger->warning($e->getMessage()); return self::ERROR_DB; } return self::SUCCESS; } public function locateSecondPeriodStudents(Request $request) { //POST method is checked if (!$request->isMethod('POST')) { return $this->respondWithStatus([ "message" => t("Method Not Allowed") ], Response::HTTP_METHOD_NOT_ALLOWED); } //user validation $authToken = $request->headers->get('PHP_AUTH_USER'); $users = $this->entityTypeManager->getStorage('user')->loadByProperties(array('name' => $authToken)); $user = reset($users); if (!$user) { return $this->respondWithStatus([ 'message' => t("User not found"), ], Response::HTTP_FORBIDDEN); } //user role validation if (false === in_array('ministry', $user->getRoles())) { return $this->respondWithStatus([ 'message' => t("User Invalid Role"), ], Response::HTTP_FORBIDDEN); } //check where distribution can be done now $secondPeriodEnabled = "0"; $config_storage = $this->entityTypeManager->getStorage('epal_config'); $epalConfigs = $config_storage->loadByProperties(array('id' => 1)); $epalConfig = reset($epalConfigs); if (!$epalConfig) { return $this->respondWithStatus([ 'message' => t("EpalConfig Enity not found"), ], Response::HTTP_FORBIDDEN); } else { $secondPeriodEnabled = $epalConfig->activate_second_period->getString(); } if ($secondPeriodEnabled === "0") { return $this->respondWithStatus([ 'message' => t("secondPeriodEnabled setting is false"), ], Response::HTTP_FORBIDDEN); } $transaction = $this->connection->startTransaction(); try { if ($this->initializeResultsInSecondPeriod() === self::ERROR_DB) { $transaction->rollback(); return $this->respondWithStatus([ "message" => t("Unexpected Error in initializeResultsInSecondPeriod function") ], Response::HTTP_INTERNAL_SERVER_ERROR); } $sCon = $this->connection->select('epal_student', 'eStudent') ->fields('eStudent', array('id', 'currentclass', 'currentepal', 'second_period')) ->condition('eStudent.second_period', 1, '='); $epalStudents = $sCon->execute()->fetchAll(\PDO::FETCH_OBJ); //τοποθέτηση όλων των μαθητών Β' περιόδου στην πρώτη τους προτίμηση' $this->globalCounterId = $this->retrieveLastStudentId() + 1; if ($this->locateStudent(1, $epalStudents) === self::ERROR_DB) { $transaction->rollback(); return $this->respondWithStatus([ "message" => t("Unexpected Error in locateStudent function after calling locateSecondPeriodStudents method"), "numOfDeletions" => $num ], Response::HTTP_INTERNAL_SERVER_ERROR); } //επαναϋπολογισμός όλων των ολιγομελών τμημάτων (Προσοχή: αφορά ΟΛΟΥΣ τους μαθητές - κανονικής και Β΄ περιόδου) //αρχικοποίηση flag finalize σε 1 για όλους if ($this->setFinalize() === self::ERROR_DB) { $transaction->rollback(); return $this->respondWithStatus([ "message" => t("Unexpected Error in setFinalize function AFTER locateSecondPeriodStudents!") ], Response::HTTP_INTERNAL_SERVER_ERROR); } //εύρεση ολιγομελών και καταχώρηση μαθητών σε αυτά με κατάλληλη ένδειξη (finalize=0) if ($this->findSmallClasses() === self::ERROR_DB) { //αν αποτύχει, δεν γίνεται rollback. --> Λύση: διαγρα΄φή των όποιων αποτελεσμάτων // if ($this->initializeResultsInSecondPeriod() === self::ERROR_DB) { // $transaction->rollback(); // return $this->respondWithStatus([ // "message" => t("Unexpected Error in initializeResults function AFTER findSmallClasses call Function") // ], Response::HTTP_INTERNAL_SERVER_ERROR); // } $transaction->rollback(); return $this->respondWithStatus([ "message" => t("Unexpected Error in findSmallClasses function AFTER locateSecondPeriodStudents!") ], Response::HTTP_INTERNAL_SERVER_ERROR); } } catch (\Exception $e) { $this->logger->warning($e->getMessage()); $transaction->rollback(); return $this->respondWithStatus([ "message" => t("An unexpected problem occured in locateSecondPeriodStudents Method") ], Response::HTTP_INTERNAL_SERVER_ERROR); } return $this->respondWithStatus([ 'message' => "locateSecondPeriodStudents has made successfully", ], Response::HTTP_OK); } private function setFinalize() { try { $query = $this->connection->update('epal_student_class'); $query->fields([ 'finalized' => 1, ]); $query->execute(); } catch (\Exception $e) { $this->logger->warning($e->getMessage()); return self::ERROR_DB; } return self::SUCCESS; } private function initializeResultsInSecondPeriod() { //initialize/empty epal_student_class if there are already data in it! try { //$this->connection->delete('epal_student_class')->execute(); $con = $this->connection->prepare("delete from epal_student_class where second_period = 1 "); $con->execute(); //$num = $con->rowCount(); } catch (\Exception $e) { $this->logger->warning($e->getMessage()); return self::ERROR_DB; } return self::SUCCESS; } private function retrieveLastStudentId() { $sCon = $this->connection->select('epal_student', 'eStudent') ->fields('eStudent', array('id')); $sCon->orderBy('eStudent.id', 'desc'); $epalStudents = $sCon->execute()->fetchAll(\PDO::FETCH_OBJ); if ($epalStudents) { $epalStrudent = reset($epalStudents); return $epalStrudent->id; } return 0; } }