/** * キーにフィールド名、値に同名フィールド値の配列を持つ配列から、1つのお題を表す配列を生成します。 * @param string[][] $fieldsAsMultiDimensionalArray フィールド名はバリデート済み、かつフィールド値が空文字列であってはなりません。 * @throws SyntaxException 妥当なtextフィールドが存在しない場合。 * typeフィールドにselectionが指定されているとき、answerフィールド、optionフィールドが規則に合致しない場合。 * @return (string|string[]|float)[][] */ public function parse(array $fieldsAsMultiDimensionalArray) : array { $word = []; foreach ($fieldsAsMultiDimensionalArray as $fieldName => $fields) { foreach ($fields as $field) { $validatedField = $this->parseField($fieldName, $field); if (!is_null($validatedField)) { $word[$fieldName][] = $validatedField; } } } if (!isset($word['text'][0])) { // textフィールドが存在しない場合 throw new SyntaxException(_('textフィールドは必須です。')); } if (isset($word['type'][0]) && $word['type'][0] === 'selection') { // typeフィールドにselectionが指定されている場合 if (!isset($word['option'][0])) { throw new SyntaxException(_('typeフィールドに「selection」が指定されている場合、optionフィールドは必須です。')); } if (isset($word['answer'])) { // 選択問題なら foreach ($word['answer'] as $answer) { if (!in_array($answer, $word['option'])) { throw new SyntaxException(sprintf(_('「%s」はoptionフィールドのいずれの値にも一致しません。'), $answer)); } } } } $answerValidator = new AnswerValidator(); if (isset($word['answer'][0]) && $answerValidator->isRegExp($word['answer'][0])) { // 1個目のanswerフィールドが正規表現文字列だった場合 $this->logger->error(_('1個目のanswerフィールドは、正規表現文字列であってはなりません。')); foreach ($word['answer'] as $index => $answer) { if (!$answerValidator->isRegExp($answer)) { $noRegExpIndex = $index; break; } } if (isset($noRegExpIndex)) { array_unshift($word['answer'], array_splice($word['answer'], $noRegExpIndex)[0]); } else { unset($word['answer']); } } if (!isset($word['answer'][0]) && ($word['type'][0] ?? null) !== 'selection') { // answerフィールドが存在せず、typeフィールドがselectionでない場合 $text = $this->parseField('answer', $word['text'][0]); if (is_null($text)) { throw new SyntaxException(sprintf(_('「%s」は解答文字列の規則に合致しません。'), $word['text'][0])); } else { $word['text'][0] = $text; } } return $word; }