1 | <?php |
||
24 | class ImportCommand extends ContainerAwareCommand |
||
25 | { |
||
26 | |||
27 | const MAX_VIOLATION_ERRORS = 10; |
||
28 | |||
29 | 4 | protected function configure() |
|
30 | { |
||
31 | 4 | $this->setName('importengine:import') |
|
32 | 4 | ->setDescription('Imports data with a definied importer') |
|
33 | 4 | ->addArgument('source_id', InputArgument::REQUIRED, "id of source. Different StorageProviders need different id data.\n- upload, directory: \"<path/to/file>\"\n- doctrine: \"<id of query>\"\n- service: \"<service>.<method>[?arguments_like_url_query]\"") |
|
34 | 4 | ->addArgument('source_provider', InputArgument::OPTIONAL, 'id of source provider', 'default') |
|
35 | 4 | ->addOption('importer', 'i', InputOption::VALUE_REQUIRED, 'id/name of importer') |
|
36 | 4 | ->addOption('context', 'c', InputOption::VALUE_REQUIRED, 'Supply optional context information to import. Supply key-value data in query style: key=value&otherkey=othervalue&...') |
|
37 | 4 | ->addOption('limit', 'l', InputOption::VALUE_REQUIRED, 'Limit imported rows') |
|
38 | 4 | ->addOption('dryrun', 'd', InputOption::VALUE_NONE, 'Do not import - Validation only') |
|
39 | ; |
||
40 | 4 | } |
|
41 | |||
42 | 4 | protected function validateInput(InputInterface $input) |
|
49 | |||
50 | 4 | protected function execute(InputInterface $input, OutputInterface $output) |
|
68 | |||
69 | 4 | protected function import(OutputInterface $output, $importerId, $sourceProviderId, $sourceId, $context=null, $limit=null, $isDryrun=false) |
|
70 | { |
||
71 | 4 | $output->writeln("Commencing ".($isDryrun?'<comment>dry-run</comment> ':'')."import using importer ".(empty($importerId)?'<comment>unknown</comment>':"<info>$importerId</info>")." with source provider <info>$sourceProviderId</info> and source id <info>$sourceId</info>"); |
|
72 | |||
73 | 4 | $sourceId = Utils::parseSourceId($sourceId); |
|
74 | 4 | $progress = new ProgressBar($output); |
|
75 | |||
76 | //set limit |
||
77 | 4 | if ($limit) { |
|
78 | 1 | $output->writeln("Limiting import to <info>$limit</info> rows."); |
|
79 | |||
80 | $this->getContainer()->get('event_dispatcher')->addListener(ImportConfigureEvent::AFTER_BUILD, function (ImportConfigureEvent $event) use ($limit) { |
||
81 | $event->getImport()->importer()->filters()->add(new OffsetFilter(0, $limit)); |
||
82 | 1 | }); |
|
83 | } |
||
84 | |||
85 | //show discovered importer id |
||
86 | 4 | if (empty($importerId)) { |
|
87 | $this->getContainer()->get('event_dispatcher')->addListener(ImportRequestEvent::DISCOVERED, function (ImportRequestEvent $event) use ($output) { |
||
88 | $importerId = $event->getImportRequest()->getImporterId(); |
||
89 | $output->writeln("Importer discovered: <info>$importerId</info>"); |
||
90 | 2 | }); |
|
91 | } |
||
92 | |||
93 | /** @var ImportBuilder $importBuilder */ |
||
94 | 4 | $importBuilder = $this->getContainer()->get('mathielen_importengine.import.builder'); |
|
95 | |||
96 | 4 | $importRequest = new ImportRequest($sourceId, $sourceProviderId, $importerId, Utils::whoAmI().'@CLI'); |
|
97 | |||
98 | 4 | $import = $importBuilder->buildFromRequest($importRequest); |
|
99 | |||
100 | //apply context info from commandline |
||
101 | 4 | $importRun = $import->getRun(); |
|
102 | 4 | if ($context) { |
|
103 | $importRun->setContext($context); |
||
104 | } |
||
105 | |||
106 | //status callback |
||
107 | 4 | $this->getContainer()->get('event_dispatcher')->addListener(ImportItemEvent::AFTER_READ, function (ImportItemEvent $event) use ($output, &$progress) { |
|
108 | /** @var ImportRun $importRun */ |
||
109 | $importRun = $event->getContext()->getRun(); |
||
110 | $stats = $importRun->getStatistics(); |
||
111 | $processed = isset($stats['processed'])?$stats['processed']:0; |
||
112 | $max = $importRun->getInfo()['count']; |
||
113 | |||
114 | if ($progress->getMaxSteps() != $max) { |
||
115 | $progress = new ProgressBar($output, $max); |
||
116 | $progress->start(); |
||
117 | } |
||
118 | |||
119 | $progress->setProgress($processed); |
||
120 | 4 | }); |
|
121 | |||
122 | /** @var ImportRunner $importRunner */ |
||
123 | 4 | $importRunner = $this->getContainer()->get('mathielen_importengine.import.runner'); |
|
124 | 4 | if ($isDryrun) { |
|
125 | 1 | $importRunner->dryRun($import); |
|
126 | } else { |
||
127 | 3 | $importRunner->run($import); |
|
128 | } |
||
129 | |||
130 | 4 | $progress->finish(); |
|
131 | 4 | $output->writeln(''); |
|
132 | 4 | $output->writeln("<info>Import done</info>"); |
|
133 | 4 | $output->writeln(''); |
|
134 | |||
135 | 4 | $this->writeStatistics($importRun->getStatistics(), new Table($output)); |
|
136 | |||
137 | 4 | $this->writeValidationViolations( |
|
138 | $import |
||
139 | 4 | ->importer() |
|
140 | 4 | ->validation() |
|
141 | 4 | ->getViolations(), |
|
142 | 4 | new Table($output)); |
|
143 | |||
144 | 4 | $output->writeln(''); |
|
145 | 4 | } |
|
146 | |||
147 | 4 | protected function writeValidationViolations(array $violations, Table $table) |
|
148 | { |
||
149 | 4 | if (empty($violations)) { |
|
150 | 4 | return; |
|
151 | } |
||
152 | $violations = $violations['source'] + $violations['target']; |
||
153 | |||
154 | $table |
||
155 | ->setHeaders(array('Constraint', 'Occurrences (lines)')) |
||
156 | ; |
||
157 | |||
158 | $tree = []; |
||
159 | foreach ($violations as $line=>$validations) { |
||
160 | /** @var ConstraintViolation $validation */ |
||
161 | foreach ($validations as $validation) { |
||
162 | $key = $validation->__toString(); |
||
163 | if (!isset($tree[$key])) { |
||
164 | $tree[$key] = []; |
||
165 | } |
||
166 | $tree[$key][] = $line; |
||
167 | } |
||
168 | } |
||
169 | |||
170 | $i = 0; |
||
171 | foreach ($tree as $violation=>$lines) { |
||
172 | $table->addRow([$violation, join(', ', Utils::numbersToRangeText($lines))]); |
||
173 | ++$i; |
||
174 | |||
175 | if ($i === self::MAX_VIOLATION_ERRORS) { |
||
176 | $table->addRow(new TableSeparator()); |
||
177 | $table->addRow(array(null, 'There are more errors...')); |
||
178 | |||
179 | break; |
||
180 | } |
||
181 | } |
||
182 | |||
183 | if ($i > 0) { |
||
184 | $table->render(); |
||
185 | } |
||
186 | } |
||
187 | |||
188 | 4 | protected function writeStatistics(array $statistics, Table $table) |
|
201 | |||
202 | } |
||
203 |
This check looks from parameters that have been defined for a function or method, but which are not used in the method body.