GenerateImportValueObjectCommand   A
last analyzed

Complexity

Total Complexity 7

Size/Duplication

Total Lines 89
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 10

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 7
lcom 0
cbo 10
dl 0
loc 89
ccs 0
cts 63
cp 0
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A configure() 0 30 1
A execute() 0 36 5
A determineFieldDefinitions() 0 15 1
1
<?php
2
3
namespace Mathielen\ImportEngineBundle\Command;
4
5
use Mathielen\ImportEngine\Import\Import;
6
use Mathielen\ImportEngine\Import\Run\ImportRunner;
7
use Mathielen\ImportEngine\Importer\Importer;
8
use Mathielen\ImportEngine\Storage\Format\Discovery\FileExtensionDiscoverStrategy;
9
use Mathielen\ImportEngine\Storage\StorageInterface;
10
use Mathielen\ImportEngine\Storage\StorageLocator;
11
use Mathielen\ImportEngineBundle\Generator\ValueObject\FieldFormatGuesser;
12
use Mathielen\ImportEngineBundle\Generator\ValueObjectGenerator;
13
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
14
use Symfony\Component\Console\Input\InputArgument;
15
use Symfony\Component\Console\Input\InputOption;
16
use Symfony\Component\Console\Input\InputInterface;
17
use Symfony\Component\Console\Output\OutputInterface;
18
19
/**
20
 * Generates value objects representing importing rows.
21
 */
22
class GenerateImportValueObjectCommand extends ContainerAwareCommand
23
{
24
    /**
25
     * @see Command
26
     */
27
    public function configure()
28
    {
29
        $this
30
            ->addArgument('source_id', InputArgument::REQUIRED, "Id of the demo-source. Different StorageProviders need different id-styles.\n- file/directory: \"<path/to/file>\"\n- doctrine: \"<id of query>\"\n- service: \"<service>.<method>[?arguments_like_url_query]\"")
31
            ->addArgument('name', InputArgument::REQUIRED, 'Classname of the valueobject that should be generated')
32
            ->addArgument('path', InputArgument::REQUIRED, 'Output directory for the class file')
33
            ->addOption('source_provider', null, InputOption::VALUE_OPTIONAL, 'Id of source provider. If not given it will be default', 'default')
34
            ->addOption('format', null, InputOption::VALUE_OPTIONAL, 'The format of the file (as a file extension). If not given it will be automatically determined.')
35
            ->addOption('skip-field-format-discovery', null, InputOption::VALUE_NONE, 'Do not scan source to determine the field-formats. Every fields will be assigned to the default-field-format')
36
            ->addOption('default-field-format', null, InputOption::VALUE_OPTIONAL, 'Default field format', 'string')
37
            ->setDescription('Generates a valueobject class file for use with the importengine.')
38
            ->setHelp(<<<EOT
39
The <info>generate:import:valueobject</info> command helps you generates new <comment>valueobjects</comment>
40
for the <info>mathielen/import-engine</info> importer.
41
42
<info>What is a valueobject?</info>
43
A <comment>valueobject</comment> is a small object that represents a simple entity whose equality is not based
44
on identity: i.e. two value objects are equal when they have the same value, not necessarily being the same object.
45
46
<info>Why do I need valueobjects for my importer?</info>
47
Here, the <comment>valueobject</comment> represents the current dataset that is processed by the importer (ie. a row of a file).
48
Having a generated class that represents this dataset enables you to explicitly define validation rules and other
49
related things.
50
51
This command can help you generate the <comment>valueobject</comment> class based on a "demo-file" of your import.
52
EOT
53
            )
54
            ->setName('importengine:generate:valueobject')
55
        ;
56
    }
57
58
    public function execute(InputInterface $input, OutputInterface $output)
59
    {
60
        $sourceId = $input->getArgument('source_id');
61
        $sourceProvider = $input->getOption('source_provider');
62
        $clsName = $input->getArgument('name');
63
        $path = $input->getArgument('path');
64
        $format = $input->getOption('format');
65
        $defaultFieldFormat = $input->getOption('default-field-format');
66
67
        if (!is_dir($path) || !is_writable($path)) {
68
            throw new \RuntimeException(sprintf('The directory "%s" is not a directory or cannot be written to.', $path));
69
        }
70
71
        /** @var StorageLocator $storageLocator */
72
        $storageLocator = $this->getContainer()->get('mathielen_importengine.import.storagelocator');
73
        $storageSelection = $storageLocator->selectStorage($sourceProvider, $sourceId);
74
75
        if (!empty($format)) {
76
            $storageSelection->addMetadata('format', FileExtensionDiscoverStrategy::fileExtensionToFormat($format));
77
        }
78
79
        $storage = $storageLocator->getStorage($storageSelection);
80
81
        if (!$input->getOption('skip-field-format-discovery')) {
82
            $fieldDefinitions = $this->determineFieldDefinitions($storage, $defaultFieldFormat);
83
        } else {
84
            $fieldDefinitions = array_change_key_case(array_fill_keys($storage->getFields(), array('type' => $defaultFieldFormat)), CASE_LOWER);
85
        }
86
87
        $voGenerator = new ValueObjectGenerator();
88
        $voGenerator->setSkeletonDirs($this->getContainer()->get('kernel')->locateResource('@MathielenImportEngineBundle/Resources/skeleton'));
89
90
        $filePath = $voGenerator->generate($fieldDefinitions, $clsName, $path);
91
92
        $output->writeln("Valueobject class file has been generated and saved to <info>$filePath</info>");
93
    }
94
95
    private function determineFieldDefinitions(StorageInterface $storage, $defaultFieldFormat = 'string')
96
    {
97
        /** @var Importer $importer */
98
        $importer = $this->getContainer()->get('mathielen_importengine.generator.valueobject.importer');
99
        $import = Import::build($importer, $storage);
100
101
        /** @var ImportRunner $importRunner */
102
        $importRunner = $this->getContainer()->get('mathielen_importengine.import.runner');
103
        $importRunner->run($import);
104
105
        /** @var FieldFormatGuesser $fieldformatguesser */
106
        $fieldformatguesser = $this->getContainer()->get('mathielen_importengine.generator.valueobject.fieldformatguesser');
107
108
        return $fieldformatguesser->getFieldDefinitionGuess($defaultFieldFormat);
109
    }
110
}
111