Completed
Push — development ( 978bc2...f10264 )
by Thomas
10:03 queued 05:32
created

ImportService::handleFormData()   B

Complexity

Conditions 6
Paths 12

Size

Total Lines 43

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
nc 12
nop 1
dl 0
loc 43
rs 8.6097
c 0
b 0
f 0
1
<?php
2
3
namespace Oc\FieldNotes\Import;
4
5
use Doctrine\ORM\EntityManagerInterface;
6
use Exception;
7
use Oc\FieldNotes\Context\HandleFormContext;
8
use Oc\FieldNotes\Exception\FileFormatException;
9
use Oc\FieldNotes\Form\UploadFormData;
10
use Oc\FieldNotes\Import\Context\ImportContext;
11
use Oc\Validator\Exception\ValidationException;
12
use Oc\Validator\Validator;
13
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
14
use Symfony\Component\ExpressionLanguage\Node\Node;
15
use Symfony\Component\Translation\TranslatorInterface;
16
use Symfony\Component\Validator\ConstraintViolationInterface;
17
18
class ImportService
19
{
20
    /**
21
     * @var EntityManagerInterface
22
     */
23
    protected $entityManager;
24
25
    /**
26
     * @var TranslatorInterface
27
     */
28
    protected $translator;
29
30
    /**
31
     * @var FileParser
32
     */
33
    private $fileParser;
34
35
    /**
36
     * @var Validator
37
     */
38
    private $validator;
39
40
    /**
41
     * @var Importer
42
     */
43
    private $importer;
44
45
    public function __construct(
46
        Importer $importer,
47
        FileParser $fileParser,
48
        Validator $validator,
49
        TranslatorInterface $translator
50
    ) {
51
        $this->translator = $translator;
52
        $this->fileParser = $fileParser;
53
        $this->validator = $validator;
54
        $this->importer = $importer;
55
    }
56
57
    /**
58
     * Handles submitted form data.
59
     */
60
    public function handleFormData(UploadFormData $formData): HandleFormContext
61
    {
62
        $success = true;
63
        $errors = [];
64
65
        try {
66
            $fieldNotes = $this->fileParser->parseFile($formData->file);
67
        } catch (FileFormatException $e) {
68
            $errors[] = $this->translator->trans('field_notes.error.wrong_file_format');
69
            $success = false;
70
        }
71
72
        try {
73
            $this->validator->validate($fieldNotes);
74
        } catch (ValidationException $e) {
75
            /**
76
             * @var ConstraintViolationInterface
77
             */
78
            foreach ($e->getViolations() as $violation) {
79
                $linePrefix = $this->getTranslatedLinePrefix($violation);
80
81
                unset($fieldNotes[$this->getLineNumber($violation)]);
82
83
                $errors[] = sprintf(
84
                    '%s %s',
85
                    $linePrefix,
86
                    $violation->getMessage()
87
                );
88
            }
89
            $success = false;
90
        } catch (Exception $e) {
91
            $errors[] = $this->translator->trans('general.error.unknown_error');
92
            $success = false;
93
        }
94
95
        if (is_array($fieldNotes)) {
96
            $context = new ImportContext($fieldNotes, $formData);
97
98
            $this->importer->import($context);
99
        }
100
101
        return new HandleFormContext($success, $errors);
102
    }
103
104
    /**
105
     * Fetches the line of the constraint violation and returns the line prefix with line number.
106
     */
107
    private function getTranslatedLinePrefix(ConstraintViolationInterface $violation): string
108
    {
109
        $line = $this->getLineNumber($violation) + 1;
110
111
        $linePrefix = $this->translator->trans(
112
            'field_notes.error.line_prefix',
113
            [
114
                '%line%' => $line,
115
            ]
116
        );
117
118
        return $linePrefix;
119
    }
120
121
    private function getLineNumber(ConstraintViolationInterface $violation): int
122
    {
123
        /**
124
         * @var Node
125
         */
126
        $expressionAst = (new ExpressionLanguage())->parse($violation->getPropertyPath(), [])->getNodes();
127
128
        return (int) $expressionAst->nodes['node']->nodes[1]->attributes['value'];
129
    }
130
}
131