/** * フィールド単体の構文解析を行います。 * @param string $fieldName フィールド名。未知のフィールド名が指定された場合はそのまま返します。 * @param string $field フィールド値。 * @return string|string[]|float|null 矯正したフィールド値を返します。矯正の結果フィールドの削除が生じるときは null を返します。 */ protected function parseField(string $fieldName, string $field) { switch ($fieldName) { case 'image': case 'audio': case 'video': $validator = new FileLocationValidator($fieldName, $this->filenames); $validator->setLogger($this->logger); $output = $validator->correct($field); break; case 'image-source': case 'audio-source': case 'video-source': $validator = new LightweightMarkupValidator(true); $validator->setLogger($this->logger); $output = $validator->correct($field); if ($output !== '') { $output = ['lml' => $output, 'html' => (new HTMLFilter())->filter((new CommonMarkConverter())->convertToHtml($output))]; } break; case 'answer': case 'option': $validator = new AnswerValidator(); $validator->setLogger($this->logger); $output = $validator->correct($field); break; case 'description': case '@summary': $validator = new LightweightMarkupValidator(false, $this->filenames); $validator->setLogger($this->logger); $output = $validator->correct($field); if ($output !== '') { $output = ['lml' => $output, 'html' => (new HTMLFilter())->filter((new CommonMarkConverter())->convertToHtml($output))]; } break; case 'weight': $validator = new NumberValidator(true); $validator->setLogger($this->logger); $number = $validator->correct($field); if ($number > 0) { $output = $number; } else { $this->logger->error(sprintf(_('「%s」は0より大きい実数として扱えません。'), $field)); $output = ''; } if ($output !== '') { $output = (double) $output; } break; case 'specifics': $validator = new SpecificsValidator(); $validator->setLogger($this->logger); $output = $validator->correct($field); break; case '@regard': if (preg_match('/^\\[.{3,}]$/u', $field) === 1 && (new AnswerValidator())->validateRegexp("/{$field}/")) { $output = $field; } else { $this->logger->error(sprintf(_('「%s」は妥当な正規表現文字クラスではありません。'), $field)); $output = ''; } break; default: $output = $field; } $correctedField = is_array($output) ? $output['lml'] : $output; $fieldLength = mb_strlen($correctedField, 'UTF-8'); $maxFieldLength = in_array($fieldName, self::MARKUP_FIELD_NAMES) ? self::MAX_MARKUP_FIELD_LENGTH : self::MAX_FIELD_LENGTH; if ($fieldLength > $maxFieldLength) { throw new SyntaxException(sprintf(_('「%1$s」フィールドの値は%2$d文字です。%3$d文字以内にしなければなりません:'), $fieldName, $fieldLength, $maxFieldLength) . "\n{$correctedField}"); } return $output === '' ? null : $output; }
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 ?? ''; }