SchemaXml.php 5.4 KB
Newer Older
Ketan's avatar
Ketan committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace Magento\Mtf\Util\Generate\Fixture;

use Magento\Framework\ObjectManagerInterface;

/**
 * Fixture files generator.
 */
class SchemaXml
{
    /**
     * Object manager instance.
     *
     * @var ObjectManagerInterface
     */
    protected $objectManager;

    /**
     * Provider of fields from database.
     *
     * @var FieldsProvider
     */
    protected $fieldsProvider;

    /**
     * The DOMDocument class represents an entire XML.
     *
     * @var \DOMDocument
     */
    protected $dom;

    /**
     * Required fields list.
     *
     * @var array
     */
    protected $requiredFields = [
        'name',
        'entity_type',
        'collection',
    ];

    /**
     * @constructor
     * @param ObjectManagerInterface $objectManager
     */
    public function __construct(ObjectManagerInterface $objectManager)
    {
        $this->objectManager = $objectManager;
        $this->fieldsProvider = $this->objectManager->create(\Magento\Mtf\Util\Generate\Fixture\FieldsProvider::class);
        $this->dom = new \DOMDocument('1.0');
        $this->dom->load(dirname(__FILE__) . '/template.xml');
        $this->dom->preserveWhiteSpace = false;
        $this->dom->formatOutput = true;
    }

    /**
     * Launch Fixture generators.
     *
     * @return void
     */
    public function launch()
    {
        $options = getopt('', ['type:', 'name:', 'entity_type:', 'collection:', 'help']);
        $checkKeyExists = count(array_diff($this->requiredFields, array_keys($options)));

        if (empty($options) || isset($options['help']) || $checkKeyExists > 0) {
            $this->getHelp();
        }
        $config['type'] = empty($options['type']) ? 'flat' : $options['type'];
        if ($config['type'] === 'composite') {
            $options['entities'] = explode(',', $options['entity_type']);
            unset($options['entity_type']);
        }
        $config = array_merge($config, $options);

        $this->generate($config);
    }

    /**
     * Generate Fixtures XML.
     *
     * @param array $config
     * @return void
     */
    public function generate(array $config)
    {
        if (!$this->fieldsProvider->checkConnection()) {
            return;
        }

        $this->generateFixtureXml($config);
    }

    /**
     * Generate fixtures XML definition files.
     *
     * @param array $config
     * @return void
     */
    protected function generateFixtureXml(array $config)
    {
        $classShortName = ucfirst($config['name']);
        $fileName = $classShortName . '.xml';
        $collection = explode('\\', $config['collection']);
        $collection = array_values(array_filter($collection));
        $path = $collection[0] . '\\' . $collection[1] . '\Test\Fixture\\';
        $module = $collection[0] . '_' . $collection[1];
        $repositoryClass = $collection[0] . '\\' . $collection[1] . '\Test\Repository\\' . $classShortName;
        $handlerInterface = $collection[0] . '\\' . $collection[1] . '\Test\Handler\\';
        $handlerInterface .= $classShortName . '\\' . $classShortName . 'Interface';
        $fixtureClass = $path . $classShortName;
        $folderName = MTF_TESTS_PATH . $path;
        $pathToFile = str_replace('\\', DIRECTORY_SEPARATOR, $folderName . $fileName);
        if (file_exists($pathToFile)) {
            echo "Fixture with name ($pathToFile) already exists.\n";
            return;
        }
        if (!is_dir($folderName)) {
            mkdir($folderName, 0777, true);
        }

        /** @var \DOMElement $root */
        $root = $this->dom->getElementsByTagName('config')->item(0);

        $fixture = $this->dom->createElement('fixture');
        $fixture->setAttribute('name', $config['name']);
        $fixture->setAttribute('module', $module);
        $fixture->setAttribute('type', $config['type']);
        $fixture->setAttribute('collection', implode('\\', $collection));
        $fixture->setAttribute('repository_class', $repositoryClass);
        $fixture->setAttribute('handler_interface', $handlerInterface);
        $fixture->setAttribute('class', $fixtureClass);
        if (isset($config['entity_type'])) {
            $fixture->setAttribute('entity_type', $config['entity_type']);
        }
        $root->appendChild($fixture);

        $fields = $this->fieldsProvider->getFields($config);
        foreach ($fields as $fieldName => $fieldValue) {
            $field = $this->dom->createElement('field');
            $field->setAttribute('name', $fieldName);
            $field->setAttribute('is_required', (int)$fieldValue['is_required']);
            $fixture->appendChild($field);
        }

        file_put_contents($pathToFile, str_replace('  ', '    ', $this->dom->saveXML()));
    }

    /**
     * Prints help info and stops code execution.
     *
     * @SuppressWarnings(PHPMD)
     */
    protected function getHelp()
    {
        echo <<<TAG
Usage: Magento 2 fixture schema generator.

 --type\t\t<flat>|<eav>|<table>|<composite>\t\tTable type for the entity\tDefault: flat
 --name\t\t<className>\t\t\t\t\tName of generated class
 --entity_type\t<entity_type>|<entity_type1,entity_type2>\tDatabase table name where entity data is stored
 --collection\t<path\\\\to\\\\collection>\t\t\t\tCollection to generate data sets\tNOTE: All backslashes must be escaped
 --help\t\tThis help

 name, entity_type, collection - required fields

TAG;
        exit(0);
    }
}