/** * 一つのお題を表す配列から解答行に直列化します。 * @param (string|string[]|float)[][] $word * @return string 末尾に改行 (CRLF) を含みます。 */ protected function serializeAnswerLine(array $word) : string { $line = ['A']; $specifics = new URLSearchParams($word['specifics'][0] ?? ''); if (isset($word['option'][0])) { if (isset($word['type'][0]) && $word['type'][0] === 'selection' && empty($word['answer'])) { $line[] = 2; } elseif ($specifics->has('require-all-right')) { $line[] = 3; } else { $line[] = 1; } $answers = isset($word['answer'][0]) ? $word['answer'] : $word['text']; foreach ($word['option'] as $i => $option) { $line[] = $this->serializeQuizField($option); if ($line[1] === 2) { $line[] = $i + 1; } elseif (in_array($option, $answers)) { $line[] = '\\seikai'; } } if ($specifics->has('no-random')) { $line[] = '\\norandom'; } } else { $line[] = 0; $answers = $this->getAnswers($word, [$this, 'convertToShiftJISableInAnswerWithKatakana']); if (!$answers) { $this->logUnserializableError('Inteligenceω クイズ', $word); return ''; } $bonuses = $specifics->getAll('bonus'); foreach ($answers as $i => $answer) { $line[] = $answer; if (!empty($bonuses[$i])) { $line[] = "\\bonus={$bonuses[$i]}"; } } } $explain[] = $word['text'][0]; if (isset($word['description'][0])) { $explain[] = $word['description'][0]['lml']; } $line[] = '\\explain=' . $this->serializeQuizField(implode("\n\n", $explain)); return implode(',', $line) . "\r\n"; }
public function correct(string $input) : string { $nameValues = $this->parse($input); if ($nameValues) { $params = new URLSearchParams(); foreach ($nameValues as $name => $values) { foreach ($values as $value) { switch ($name) { // 空文字列 case 'pixelization': case 'require-all-right': case 'no-random': $params->append($name, ''); break; // 0より大きい実数 // 0より大きい実数 case 'magnification': case 'last-magnification': case 'length': case 'speed': case 'volume': $validator = new NumberValidator(true); $validator->setLogger($this->logger); $number = $validator->correct($value); if ($number !== '' && $number > 0) { $params->append($name, $number); } else { $this->logger->error(sprintf(_('「%s」は0より大きい実数として扱えません。'), $value)); } break; // 0以上の実数 // 0以上の実数 case 'start': $validator = new NumberValidator(true); $validator->setLogger($this->logger); $number = $validator->correct($value); if ($number !== '' && $number >= 0) { $params->append($name, $number); } else { $this->logger->error(sprintf(_('「%s」は0以上の実数として扱えません。'), $value)); } break; // 1以上の整数 // 1以上の整数 case 'repeat': case 'score': case 'last-score': $validator = new NumberValidator(); $validator->setLogger($this->logger); $number = $validator->correct($value); if ($number !== '' && $number >= 1) { $params->append($name, $number); } else { $this->logger->error(sprintf(_('「%s」は1以上の整数として扱えません。'), $value)); } break; // 整数 // 整数 case 'bonus': $validator = new NumberValidator(); $validator->setLogger($this->logger); $number = $validator->correct($value); if ($number !== '') { $params->append($name, $number); } else { $this->logger->error(sprintf(_('「%s」は整数として扱えません。'), $value)); } break; default: $params->append($name, $value); } } } foreach (self::DEPENDENCES as $source => $destination) { if ($params->has($source) && !$params->has($destination)) { $params->delete($source); // TRANRATORS: %1$s、%2$s はapplication/x-www-form-urlencoded形式の名前部分 $this->logger->error(sprintf(_('「%1$s」を指定するときは、「%2$s」も指定しておく必要があります。'), $source, $destination)); } } $output = (string) $params; } else { $this->logger->error(_('解析した結果空文字列になりました。')); } return $output ?? ''; }