Almost done, finish line!

Took 45 minutes
This commit is contained in:
Tobias Hopp 2020-10-02 17:07:56 +02:00
parent 8559e3388d
commit 9b1b2ea0c8
7 changed files with 112 additions and 30 deletions

29
.idea/workspace.xml generated
View File

@ -20,19 +20,12 @@
</component> </component>
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="fc13552d-b118-4828-b78f-fc8714e0cfdc" name="Default Changelist" comment=""> <list default="true" id="fc13552d-b118-4828-b78f-fc8714e0cfdc" name="Default Changelist" comment="">
<change afterPath="$PROJECT_DIR$/.idea/dataSources.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/vendor/js/faq.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/classes/Api.class.inc.php" beforeDir="false" afterPath="$PROJECT_DIR$/classes/Api.class.inc.php" afterDir="false" />
<change beforePath="$PROJECT_DIR$/config.inc.php" beforeDir="false" afterPath="$PROJECT_DIR$/config.inc.php" afterDir="false" /> <change beforePath="$PROJECT_DIR$/config.inc.php" beforeDir="false" afterPath="$PROJECT_DIR$/config.inc.php" afterDir="false" />
<change beforePath="$PROJECT_DIR$/controller/DefaultController.class.inc.php" beforeDir="false" afterPath="$PROJECT_DIR$/controller/DefaultController.class.inc.php" afterDir="false" />
<change beforePath="$PROJECT_DIR$/controller/FaqController.class.inc.php" beforeDir="false" afterPath="$PROJECT_DIR$/controller/FaqController.class.inc.php" afterDir="false" /> <change beforePath="$PROJECT_DIR$/controller/FaqController.class.inc.php" beforeDir="false" afterPath="$PROJECT_DIR$/controller/FaqController.class.inc.php" afterDir="false" />
<change beforePath="$PROJECT_DIR$/index.php" beforeDir="false" afterPath="$PROJECT_DIR$/index.php" afterDir="false" />
<change beforePath="$PROJECT_DIR$/main.inc.php" beforeDir="false" afterPath="$PROJECT_DIR$/main.inc.php" afterDir="false" />
<change beforePath="$PROJECT_DIR$/model/DefaultModel.class.inc.php" beforeDir="false" afterPath="$PROJECT_DIR$/model/DefaultModel.class.inc.php" afterDir="false" />
<change beforePath="$PROJECT_DIR$/model/FaqModel.class.inc.php" beforeDir="false" afterPath="$PROJECT_DIR$/model/FaqModel.class.inc.php" afterDir="false" /> <change beforePath="$PROJECT_DIR$/model/FaqModel.class.inc.php" beforeDir="false" afterPath="$PROJECT_DIR$/model/FaqModel.class.inc.php" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/faq.tmpl.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/faq.tmpl.html" afterDir="false" /> <change beforePath="$PROJECT_DIR$/templates/faq.tmpl.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/faq.tmpl.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/start.tmpl.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/start.tmpl.html" afterDir="false" /> <change beforePath="$PROJECT_DIR$/vendor/js/faq.js" beforeDir="false" afterPath="$PROJECT_DIR$/vendor/js/faq.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/views/Apitemplate.class.inc.php" beforeDir="false" afterPath="$PROJECT_DIR$/views/Apitemplate.class.inc.php" afterDir="false" /> <change beforePath="$PROJECT_DIR$/views/Apitemplate.class.inc.php" beforeDir="false" afterPath="$PROJECT_DIR$/views/Apitemplate.class.inc.php" afterDir="false" />
</list> </list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
@ -44,7 +37,7 @@
<execution /> <execution />
</component> </component>
<component name="DarkyenusTimeTracker"> <component name="DarkyenusTimeTracker">
<option name="totalTimeSeconds" value="24012" /> <option name="totalTimeSeconds" value="26733" />
<option name="gitIntegration" value="true" /> <option name="gitIntegration" value="true" />
<option name="naggedAbout" value="1" /> <option name="naggedAbout" value="1" />
</component> </component>
@ -88,7 +81,7 @@
<option name="number" value="Default" /> <option name="number" value="Default" />
<option name="presentableId" value="Default" /> <option name="presentableId" value="Default" />
<updated>1601618466935</updated> <updated>1601618466935</updated>
<workItem from="1601618467981" duration="26007000" /> <workItem from="1601618467981" duration="28726000" />
</task> </task>
<task id="LOCAL-00001" summary="Initial commit"> <task id="LOCAL-00001" summary="Initial commit">
<created>1601618764031</created> <created>1601618764031</created>
@ -104,7 +97,14 @@
<option name="project" value="LOCAL" /> <option name="project" value="LOCAL" />
<updated>1601628069096</updated> <updated>1601628069096</updated>
</task> </task>
<option name="localTasksCounter" value="3" /> <task id="LOCAL-00003" summary="Almost done, just the answer system and query is missing">
<created>1601648584159</created>
<option name="number" value="00003" />
<option name="presentableId" value="LOCAL-00003" />
<option name="project" value="LOCAL" />
<updated>1601648584159</updated>
</task>
<option name="localTasksCounter" value="4" />
<servers /> <servers />
</component> </component>
<component name="TypeScriptGeneratedFilesManager"> <component name="TypeScriptGeneratedFilesManager">
@ -124,7 +124,8 @@
<component name="VcsManagerConfiguration"> <component name="VcsManagerConfiguration">
<MESSAGE value="Initial commit" /> <MESSAGE value="Initial commit" />
<MESSAGE value="Stunden ende, einiges fertig, fehlt nicht mehr viel" /> <MESSAGE value="Stunden ende, einiges fertig, fehlt nicht mehr viel" />
<option name="LAST_COMMIT_MESSAGE" value="Stunden ende, einiges fertig, fehlt nicht mehr viel" /> <MESSAGE value="Almost done, just the answer system and query is missing" />
<option name="LAST_COMMIT_MESSAGE" value="Almost done, just the answer system and query is missing" />
</component> </component>
<component name="WindowStateProjectService"> <component name="WindowStateProjectService">
<state x="728" y="326" width="800" height="683" key="#com.intellij.execution.impl.EditConfigurationsDialog" timestamp="1601632929047"> <state x="728" y="326" width="800" height="683" key="#com.intellij.execution.impl.EditConfigurationsDialog" timestamp="1601632929047">
@ -163,10 +164,10 @@
<screen x="0" y="34" width="1920" height="1046" /> <screen x="0" y="34" width="1920" height="1046" />
</state> </state>
<state x="441" y="192" width="1037" height="736" key="SettingsEditor/0.34.1920.1046@0.34.1920.1046" timestamp="1601632853044" /> <state x="441" y="192" width="1037" height="736" key="SettingsEditor/0.34.1920.1046@0.34.1920.1046" timestamp="1601632853044" />
<state x="555" y="292" width="800" height="535" key="Vcs.Push.Dialog.v2" timestamp="1601628070210"> <state x="555" y="292" width="800" height="535" key="Vcs.Push.Dialog.v2" timestamp="1601648585625">
<screen x="0" y="34" width="1920" height="1046" /> <screen x="0" y="34" width="1920" height="1046" />
</state> </state>
<state x="555" y="292" width="800" height="535" key="Vcs.Push.Dialog.v2/0.34.1920.1046@0.34.1920.1046" timestamp="1601628070210" /> <state x="555" y="292" width="800" height="535" key="Vcs.Push.Dialog.v2/0.34.1920.1046@0.34.1920.1046" timestamp="1601648585625" />
<state x="809" y="122" width="639" height="876" key="com.intellij.database.view.ui.AbstractDbRefactoringDialog" timestamp="1601632983240"> <state x="809" y="122" width="639" height="876" key="com.intellij.database.view.ui.AbstractDbRefactoringDialog" timestamp="1601632983240">
<screen x="0" y="34" width="1920" height="1046" /> <screen x="0" y="34" width="1920" height="1046" />
</state> </state>

