/** * @param CheckAction $action */ public function perform(CheckAction $action) { $files = $this->getFiles($action->getBasePath()); $parser = new Parser(); foreach ($files as $file) { if (in_array($file->getFileName(), $action->getSkip('file'))) { continue; } $data = $parser->parse(file_get_contents($file->getRealPath())); $context = ['file_name' => $file->getFileName(), 'file_path' => $file->getPathName(), 'discriminator' => 'category', 'training' => $this->getCurrentTraining($file)]; if (!is_array($data)) { $action->addError('structure', 'Output must be type of array, given ' . gettype($data), $context); $action->addSkip('category', $file->getFileName()); continue; } if (empty($data)) { $action->addError('structure', 'Resource file cannot be empty', $context); continue; } //Structure without data can pass if (1 === count($data) && isset($data['category'])) { $action->addSkip('category', $data['category']); continue; } if (empty($data['category'])) { $action->addError('structure', 'Cannot have empty label', $context); } if (!isset($data['questions']) || empty($data['questions'])) { $action->addError('structure', 'Missing questions', $context); $action->addSkip('category', $data['category']); continue; } foreach ($data['questions'] as $questionNode) { $context['discriminator'] = 'question'; if (!isset($questionNode['question'])) { $action->addError('structure', 'Required a question', $context); continue 2; } if (!is_string($questionNode['question'])) { $action->addError('structure', 'Should be a string', $context); continue 2; } if (empty($questionNode['question'])) { $action->addError('structure', 'Cannot have empty label', $context); } if (!isset($questionNode['answers']) || count($questionNode['answers']) <= 1) { $action->addError('structure', 'Must contains at least 2 answers to be valid', $context); continue 2; } $good = 0; foreach ($questionNode['answers'] as $answerNode) { $context['discriminator'] = 'answer'; if (!isset($answerNode['value']) || !is_string($answerNode['value'])) { $action->addError('structure', 'Missing or invalid [value] field', $context); continue 3; } if (empty($answerNode['value'])) { $action->addError('structure', sprintf('Cannot have empty label, related question : "%s"', $questionNode['question']), $context); } if (!isset($answerNode['correct']) || !is_bool($answerNode['correct'])) { $action->addError('structure', 'Missing or invalid [correct] field', $context); continue 3; } if (true === $answerNode['correct']) { $good++; } } if (0 === $good) { $action->addError('structure', 'Must have at least one valid answer', $context); continue 2; } } } }
/** * @param CheckAction $action */ public function perform(CheckAction $action) { $files = $this->getFiles($action->getBasePath()); $parser = new Parser(); $collector = ['category' => [], 'question' => [], 'answer' => []]; foreach ($files as $file) { if (in_array($file->getFileName(), $action->getSkip('file'))) { continue 1; } $data = $parser->parse(file_get_contents($file->getRealPath())); if (in_array($data['category'], $action->getSkip('category'))) { continue 1; } $trainingName = $this->getCurrentTraining($file); $identifier = implode('=', [$trainingName, $file->getFileName()]); $collector['category'][$identifier] = $data['category']; foreach ($data['questions'] as $questionNode) { if (in_array($questionNode['question'], $action->getSkip('question'))) { continue 2; } $collector['question'][$identifier][] = $questionNode['question']; foreach ($questionNode['answers'] as $answerNode) { if (in_array($answerNode['value'], $action->getSkip('answer'))) { continue 3; } $collector['answer'][$identifier][$questionNode['question']][] = $answerNode['value']; } } } foreach ($collector as $type => $node) { if ($type === 'category') { //flatten foreach (array_count_values($collector[$type]) as $category => $count) { if ($count > 1) { $affected = array_keys($collector[$type], $category); $errorFiles = []; foreach ($affected as $value) { list($training, $file) = explode('=', $value); $errorFiles[] = $file; } $action->addError('integrity', sprintf('Category "%s" was find several times', $category), ['file_name' => $errorFiles, 'discriminator' => 'category', 'training' => $training]); } } } if ($type === 'question') { //nested foreach ($node as $context => $questionsNodes) { list($training, $fileName) = explode('=', $context); foreach (array_count_values($questionsNodes) as $question => $count) { if ($count > 1) { $action->addError('integrity', sprintf('Question "%s" was find several times', $question), ['file_name' => $fileName, 'discriminator' => 'question', 'training' => $training]); } } } } if ($type === 'answer') { //nested foreach ($node as $context => $answerNode) { list($training, $fileName) = explode('=', $context); foreach ($answerNode as $question => $answers) { foreach (array_count_values($answers) as $answer => $count) { if ($count > 1) { $action->addError('integrity', sprintf('Answer "%s" was find several times for question "%s"', $answer, $question), ['file_name' => $fileName, 'discriminator' => 'answer', 'training' => $training]); } } } } } } }