protected function execute(InputInterface $input, OutputInterface $output)
 {
     $path = new PathBuilder();
     $path->setModule('Uploads');
     $path = realpath(dirname(dirname(dirname(dirname(dirname(__DIR__)))))) . DIRECTORY_SEPARATOR . $path->getSourcePath();
     $path = str_replace('/src/' . 'Uploads' . '/.php', '', $path);
     if (file_exists($path)) {
         throw new \RuntimeException('A directory with the same module name already exists: ' . $path);
     }
     $templatePath = realpath(dirname(dirname(dirname(__DIR__)))) . DIRECTORY_SEPARATOR . 'templates' . DIRECTORY_SEPARATOR . 'Uploads';
     $this->copy_directory($templatePath, $path);
     $this->updateApplicationConfig('Uploads');
     $output->writeln('<info>write</info>: ' . $path);
     $output->writeln('<info>write</info>: ' . realpath(dirname(dirname(dirname(dirname(dirname(__DIR__)))))) . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'application.config.local.php');
 }
 /**
  * @param InputInterface  $input
  * @param OutputInterface $output
  *
  * @return int|null|void
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $moduleName = $input->getArgument('ModuleName');
     $dtoName = $input->getArgument('DataTransferName') . 'Dto';
     $path = new PathBuilder();
     $path = $path->addPart('module')->addPart($moduleName)->addPart('src')->addPart($moduleName)->addPart('DataTransfer')->addPart($dtoName . '.php')->getPath();
     if (file_exists($path)) {
         throw new \RuntimeException('A file with the same data transfer name already exists: ' . $path);
     }
     $templatePath = new PathBuilder();
     $templatePath = $templatePath->addPart('vendor')->addPart('middleout')->addPart('mdo-bundle-zf2-scaffold')->addPart('templates')->addPart('BareModule')->addPart('src')->addPart('BareModule')->addPart('DataTransfer')->addPart('ScaffoldDto.php')->getPath();
     $t = file_get_contents($templatePath);
     $t = str_replace('BareModule', $moduleName, $t);
     $t = str_replace('ScaffoldDto', $dtoName, $t);
     $builder = new PathBuilder();
     $builder->make_path($path);
     file_put_contents($path, $t);
     $output->writeln('<info>write</info>: ' . $path);
 }
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $path = new PathBuilder();
        $path = $path->addPart('config')->addPart('autoload')->addPart('database.eloquentzf2.config.local.php')->getPath();
        $dbConfig = (include $path);
        $dbConfig = $dbConfig['database_eloquent'];
        $moduleName = $input->getArgument('ModuleName');
        $modelName = $input->getArgument('ModelName');
        $tblName = $input->getArgument('TableName');
        $entityPath = $input->getArgument('EntityRelativePath');
        if ($dbConfig['host'] == 'localhost') {
            $dbConfig['host'] = '127.0.0.1';
        }
        $dbh = new \PDO('mysql:host=' . $dbConfig['host'] . ';dbname=' . $dbConfig['database'], $dbConfig['username'], $dbConfig['password'] ? $dbConfig['password'] : null);
        $columns = [];
        $priKey = null;
        $autoInc = true;
        $enums = [];
        foreach ($dbh->query('select * from information_schema.columns where table_schema = \'' . $dbConfig['database'] . '\' and table_name = \'' . $tblName . '\'') as $row) {
            $columns[] = $row['COLUMN_NAME'];
            if (strtolower($row['COLUMN_KEY']) == 'pri') {
                if (!$priKey) {
                    $priKey = $row['COLUMN_NAME'];
                    if ($row['EXTRA'] != 'auto_increment') {
                        $autoInc = false;
                    }
                } else {
                    $priKey = [$priKey];
                    $priKey[] = $row['COLUMN_NAME'];
                    $autoInc = false;
                }
            }
            if (strtolower($row['DATA_TYPE']) == 'enum') {
                $enums[$row['COLUMN_NAME']] = explode(',', rtrim(str_replace('enum(', '', $row['COLUMN_TYPE']), ')'));
                $enums[$row['COLUMN_NAME']] = array_map(function ($el) {
                    return trim($el, "'");
                }, $enums[$row['COLUMN_NAME']]);
            }
            if (strtolower($row['DATA_TYPE']) == 'tinyint') {
                $enums[$row['COLUMN_NAME']] = [true, false];
            }
        }
        $fillable = [];
        foreach ($columns as $column) {
            if (is_array($priKey)) {
                if (!in_array($column, $priKey)) {
                    $fillable[] = $column;
                }
            } else {
                if ($column != $priKey) {
                    $fillable[] = $column;
                }
            }
        }
        foreach ($fillable as $k => $v) {
            if (in_array($v, ['created_at', 'updated_at', 'deleted_at'])) {
                unset($fillable[$k]);
            }
        }
        $path = new PathBuilder();
        $path = $path->addPart('module')->addPart($moduleName)->addPart('src')->addPart($moduleName)->addPart('Entity');
        if ($entityPath) {
            $entityPath = trim($entityPath, '/');
            $path->addPart($entityPath);
        }
        $path = $path->addPart($modelName . '.php')->getPath();
        if (file_exists($path)) {
            throw new \RuntimeException('A file with the same model name already exists: ' . $path);
        }
        $prop1 = new \Zend\Code\Generator\PropertyGenerator('incrementing', $autoInc, \Zend\Code\Generator\PropertyGenerator::FLAG_PUBLIC);
        $prop1->setDocBlock('@var bool');
        $prop2 = new \Zend\Code\Generator\PropertyGenerator('table', $tblName, \Zend\Code\Generator\PropertyGenerator::FLAG_PROTECTED);
        $prop2->setDocBlock('@var string');
        $prop3 = new \Zend\Code\Generator\PropertyGenerator('primaryKey', $priKey, \Zend\Code\Generator\PropertyGenerator::FLAG_PROTECTED);
        $prop3->setDocBlock(is_array($priKey) ? '@var array' : '@var string');
        $prop4 = new \Zend\Code\Generator\PropertyGenerator('fillable', $fillable, \Zend\Code\Generator\PropertyGenerator::FLAG_PROTECTED);
        $prop4->setDocBlock('@var array The attributes that are mass assignable.');
        $class = new ClassGenerator($modelName, $moduleName . '\\Entity', null, 'AbstractEntity', [], [$prop1, $prop2, $prop3, $prop4], []);
        if ($entityPath) {
            $class->setNamespaceName($class->getNamespaceName() . '\\' . trim(str_replace('/', '\\', $entityPath), '/'));
        }
        $dbGenerator = new \Zend\Code\Generator\DocBlockGenerator();
        foreach ($columns as $column) {
            $dbGenerator->setTag(['name' => 'property', 'description' => 'string $' . $column]);
        }
        $class->addUse('MdoBundleEloquent\\Entity\\AbstractEntity');
        $class->setDocBlock($dbGenerator);
        // Set timestamps = false if no created_at / updated_at
        if (!in_array('created_at', $columns) && !in_array('updated_at', $columns)) {
            $prop = new \Zend\Code\Generator\PropertyGenerator('timestamps', false, \Zend\Code\Generator\PropertyGenerator::FLAG_PUBLIC);
            $prop->setDocBlock('@var bool');
            $class->addPropertyFromGenerator($prop);
        }
        // Set getUpdatedAtColumn() to null if no created_at
        if (!in_array('created_at', $columns) && in_array('updated_at', $columns)) {
            $method = new \Zend\Code\Generator\MethodGenerator('getCreatedAtColumn', [], \Zend\Code\Generator\PropertyGenerator::FLAG_PUBLIC);
            $method->setDocBlock('@return null');
            $class->addMethodFromGenerator($method);
            $method = new \Zend\Code\Generator\MethodGenerator('setCreatedAt', ['value'], \Zend\Code\Generator\PropertyGenerator::FLAG_PUBLIC);
            $method->setDocBlock('@return null');
            $class->addMethodFromGenerator($method);
        }
        // Set getCreatedAtColumn() to null if no created_at
        if (!in_array('updated_at', $columns) && in_array('created_at', $columns)) {
            $method = new \Zend\Code\Generator\MethodGenerator('getUpdatedAtColumn', [], \Zend\Code\Generator\PropertyGenerator::FLAG_PUBLIC);
            $method->setDocBlock('@return null');
            $class->addMethodFromGenerator($method);
            $method = new \Zend\Code\Generator\MethodGenerator('setUpdatedAt', ['value'], \Zend\Code\Generator\PropertyGenerator::FLAG_PUBLIC);
            $method->setDocBlock('@return null');
            $class->addMethodFromGenerator($method);
        }
        // Set use soft delete trait if deleted_at
        if (in_array('deleted_at', $columns)) {
            $class->addTrait('SoftDeletingTrait');
            $prop = new \Zend\Code\Generator\PropertyGenerator('dates', ['deleted_at'], \Zend\Code\Generator\PropertyGenerator::FLAG_PROTECTED);
            $prop->setDocBlock('@var array');
            $class->addPropertyFromGenerator($prop);
            $class->addUse('Illuminate\\Database\\Eloquent\\SoftDeletingTrait');
        }
        $method = new \Zend\Code\Generator\MethodGenerator('getDates', [], \Zend\Code\Generator\PropertyGenerator::FLAG_PUBLIC, 'return [];');
        $method->setDocBlock('@return null');
        $class->addMethodFromGenerator($method);
        // Set enums
        foreach ($enums as $enumColName => $values) {
            foreach ($values as $value) {
                if (is_bool($value)) {
                    $name = $value === TRUE ? 'yes' : 'no';
                    $prop = new \Zend\Code\Generator\PropertyGenerator(strtoupper($enumColName . '_' . $name), (int) $value);
                } else {
                    $prop = new \Zend\Code\Generator\PropertyGenerator(strtoupper($enumColName . '_' . $value), $value);
                }
                $prop->setConst(true);
                $class->addPropertyFromGenerator($prop);
            }
            $method = new \Zend\Code\Generator\MethodGenerator('get' . ucfirst($enumColName) . 'Values', [], \Zend\Code\Generator\PropertyGenerator::FLAG_STATIC);
            $method->setDocBlock('@return array');
            $body = 'return [';
            foreach ($values as $value) {
                if (is_bool($value)) {
                    $name = $value === TRUE ? 'yes' : 'no';
                } else {
                    $name = $value;
                }
                $body .= "\r\n" . '    ' . "'" . $name . "'" . ' => self::' . strtoupper($enumColName . '_' . $name) . ',';
            }
            $body .= "\r\n" . '];';
            $method->setBody($body);
            $class->addMethodFromGenerator($method);
        }
        $builder = new PathBuilder();
        $builder->make_path($path);
        file_put_contents($path, '<?php' . "\r\n" . $class->generate());
        $output->writeln('<info>write</info>: ' . $path);
        // Now that we wrote the eloquent class
        // Let's build the model validator class
        $class = new ClassGenerator($modelName . 'Validator', $moduleName . '\\Validator', null, 'AbstractFieldset', ['InputFilterProviderInterface'], [], []);
        $class->addUse('MdoBundle\\Form\\AbstractFieldset');
        $class->addUse('MdoBundle\\Validator\\ValidatorTrait\\ValidationRulesTrait');
        $class->addUse('Zend\\InputFilter\\InputFilterProviderInterface');
        $class->addUse('Zend\\Mvc\\I18n\\Translator');
        $class->addTrait('ValidationRulesTrait');
        $codeName = strtolower($modelName);
        $body = <<<phpCode
parent::__construct('{$codeName}');

\$this->validationRules = [

phpCode;
        foreach ($fillable as $item) {
            $body .= <<<phpCode
    '{$item}' => [
        'required',
        'validators' => [
            [
                'name' => 'NotEmpty',
                'break_chain_on_failure' => true,
                'options' => [
                    'message' => \$translator->translate('You must provide the field {$item}'),
                ],
            ],
        ]
    ],

phpCode;
        }
        $body .= <<<phpCode
];

return \$this->addElements([

phpCode;
        foreach ($fillable as $item) {
            $body .= <<<phpCode
    '{$item}',

phpCode;
        }
        $body .= <<<phpCode
]);
phpCode;
        $class->addMethod('__construct', [new ParameterGenerator('translator', 'Translator')], [], $body);
        $path = new PathBuilder();
        $path = $path->addPart('module')->addPart($moduleName)->addPart('src')->addPart($moduleName)->addPart('Validator')->addPart($modelName . 'Validator.php')->getPath();
        if (file_exists($path)) {
            throw new \RuntimeException('A file with the same model validator name already exists: ' . $path);
        }
        file_put_contents($path, '<?php' . "\r\n" . $class->generate());
        $output->writeln('<info>write</info>: ' . $path);
    }