View File

@ -7,4 +7,4 @@ define( 'MYSQL_PASS', 'RnKVJHcUBIIu1XM2' );
define( 'MYSQL_DB', 'online-faq' ); define( 'MYSQL_DB', 'online-faq' );
define( 'CODE_LENGTH', 4 ); define( 'CODE_LENGTH', 4 );
define( 'WASTED_TIME', '5hrs and 51min' ); define( 'WASTED_TIME', '7hrs and 26min' );

View File

@ -29,6 +29,32 @@ class FaqController extends DefaultController
return $view->getResponse(); return $view->getResponse();
} }
public function getQuestionAction()
{
$view = new Apitemplate();
$FAQModel = new FaqModel();
$room = $FAQModel->getRoom();
$question_id = Api::getVar( 'question_id' );
if( empty( $question_id ) || !isset( $question_id ) )
{
$view->setSuccess( false );
$view->setHeaderCode( 903 );
return $view->getResponse();
}
if( ( $question = $FAQModel->getQuestion( $question_id ) ) === false )
{
$view->setSuccess( false );
$view->setHeaderCode( 906 );
return $view->getResponse();
}
$view->setResponse( $question );
$view->setSuccess( true );
return $view->getResponse();
}
public function addQuestionAction() public function addQuestionAction()
{ {
$view = new Apitemplate(); $view = new Apitemplate();

View File

@ -40,6 +40,15 @@ class FaqModel
return false; return false;
} }
$return = array();
foreach( $result as $index => $value )
{
$result[$index]['question'] = substr( $result[$index]['question'], 0, 50 );
$result[$index]['question'] = str_replace( "\n", ' ', $result[$index]['question'] );
$result[$index]['answer'] = substr( $result[$index]['answer'], 0, 50 );
$result[$index]['answer'] = str_replace( "\n", ' ', $result[$index]['answer'] );
}
return $result; return $result;
} }
@ -59,22 +68,22 @@ class FaqModel
public function addQuestion(int $room_id, string $question) public function addQuestion(int $room_id, string $question)
{ {
$stmnt = Database::getConnection()->prepare( 'INSERT INTO questions ( room_id, question, created_by ) VALUES ( :room_id, :question, :created_by )' ); $stmnt = Database::getConnection()->prepare( 'INSERT INTO questions ( room_id, question, created_by ) VALUES ( :room_id, :question, :created_by )' );
$stmnt->execute( array( 'room_id' => $room_id, 'question' => $question, 'created_by' => 'Anonymous' ) ); $stmnt->execute( array( 'room_id' => $room_id, 'question' => htmlspecialchars( $question ), 'created_by' => 'Anonymous' ) );
} }
public function addAnswer(int $question_id, string $answer) public function addAnswer(int $question_id, string $answer)
{ {
$stmnt = Database::getConnection()->prepare( 'UPDATE questions SET answer = :answer WHERE id = :id' ); $stmnt = Database::getConnection()->prepare( 'UPDATE questions SET answer = :answer WHERE id = :id' );
$stmnt->execute( array( 'answer' => $answer, 'id' => $question_id ) ); $stmnt->execute( array( 'answer' => htmlspecialchars( $answer ), 'id' => $question_id ) );
} }
public function checkUserIsRoomOwner( array $a_room ) public function checkUserIsRoomOwner( array $a_room )
{ {
$stmnt = Database::getConnection()->prepare( 'SELECT owner_sid FROM rooms WHERE id = :id' ); $stmnt = Database::getConnection()->prepare( 'SELECT id, owner_sid FROM rooms WHERE id = :id' );
$stmnt->execute( array( 'id' => $a_room['id'] ) ); $stmnt->execute( array( 'id' => $a_room['id'] ) );
$result = $stmnt->fetchAll( PDO::FETCH_ASSOC ); $result = $stmnt->fetch( PDO::FETCH_ASSOC );
if( $result === false || empty( $result ) ) if( $result === false || empty( $result ) )
{ {
@ -87,4 +96,18 @@ class FaqModel
return false; return false;
} }
public function getQuestion( int $question_id)
{
$stmnt = Database::getConnection()->prepare( 'SELECT * FROM questions WHERE id = :id' );
$stmnt->execute( array( 'id' => $question_id ) );
$result = $stmnt->fetch( PDO::FETCH_ASSOC );
if( $result === false || empty( $result ) )
{
return false;
}
$result['question'] = str_replace( "\n", '<br>', $result['question'] );
return $result;
}
} }

