From acc0c2bd7a536c0c34bf3b2022ab7abf8641130a Mon Sep 17 00:00:00 2001 From: BelsethUwU Date: Tue, 21 Nov 2023 21:25:49 +0100 Subject: [PATCH 1/2] Feat:large adjustment'nd verification on adminside --- .../ControllerAdminAdministrators.php | 67 ++++-- .../controllers/ControllerAdminChapters.php | 137 ++++++----- .../controllers/ControllerAdminQuestions.php | 215 +++++++++++------- Website/gateways/GatewayChapter.php | 15 +- Website/models/ModelAdministrator.php | 10 +- Website/models/ModelAnswer.php | 14 +- Website/models/ModelChapter.php | 32 ++- Website/models/ModelQuestion.php | 24 +- Website/templates/addquestions.twig | 6 +- Website/templates/adminAdministrators.twig | 5 +- .../templates/adminAdministratorsModal.twig | 7 +- Website/templates/adminChapters.twig | 3 +- Website/templates/adminChaptersModal.twig | 6 +- Website/templates/adminQuestions.twig | 5 +- Website/templates/adminQuestionsModal.twig | 6 +- Website/templates/error.twig | 4 +- Website/templates/home.twig | 4 +- Website/templates/lobby.twig | 2 +- Website/templates/loginAdmin.twig | 4 +- Website/templates/loginPlayer.twig | 4 +- Website/templates/multiplayer.twig | 4 +- Website/templates/singleplayer.twig | 4 +- Website/templates/themeChoice.twig | 4 +- Website/templates/userPlayerModal.twig | 6 +- Website/templates/userStatus.twig | 4 +- Website/templates/viewScore.twig | 4 +- 26 files changed, 368 insertions(+), 228 deletions(-) diff --git a/Website/controllers/ControllerAdminAdministrators.php b/Website/controllers/ControllerAdminAdministrators.php index 6c0ed8b..ce19cdf 100644 --- a/Website/controllers/ControllerAdminAdministrators.php +++ b/Website/controllers/ControllerAdminAdministrators.php @@ -51,21 +51,24 @@ class ControllerAdminAdministrators function add($param) { if ($_SERVER['REQUEST_METHOD'] !== 'POST') { - $_SESSION["error"]="Méthode non autorisée."; + $_SESSION["error"] = "Méthode non autorisée."; + header("Location:/admin/administrators"); } else { $username = $_POST['username']; $password = $_POST['password']; $username = trim($_POST['username']); $password = trim($_POST['password']); if (!isset($username) || !isset($password) || empty($username) || empty($password)) { - $_SESSION["error"]="Veuillez remplir tous les champs."; + $_SESSION["error"] = "Veuillez remplir tous les champs."; + header("Location:/admin/administrators"); } else { $Admin = [ 'username' => $username, 'password' => $password, ]; if ($this->mdAdministrator->verifyAdministratorByName($Admin) != null) { - $_SESSION["error"]="Cet admin existe déjà."; + $_SESSION["error"] = "Cet admin existe déjà."; + header("Location:/admin/administrators"); } else { $this->mdAdministrator->addAdministrator($Admin); header("Location:/admin/administrators"); @@ -76,28 +79,48 @@ class ControllerAdminAdministrators function updatemodal($param) { - - $administrator = $this->mdAdministrator->getAdministratorByID($param["id"]); - - echo $this->twig->render($this->vues["adminAdministratorsModal"], [ - 'administrator' => $administrator, - ]); + if ($_SERVER['REQUEST_METHOD'] !== 'GET') { + $_SESSION["error"] = "Méthode non autorisée."; + header("Location:/admin/administrators"); + } else { + $administrator = $this->mdAdministrator->getAdministratorByID($param["id"]) ?? null; + if ($administrator == null) { + $_SESSION["error"] = "Cet admin n'existe pas."; + header("Location:/admin/administrators"); + } else { + echo $this->twig->render($this->vues["adminAdministratorsModal"], [ + 'administrator' => $administrator, + ]); + } + } } function update($param) { - - $id = $_POST['id']; - $username = $_POST['username']; - $password = $_POST['password']; - - $Admin = [ - 'username' => $username, - 'password' => $password, - ]; - - $this->mdAdministrator->updateAdministrator($id, $Admin); - - header("Location:/admin/administrators"); + if ($_SERVER['REQUEST_METHOD'] !== 'POST') { + $_SESSION["error"] = "Méthode non autorisée."; + header("Location:/admin/administrators"); + } else { + $id = $_POST['id']; + $username = $_POST['username']; + $password = $_POST['password']; + $username = trim($_POST['username']); + $password = trim($_POST['password']); + if (!isset($username) || !isset($password) || empty($username) || empty($password)) { + $_SESSION["error"] = "Veuillez remplir tous les champs."; + header("Location:/admin/administrators"); + } else { + $Admin = [ + 'username' => $username, + 'password' => $password, + ]; + if ($this->mdAdministrator->verifyAdministratorByName($Admin) != null) { + $_SESSION["error"] = "Cet admin existe déjà."; + } else { + $this->mdAdministrator->updateAdministrator($id, $Admin); + header("Location:/admin/administrators"); + } + } + } } } diff --git a/Website/controllers/ControllerAdminChapters.php b/Website/controllers/ControllerAdminChapters.php index 5786909..e239d18 100644 --- a/Website/controllers/ControllerAdminChapters.php +++ b/Website/controllers/ControllerAdminChapters.php @@ -15,69 +15,100 @@ class ControllerAdminChapters function __construct() { - global $vues, $twig; - session_start(); - try { - if($_SESSION["idAdminConnected"] != null){ - $this->twig =$twig; - $this->vues = $vues; - - $this->mdChapter = new ModelChapter(); - - $chapters = $this->mdChapter->getChapters(); - - echo $twig->render($vues["adminChapters"], [ - 'chapters' => $chapters, - ]); - } - else { - header("Location:/loginAdmin"); - } - } catch (PDOException $e) { - // Gérez les erreurs PDO ici - } catch (Exception $e2) { - // Gérez d'autres erreurs ici + global $vues, $twig; + session_start(); + try { + if ($_SESSION["idAdminConnected"] != null) { + $this->twig = $twig; + $this->vues = $vues; + + $this->mdChapter = new ModelChapter(); + + $chapters = $this->mdChapter->getChapters(); + + echo $twig->render($vues["adminChapters"], [ + 'chapters' => $chapters, + 'error' => $_SESSION["error"], + ]); + $_SESSION["error"] = null; + } else { + header("Location:/loginAdmin"); } + } catch (PDOException $e) { + // Gérez les erreurs PDO ici + } catch (Exception $e2) { + // Gérez d'autres erreurs ici + } } - function delete($param) { + function delete($param) + { $this->mdChapter->deleteChapter($param["id"]); header("Location:/admin/chapters"); } - function add($param) { - - $name = $_POST['name']; - - $Chapter = [ - 'name' => $name, - ]; - - $this->mdChapter->addChapter($Chapter); - - header("Location:/admin/chapters"); + function add($param) + { + $trimmedName = trim($_POST['name']); + if (isset($_POST['name']) && !empty($_POST['name']) && !empty($trimmedName)) { + $name = $_POST['name']; + $Chapter = [ + 'name' => $name, + ]; + $this->mdChapter->addChapter($Chapter); + header("Location:/admin/chapters"); + } else { + $_SESSION["error"] = "Veuillez remplir le champ"; + header("Location:/admin/chapters"); + return; + } } - function updatemodal($param) { - - $chapter = $this->mdChapter->getChapterByID($param["id"]); - - echo $this->twig->render($this->vues["adminChaptersModal"], [ - 'chapter' => $chapter, - ]); + function updatemodal($param) + { + if ($_SERVER['REQUEST_METHOD'] !== 'GET') { + $_SESSION["error"] = "Méthode non autorisée."; + header("Location:/admin/chapters"); + } else { + $chapter = $this->mdChapter->getChapterByID($param["id"]) ?? null; + if ($chapter == null) { + $_SESSION["error"] = "Chapitre introuvable."; + header("Location:/admin/chapters"); + } else { + echo $this->twig->render($this->vues["adminChaptersModal"], [ + 'chapter' => $chapter, + ]); + } + } } - function update($param) { - - $id = $_POST['id']; - $name = $_POST['name']; - - $Chapter = [ - 'name' => $name, - ]; - - $this->mdChapter->updateChapter($id,$Chapter); - - header("Location:/admin/chapters"); + function update($param) + { + var_dump($_SESSION["error"]); + if ($_SERVER['REQUEST_METHOD'] !== 'POST') { + $_SESSION["error"] = "Méthode non autorisée."; + header("Location:/admin/chapters"); + } else { + $id = $_POST['id']; + $name = $_POST['name']; + $trimmedName = trim($_POST['name']); + if (!isset($name) || empty($name) || empty($trimmedName)) { + $_SESSION["error"] = "Veuillez remplir le champ."; + header("Location:/admin/chapters"); + } else { + $chapter = $this->mdChapter->verifyChapterByName($name) ?? null; + if ($chapter != null) { + $_SESSION["error"] = "Ce chapitre existe déjà."; + header("Location:/admin/chapters"); + } else { + $Chapter = [ + 'name' => $name, + ]; + + $this->mdChapter->updateChapter($id, $Chapter); + header("Location:/admin/chapters"); + } + } + } } } diff --git a/Website/controllers/ControllerAdminQuestions.php b/Website/controllers/ControllerAdminQuestions.php index 0b76197..888ac8b 100644 --- a/Website/controllers/ControllerAdminQuestions.php +++ b/Website/controllers/ControllerAdminQuestions.php @@ -36,7 +36,9 @@ class ControllerAdminQuestions echo $twig->render($vues["adminQuestions"], [ 'questions' => $questions, 'chapters' => $chapters, + 'error' => $_SESSION["error"], ]); + $_SESSION["error"] = null; } else { header("Location:/loginAdmin"); } @@ -55,106 +57,147 @@ class ControllerAdminQuestions function add($param) { - $content = $_POST['content']; - $idChapter = intval($_POST['idChapter']); - $AnswersPost = array(); - $AnswersPost[0] = $_POST['answer1']; - $AnswersPost[1] = $_POST['answer2']; - $AnswersPost[2] = $_POST['answer3']; - $AnswersPost[3] = $_POST['answer4']; - $correctAnswer = intval($_POST['correctAnswer']); - - $Question = [ - 'content' => $content, - 'idchapter' => $idChapter, - 'idanswergood' => $correctAnswer, - 'difficulty' => 1, - 'nbfails' => 0, - ]; - - $idquestion = intval($this->mdQuestion->addQuestion($Question)); - - for ($i = 0; $i <= 3; $i++) { - $Answers[] = [ - 'content' => $AnswersPost[$i], - 'idquestion' => $idquestion, - ]; - } - - - $answersId = array(); - for ($i = 0; $i <= 3; $i++) { - $answersId[$i] = $this->mdAnswer->addAnswer($Answers[$i]); + if ($_SERVER['REQUEST_METHOD'] !== 'POST') { + $_SESSION["error"] = "Méthode non autorisée."; + header("Location:/admin/questions"); + } else { + $trimmedContent = trim($_POST['content']); + $trimmedAnswer1 = trim($_POST['answer1']); + $trimmedAnswer2 = trim($_POST['answer2']); + $trimmedAnswer3 = trim($_POST['answer3']); + $trimmedAnswer4 = trim($_POST['answer4']); + if ( + isset($_POST['content']) && !empty($_POST['content']) && !empty($trimmedContent) + && isset($_POST['answer1']) && !empty($_POST['answer1']) && !empty($trimmedAnswer1) + && isset($_POST['answer2']) && !empty($_POST['answer2']) && !empty($trimmedAnswer2) + && isset($_POST['answer3']) && !empty($_POST['answer3']) && !empty($trimmedAnswer3) + && isset($_POST['answer4']) && !empty($_POST['answer4']) && !empty($trimmedAnswer4) + ) { + $content = $_POST['content']; + $idChapter = intval($_POST['idChapter']); + $AnswersPost = array(); + $AnswersPost[0] = $_POST['answer1']; + $AnswersPost[1] = $_POST['answer2']; + $AnswersPost[2] = $_POST['answer3']; + $AnswersPost[3] = $_POST['answer4']; + $correctAnswer = intval($_POST['correctAnswer']); + + $Question = [ + 'content' => $content, + 'idchapter' => $idChapter, + 'idanswergood' => $correctAnswer, + 'difficulty' => 1, + 'nbfails' => 0, + ]; + + $idquestion = intval($this->mdQuestion->addQuestion($Question)); + + for ($i = 0; $i <= 3; $i++) { + $Answers[] = [ + 'content' => $AnswersPost[$i], + 'idquestion' => $idquestion, + ]; + } + + $answersId = array(); + for ($i = 0; $i <= 3; $i++) { + $answersId[$i] = $this->mdAnswer->addAnswer($Answers[$i]); + } + + $Question = [ + 'content' => $content, + 'idchapter' => $idChapter, + 'difficulty' => 1, + 'nbfails' => 0, + 'idanswergood' => $answersId[$correctAnswer], + ]; + + $this->mdQuestion->updateQuestion($idquestion, $Question); + + header("Location:/admin/questions"); + } else { + $_SESSION["error"] = "Veuillez remplir tous les champs"; + header("Location:/admin/questions"); + } } - - $Question = [ - 'content' => $content, - 'idchapter' => $idChapter, - 'difficulty' => 1, - 'nbfails' => 0, - 'idanswergood' => $answersId[$correctAnswer], - ]; - - $this->mdQuestion->updateQuestion($idquestion, $Question); - - header("Location:/admin/questions"); } function updatemodal($param) { - $question = $this->mdQuestion->getQuestionByID($param["id"]); - $answers = $this->mdAnswer->getAnswersByIDQuestions($param["id"]); + $question = $this->mdQuestion->getQuestionByID($param["id"]) ?? null; + + $answers = $this->mdAnswer->getAnswersByIDQuestions($param["id"]) ?? null; + + $chapters = $this->mdChapter->getChapters() ?? null; - $chapters = $this->mdChapter->getChapters(); + if ($question == null || $answers == null || $chapters == null) { + $_SESSION["error"] = "Erreur lors de la récupération des données"; + header("Location:/admin/questions"); + } else { - echo $this->twig->render($this->vues["adminQuestionsModal"], [ - 'question' => $question, - 'chapters' => $chapters, - 'answers' => $answers, - ]); + echo $this->twig->render($this->vues["adminQuestionsModal"], [ + 'question' => $question, + 'chapters' => $chapters, + 'answers' => $answers, + ]); + } } function update($param) { - - $id = intval($_POST['id']); - $content = $_POST['content']; - $idChapter = intval($_POST['idChapter']); - $correctAnswer = intval($_POST['correctAnswer']); - - $answersId = array(); - $answersId[0] = intval($_POST['IdAnswer1']); - $answersId[1] = intval($_POST['IdAnswer2']); - $answersId[2] = intval($_POST['IdAnswer3']); - $answersId[3] = intval($_POST['IdAnswer4']); - - $answers = array(); - $answers[0] = $_POST['answer1']; - $answers[1] = $_POST['answer2']; - $answers[2] = $_POST['answer3']; - $answers[3] = $_POST['answer4']; - - - $questionDataArray = [ - 'content' => $content, - 'idchapter' => $idChapter, - 'idanswergood' => $answersId[$correctAnswer], - ]; - - $this->mdQuestion->updateQuestion($id, $questionDataArray); - - for ($i = 0; $i <= 3; $i++) { - $answersDataArray[] = [ - 'content' => $answers[$i], - 'id' => $id, + if ( + isset($_POST['content'], $_POST['answer1'], $_POST['answer2'], $_POST['answer3'], $_POST['answer4'], $_POST['idChapter'], $_POST['correctAnswer']) && + !empty($_POST['content']) && !empty(trim($_POST['content'])) && + !empty($_POST['answer1']) && !empty(trim($_POST['answer1'])) && + !empty($_POST['answer2']) && !empty(trim($_POST['answer2'])) && + !empty($_POST['answer3']) && !empty(trim($_POST['answer3'])) && + !empty($_POST['answer4']) && !empty(trim($_POST['answer4'])) && + !empty($_POST['idChapter']) && + is_numeric($_POST['correctAnswer']) && $_POST['correctAnswer'] >= 0 && $_POST['correctAnswer'] <= 3 + ) { + $id = intval($_POST['id']); + $content = $_POST['content']; + $idChapter = intval($_POST['idChapter']); + $correctAnswer = intval($_POST['correctAnswer']); + + $answersId = array(); + $answersId[0] = intval($_POST['IdAnswer1']); + $answersId[1] = intval($_POST['IdAnswer2']); + $answersId[2] = intval($_POST['IdAnswer3']); + $answersId[3] = intval($_POST['IdAnswer4']); + + $answers = array(); + $answers[0] = $_POST['answer1']; + $answers[1] = $_POST['answer2']; + $answers[2] = $_POST['answer3']; + $answers[3] = $_POST['answer4']; + + + $questionDataArray = [ + 'content' => $content, + 'idchapter' => $idChapter, + 'idanswergood' => $answersId[$correctAnswer], ]; - } - for ($i = 0; $i <= 3; $i++) { - $this->mdAnswer->updateAnswer($answersId[$i], $answersDataArray[$i]); - } + $this->mdQuestion->updateQuestion($id, $questionDataArray); - header("Location:/admin/questions"); + for ($i = 0; $i <= 3; $i++) { + $answersDataArray[] = [ + 'content' => $answers[$i], + 'id' => $id, + ]; + } + + for ($i = 0; $i <= 3; $i++) { + $this->mdAnswer->updateAnswer($answersId[$i], $answersDataArray[$i]); + } + + header("Location:/admin/questions"); + + } else { + $_SESSION["error"] = "Veuillez remplir tous les champs"; + header("Location:/admin/questions"); + } } } \ No newline at end of file diff --git a/Website/gateways/GatewayChapter.php b/Website/gateways/GatewayChapter.php index 0e88e38..6863871 100755 --- a/Website/gateways/GatewayChapter.php +++ b/Website/gateways/GatewayChapter.php @@ -62,7 +62,7 @@ class GatewayChapter $this->con->executeQuery($query, array(':id' => array($id, PDO::PARAM_INT))); } - public function verifyChapter($id) + public function verifyChapterByID($id) { $query = "SELECT chapters.id FROM chapters WHERE id = :id;"; $this->con->executeQuery( @@ -74,4 +74,17 @@ class GatewayChapter $results = $this->con->getResults(); return $results[0]; } + public function verifyChapterByName($name) + { + $query = "SELECT * FROM chapters WHERE name = :name;"; + $this->con->executeQuery( + $query, + array( + ':name' => array($name, PDO::PARAM_STR) + ) + ); + $results = $this->con->getResults(); + + return $results[0]; + } } diff --git a/Website/models/ModelAdministrator.php b/Website/models/ModelAdministrator.php index b0e2051..a4110e0 100644 --- a/Website/models/ModelAdministrator.php +++ b/Website/models/ModelAdministrator.php @@ -22,8 +22,12 @@ class ModelAdministrator public function getAdministratorByID($id) { $administratorDataArray = $this->gwAdministrator->getAdministratorByID($id); - $administrator = new Administrator($administratorDataArray["id"],$administratorDataArray["username"], $administratorDataArray["password"]); - return $administrator; + if ($administratorDataArray == null) { + return null; + } else { + $administrator = new Administrator($administratorDataArray["id"], $administratorDataArray["username"], $administratorDataArray["password"]); + return $administrator; + } } public function getAdministrators() @@ -31,7 +35,7 @@ class ModelAdministrator $administratorsDataArray = $this->gwAdministrator->getAdministrators(); $administrators = array(); foreach ($administratorsDataArray as $administratorDataArray) { - $administrator = new Administrator($administratorDataArray["id"],$administratorDataArray["username"], $administratorDataArray["password"]); + $administrator = new Administrator($administratorDataArray["id"], $administratorDataArray["username"], $administratorDataArray["password"]); $administrators[] = $administrator; } return $administrators; diff --git a/Website/models/ModelAnswer.php b/Website/models/ModelAnswer.php index 3d7f159..62bdf8f 100644 --- a/Website/models/ModelAnswer.php +++ b/Website/models/ModelAnswer.php @@ -30,12 +30,16 @@ class ModelAnswer function getAnswersByIDQuestions($idQuestion) { $answersDataArray = $this->gwAnswer->getAnswersByIDQuestions($idQuestion); - $answers = array(); - foreach ($answersDataArray as $answerDataArray) { - $answer = new Answer($answerDataArray['id'], $answerDataArray['content'], $idQuestion); - $answers[] = $answer; + if ($answersDataArray == null) { + return null; + } else { + $answers = array(); + foreach ($answersDataArray as $answerDataArray) { + $answer = new Answer($answerDataArray['id'], $answerDataArray['content'], $idQuestion); + $answers[] = $answer; + } + return $answers; } - return $answers; } function updateAnswer($answersId, $answer) diff --git a/Website/models/ModelChapter.php b/Website/models/ModelChapter.php index 5e7f100..716314e 100644 --- a/Website/models/ModelChapter.php +++ b/Website/models/ModelChapter.php @@ -17,12 +17,16 @@ class ModelChapter function getChapters() { $chaptersDataArray = $this->gwChapter->getChapters(); - $chapters = array(); - foreach ($chaptersDataArray as $chapterDataArray) { - $chapter = new Chapter($chapterDataArray['id'],$chapterDataArray["name"]); - $chapters[] = $chapter; + if ($chaptersDataArray == null) { + return null; + } else { + $chapters = array(); + foreach ($chaptersDataArray as $chapterDataArray) { + $chapter = new Chapter($chapterDataArray['id'], $chapterDataArray["name"]); + $chapters[] = $chapter; + } + return $chapters; } - return $chapters; } function deleteChapter($id) @@ -38,8 +42,12 @@ class ModelChapter function getChapterByID($id) { $chapterDataArray = $this->gwChapter->getChapterByID($id); - $chapter = new Chapter($chapterDataArray['id'],$chapterDataArray['name']); - return $chapter; + if ($chapterDataArray == null) { + return null; + } else { + $chapter = new Chapter($chapterDataArray['id'], $chapterDataArray['name']); + return $chapter; + } } function updateChapter($id, $chapter) @@ -48,7 +56,15 @@ class ModelChapter } public function verifyChapter($chapter) { - $id = $this->gwChapter->verifyChapter($chapter); + $id = $this->gwChapter->verifyChapterByID($chapter); + return $id; + } + public function verifyChapterByName($name) + { + $id = $this->gwChapter->verifyChapterByName($name); + if ($id == null) { + return null; + } return $id; } } diff --git a/Website/models/ModelQuestion.php b/Website/models/ModelQuestion.php index 447462a..94b2d27 100644 --- a/Website/models/ModelQuestion.php +++ b/Website/models/ModelQuestion.php @@ -15,7 +15,7 @@ class ModelQuestion $this->gwQuestion = new GatewayQuestion(); } - function getQuestions() : array + function getQuestions(): array { $questionsDataArray = $this->gwQuestion->getQuestions(); $questions = array(); @@ -50,15 +50,19 @@ class ModelQuestion function getQuestionByID($id) { $questionDataArray = $this->gwQuestion->getQuestionByID($id); - $question = new Question( - intval($questionDataArray['id']), - $questionDataArray['content'], - intval($questionDataArray['idchapter']), - intval($questionDataArray['idanswergood']), - intval($questionDataArray['difficulty']), - intval($questionDataArray['nbfails']) - ); - return $question; + if ($questionDataArray == null) { + return null; + } else { + $question = new Question( + intval($questionDataArray['id']), + $questionDataArray['content'], + intval($questionDataArray['idchapter']), + intval($questionDataArray['idanswergood']), + intval($questionDataArray['difficulty']), + intval($questionDataArray['nbfails']) + ); + return $question; + } } function updateQuestion($id, $questionDataArray) diff --git a/Website/templates/addquestions.twig b/Website/templates/addquestions.twig index 10dcc28..75392c3 100644 --- a/Website/templates/addquestions.twig +++ b/Website/templates/addquestions.twig @@ -2,14 +2,14 @@ - + Math'Educ - + - +
diff --git a/Website/templates/adminAdministrators.twig b/Website/templates/adminAdministrators.twig index a982a62..43adc4f 100644 --- a/Website/templates/adminAdministrators.twig +++ b/Website/templates/adminAdministrators.twig @@ -1,7 +1,7 @@ - Maths'Educ + Math'Educ @@ -15,7 +15,8 @@
-

Liste des administrators

+

Liste des administrators

+

{{ error }}

    {% for admin in administrators %}
  • diff --git a/Website/templates/adminAdministratorsModal.twig b/Website/templates/adminAdministratorsModal.twig index bfa0d29..f419f8e 100644 --- a/Website/templates/adminAdministratorsModal.twig +++ b/Website/templates/adminAdministratorsModal.twig @@ -1,15 +1,14 @@ - Maths'Educ + Math'Educ - - + - +