Skip to content

Commit

Permalink
Initial implementation of QuestionHandler
Browse files Browse the repository at this point in the history
QuestionHandler used to help figure out which question to ask next to the user when a student is filling out their profile.
  • Loading branch information
Jacob committed Mar 21, 2018
1 parent 59242a0 commit 1a2a094
Show file tree
Hide file tree
Showing 4 changed files with 195 additions and 9 deletions.
180 changes: 180 additions & 0 deletions classes/QuestionHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
<?php
/**
* Created by PhpStorm.
* User: Jacob
* Date: 3/20/2018
* Time: 8:51 PM
*/

class QuestionHandler
{
/**
* Returns the most recently answered question from a user which could also be answered again based on
* question dependencies.
*
* @param Student $student
* @return Question
*/
public static function getCurrentQuestion(Student $student)
{
$aq = $student->getAnsweredQuestions();
if (!is_null($aq) and count($aq) > 0) {
$answered = array_reverse(array_map(function ($o) {
$o->getQuestion();
}, $aq));
foreach ($answered as $item) {
if (self::checkQuestionDependency($student, $item)) {
return $item;
}
}
}
return null;
}

/**
* Returns the next question a user can answer given question dependencies.
*
* @param Student $student
* @return Question|null
*/
public static function getNextQuestion(Student $student)
{
$unanswered = self::getUnansweredQuestions($student);
foreach ($unanswered as $question) {
if (self::checkQuestionDependency($student, $question)) {
return $question;
}
}
return null;
}

/**
* @param Student $student
* @param int $n
* @return Question|null
*/
public static function getNthQuestion(Student $student, int $n)
{
if ($n < count($student->getAnsweredQuestions())) {
return $student->getAnsweredQuestions()[$n]->getQuestion();
} else {
return self::getUnansweredQuestions($student)[$n];
}
}

/**
* Returns the second most recently answered question from a user which could also be answered again based on
* question dependencies.
*
* @param Student $student
* @return Question|null
*/
public static function getPreviousQuestion(Student $student)
{
$aq = $student->getAnsweredQuestions();
if (!is_null($aq) and count($aq) > 0) {
$answered = array_reverse(array_map(function ($o) {
$o->getQuestion();
}, $aq));
foreach (array_slice($answered,1) as $item) {
if (self::checkQuestionDependency($student, $item)) {
return $item;
}
}
}
return null;
}

/**
* Returns an array of questions that have yet to be answered by the
*
* @param Student $student
* @return Question[]
*/
public static function getUnansweredQuestions(Student $student)
{
$dbc = new DatabaseConnection();
$params = ["i", $student->getPkID()];
$questionIDs = $dbc->query("select multiple", "SELECT pkquestionid FROM tblquestions
WHERE pkquestionid NOT IN
(SELECT fkquestionid FROM tblprofileanswers
WHERE fkuserid = ?)", $params);
$output = [];
if ($questionIDs) {
try {
foreach ($questionIDs as $questionID) {
$output[] = new QuestionMC($questionID);
}
} catch (Exception | Error $e) {
return [];
}
}
return $output;
}

/**
* Checks to see if the given question has been answered by the user
*
* @param Student $student
* @param Question $question
* @return bool
*/
public static function isQuestionAnswered(Student $student, Question $question): bool
{
$aq = $student->getAnsweredQuestions();
if (!is_null($aq) and count($aq) > 0) {
$answered = array_reverse(array_map(function ($o) {
$o->getQuestion();
}, $aq));
return in_array($question, $answered, true);
}
return false;
}

/**
* @param Student $student
* @param Question $question
* @param $answer
* @param int $importance
*/
public static function saveAnswer(Student $student, Question $question, $answer, int $importance): void
{
$student->addAnsweredQuestion(new QuestionAnswered($student, $question, $answer, $importance));
$student->updateToDatabase();
}

/**
* Checks to see if the specified question can be asked to the given student based on the dependencies of the
* given question and what questions the student has already answered.
*
* Will not always return true if the question has already been answered by the student. For example, if a student
* answers a child question, then changes the answer to the parent question, and then decides to try to answer
* the child question again.
*
* @param Student $student
* @param Question $question
* @return bool
*/
private static function checkQuestionDependency(Student $student, Question $question): bool
{
if (empty($question->getDependencies())) {
return true;
} else {
$haystack = $student->getAnsweredQuestions();
for ($i = 0; $i < count($haystack); $i++) {
$haystack[$i] = $haystack[$i]->getQuestion()->getPkID();
}
foreach ($question->getDependencies() as $dependency) {
if ($index = array_search($dependency->getParentID(), $haystack, true)) {
$studentAnswer = $student->getAnsweredQuestions()[$index];
if ($dependency->getRequiredAnswer() !== $studentAnswer->getAnswer()) {
return false;
}
} else {
return false;
}
}
return true;
}
}
}
4 changes: 2 additions & 2 deletions classes/entities/Question.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ public function getQuestionText(): string

/**
* @param Dependency $dependency
* @return bool
* @return bool|int
*/
private function addDependency(Dependency $dependency): bool
private function addDependency(Dependency $dependency)
{
return array_push($this->dependencies, $dependency);
}
Expand Down
2 changes: 1 addition & 1 deletion classes/entities/QuestionAnswered.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public function __construct2(Question $question, Student &$student)
* @param int $importance
* @throws Exception
*/
public function __construct3(Question $question, Student &$student, $answer, int $importance)
public function __construct4(Question $question, Student &$student, $answer, int $importance)
{
$result = [
$this->setQuestion($question),
Expand Down
18 changes: 12 additions & 6 deletions classes/entities/Student.php
Original file line number Diff line number Diff line change
Expand Up @@ -261,9 +261,6 @@ public function updateToDatabase(): bool
$result = $dbc->query("update", "UPDATE tbleduprofile SET nact=?, hadap=?, ngpa=?, nsat=?,
dtentry=?, ncollegelength=?, fkmajorid=?, fkmajor1=?, fkmajor2=?, fkmajor3=?,
nhouseincome=?, isgender=? WHERE fkuserid=?", $params);
$this->inDatabase = $result;
$this->synced = $result;
return (bool)$result;
} else {
$dbc = new DatabaseConnection();
$preferredMajors = $this->getPreferredMajors();
Expand Down Expand Up @@ -295,10 +292,19 @@ public function updateToDatabase(): bool
fkmajor2, fkmajor3, ngpa, nact, nsat, hadap, nhouseincome,
dtentry, ncollegelength, isgender) VALUES
(?,?,?,?,?,?,?,?,?,?,?,?,?)", $params);
$this->inDatabase = $result;
$this->synced = $result;
return (bool)$result;
}
$this->inDatabase = $result;

if(!is_null($this->getAnsweredQuestions())) {
foreach($this->getAnsweredQuestions() as $answeredQuestion) {
$answeredQuestion->removeFromDatabase();
$result = ($result and $answeredQuestion->updateToDatabase());
}
}

$this->inDatabase = $result;
$this->synced = $result;
return (bool)$result;
} else {
return false;
}
Expand Down

0 comments on commit 1a2a094

Please sign in to comment.