View File

@ -68,6 +68,9 @@
<div class="modal-body"> <div class="modal-body">
<span class="text-danger" id="askErrorMsg"></span> <span class="text-danger" id="askErrorMsg"></span>
<div class="form-group"> <div class="form-group">
<label for="name" class="col-form-label">Name</label><br>
<input type="text" maxlength="15" id="name">
<br>
<label for="question" class="col-form-label">Question</label> <label for="question" class="col-form-label">Question</label>
<textarea name="question" class="form-control" id="question" maxlength="500" rows="4"></textarea> <textarea name="question" class="form-control" id="question" maxlength="500" rows="4"></textarea>
</div> </div>
@ -104,6 +107,25 @@
</div> </div>
</div> </div>
<div class="modal fade" id="readMoreModal" tabindex="-1" role="dialog" aria-labelledby="answerModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="readMoreModalLabel">Answer a question</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<span id="readMoreModalText" class="text-justify">Loading...</span>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="errorModal" tabindex="-1" role="dialog" aria-labelledby="errorModalLabel" aria-hidden="true"> <div class="modal fade" id="errorModal" tabindex="-1" role="dialog" aria-labelledby="errorModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document"> <div class="modal-dialog" role="document">
<div class="modal-content"> <div class="modal-content">

31
vendor/js/faq.js vendored
View File

