Hi, I’m pretty stuck.
My desired functionality is an amazon-like question-and-answer section. I want users to be able to submit questions about a product via a <form>
in the front end. I also want users to be able to submit answers to questions asked by other users, allowing multiple answers per question. I don’t want these to display automatically. I need to moderate them, and want to toggle them into view via the panel. This is why I have a ‘live’ field which must be explicitly set to “yes” in order for the questions and answers to display.
I am thinking the best way to do this is via a nested structure within my .yml file that looks like this:
fields:
questions:
type: structure
fields:
question:
label: question
type: text
user:
label: user
type: text
date:
label: date
type: text
live:
label: live
type: radio
options:
yes: yes
no: no
answers:
type: structure
fields:
answerer:
type: text
answer:
type: text
live:
type: radio
options:
yes: yes
no: no
Here is the code I use to retrieve the information from the <form>
submit, and write it to the .txt file:
<?php $questionData = [
'user' => get('user'),
'question' => get('question'),
'date' => get('date'),
'answer' => get('answer'),
'answerer' => get('answerer')
];
function addToQuestionStructure($page, $field, $questionData = array()){
$fieldData = page($page)->$field()->yaml();
$fieldData[] = $questionData;
$fieldData = yaml::encode($fieldData);
try {
page($page)->update(array($field => $fieldData));
} catch(Exception $e) {
return $e->getMessage();
}
}
if (isset($_POST['question'])) {
addToQuestionStructure($page, 'questions', [
'user' => esc($questionData['user']),
'question' => esc($questionData['question']),
'date' => esc($questionData['date']),
'answer' => esc($questionData['answer']),
'answerer' => esc($questionData['answerer']),
]);
}
?>
This is the code I am using to output the .txt data to my HTML.
<?php $questions = $page->questions()->toStructure(); ?>
<?php $liveCounter = 0 ?>
<?php if ($questions->isNotEmpty()): ?>
<?php foreach ($questions as $item): ?>
<!--this field allows me to toggle questions in and out of view-->
<?php if($item->live() == 'yes'): ?>
<?php $liveCounter = $liveCounter + 1 ?>
<div class='col-xs-12' style='margin-top:60px'>
<div class='review-top-container'>
<div class='review-container'>
<span class='review-title'><?= $item->question() ?></span>
<p class='review-author'><?= $item->user() ?></p>
<p class='review-body'><?= $item->date()?></p>
<hr class='border02'>
</div>
</div><br>
</div>
<br><br><br><br><br><br><br><br><br><br>
<?php if ($item->answers()->isNotEmpty()): ?>
<!--if the answers field is not empty, we want to display them-->
<?php foreach ($item->answers() as $test): ?>
<?php var_dump($test) ?>
<?php endforeach ?>
<?php elseif ($item->answers()->isEmpty()): ?>
<?php echo "nope" ?>
<?php endif ?>
<?php endif ?>
<?php endforeach ?>
<?php endif ?>
<?php if ($liveCounter == 0): ?>
<p style="color:white;">No questions yet. Ask the first one dawg!</p>
<?php endif ?>
I believe I am targeting it correctly because var_dump()
relays the correct information, except it is in an array within another array.
array(1) { [0]=> array(3) { ["answerer"]=> string(4) "Andy" ["answer"]=> string(69) "It holds up quite well. I have been using mine in the rain for years." ["live"]=> string(3) "yes" } }
However, when I try to go and target specific fields with the syntax I can use to target the question using the following syntax
<?php if ($item->answers()->isNotEmpty()): ?>
<?php foreach ($item->answers() as $test): ?>
<?php $test->answer() ?>
<?php endforeach ?>
<?php endif ?>
I get the error:
Call to a member function answer() on array
I was thinking the problem may be in my addToQuestionStructure function. Maybe I need to create another function references the ‘answers’ sub field more directly, instead of referring to the ‘questions’ field?
I noticed the documentation briefly mentioned nested structures, saying:
If you nest structure fields inside a structure field, you have to call the
toStructure() method on the nested fields as well and then loop through the nested items like above.
This might be my problem, because I haven’t called toStructure()
twice, but don’t know what it looks like to ‘call the method on the nested fields’ but I can’t find any examples of the nested structures, and thus can’t figure out the correct syntax to get them working.
In summary, I want to be able to access the data from the answers structure that is a feild of my questions structure, with a syntax somewhat like the following: <?= $item->answerer() ?>
I hope my question is clear, and that this is possible. Please let me know if you need any clarification. Thank you.