@ -4,9 +4,9 @@ askQuestionModal = $( '#askQuestionModal' );
readMoreModal = $( '#readMoreModal' ); readMoreModal = $( '#readMoreModal' );
answerModal = $( '#answerModal' ); answerModal = $( '#answerModal' );
answerText = $('#answer' ); answerText = $('#answer' );
answerModalTitle = $('#answerModalTitle'); answerModalTitle = $('#answerModalLabel');
readMoreModalText = $('#readMoreModalText' ); readMoreModalText = $('#readMoreModalText' );
readMoreModalTitle = $('#readMoreModalTitle' ); readMoreModalTitle = $('#readMoreModalLabel' );
errorMsg = $( '#errorMsg' ); errorMsg = $( '#errorMsg' );
askErrorMsg = $('#askErrorMsg') askErrorMsg = $('#askErrorMsg')
answerErrorMsg = $('#answerErrorMsg' ); answerErrorMsg = $('#answerErrorMsg' );
@ -68,6 +68,7 @@ function askQuestion()
function( result ){ function( result ){
askErrorMsg.html( '' ); askErrorMsg.html( '' );
askButton.prop( 'disabled', false ); askButton.prop( 'disabled', false );
question.val('');
askQuestionModal.modal( 'hide' ); askQuestionModal.modal( 'hide' );
}, function( result ) { }, function( result ) {
askButton.prop( 'disabled', false ); askButton.prop( 'disabled', false );
@ -97,10 +98,12 @@ function openReadMoreModal( id )
readMoreModal.modal( 'show' ); readMoreModal.modal( 'show' );
readMoreModalText.html( 'Loading...' ); readMoreModalText.html( 'Loading...' );
readMoreModalTitle.html( 'Question from: Anonymous' ); readMoreModalTitle.html( 'Question from: Anonymous' );
request( 'getQuestion', {"id":id}, function( result ) request( 'getQuestion', {"question_id":id}, function( result )
{ {
readMoreModalTitle.html( 'Question from: ' + result.data.created_by ); readMoreModalTitle.html( 'Question from: ' + result.data.created_by );
readMoreModalText.html( result.data.question ); readMoreModalText.html( '<strong>Question</strong><br>' + result.data.question +
'<hr><strong>Answer</strong><br>' + result.data.answer
);
}, function() { }, function() {
readMoreModalText.html( 'An error occurred, please try again later!' ); readMoreModalText.html( 'An error occurred, please try again later!' );
}); });
@ -114,7 +117,7 @@ function openAnswerModal( id )
answerErrorMsg.html( '' ); answerErrorMsg.html( '' );
answerModal.modal( 'show' ); answerModal.modal( 'show' );
request( 'getQuestion', {"id":id}, function( result ) request( 'getQuestion', {"question_id":id}, function( result )
{ {
readMoreModalTitle.html( 'Answer ' + result.data.created_by + " question" ); readMoreModalTitle.html( 'Answer ' + result.data.created_by + " question" );
answer_id = result.data.id; answer_id = result.data.id;
@ -160,15 +163,20 @@ function getQuestions()
{ {
questions.append( '<div class="col-sm-6 col-lg-4 col-md-5"><div class="card" id="q_' + result.data.questions[i].id + '" style=" margin-bottom: 10px;">' + questions.append( '<div class="col-sm-6 col-lg-4 col-md-5"><div class="card" id="q_' + result.data.questions[i].id + '" style=" margin-bottom: 10px;">' +
' <div class="card-body">' + ' <div class="card-body">' +
' <h5 class="card-title">Subject</h5>' + ' <h5 class="card-title">Question</h5>' +
' <h6 class="card-subtitle mb-2 text-muted">Creator</h6>' + ' <h6 class="card-subtitle mb-2 text-muted">From ' + result.data.questions[i].created_by + '</h6>' +
' <p class="card-text">Text up to 100 characters</p>' + ' <p class="card-text">'+ result.data.questions[i].question + '</p>' +
' <a onclick="openReadMoreModal(\''+ result.data.questions[i].id + '\');" class="card-link">Read more</a>' + ' <a href="#" onclick="openReadMoreModal(\''+ result.data.questions[i].id + '\');" class="card-link">Read more</a>' +
' <a onclick="openAnswerModal(\'' + result.data.questions[i].id + '\');" class="card-link">Answer</a>' + ' <a href="#" onclick="openAnswerModal(\'' + result.data.questions[i].id + '\');" class="card-link">Answer</a>' +
' </div>' + ' </div>' +
' </div>' + ' </div>' +
'</div> ' ) '</div> ' )
} }
else if ( $( '#qa_' + result.data.questions[i].id ).length < 1 && result.data.questions[i].answer.length !== null )
{
$('#q_' + result.data.questions[i].id + ' p' ).html( result.data.questions[i].question + '<hr><span id="qa_' + result.data.questions[i].id + '">' + result.data.questions[i].answer + '</span>' );
}
} }
@ -188,4 +196,5 @@ function getQuestions()
); );
} }
getQuestions(); getQuestions();
setInterval( function() { getQuestions(); }, 1500 );

View File

@ -36,6 +36,7 @@ class Apitemplate
902 => 'Answer-cannot-be-set', 902 => 'Answer-cannot-be-set',
903 => 'wrong-parameters-given', 903 => 'wrong-parameters-given',
905 => 'User-is-not-owner', 905 => 'User-is-not-owner',
906 => 'Question-does-not-exist',
); );
$text = isset( $codes[$a_code] ) ? $codes[$a_code] : "Error"; $text = isset( $codes[$a_code] ) ? $codes[$a_code] : "Error";
header("HTTP/1.1 $a_code $text" ); header("HTTP/1.1 $a_code $text" );