diff --git a/src/Command/GenerateModelCommand.php b/src/Command/GenerateModelCommand.php index 103f236..afec0ea 100644 --- a/src/Command/GenerateModelCommand.php +++ b/src/Command/GenerateModelCommand.php @@ -8,6 +8,8 @@ use Krlove\EloquentModelGenerator\Generator; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; +use Illuminate\Support\Str; +use DB; /** * Class GenerateModelCommand @@ -49,10 +51,55 @@ public function __construct(Generator $generator, AppConfig $appConfig) public function fire() { $config = $this->createConfig(); - - $model = $this->generator->generateModel($config); - - $this->output->writeln(sprintf('Model %s generated', $model->getName()->getName())); + + if ($this->argument('class-name') === NULL) { + $tables = DB::connection()->getDoctrineSchemaManager()->listTables(); + $defaultSchema = DB::connection()->getConfig()['schema'] ?? ""; + foreach($tables as $table){ + $currentSchema = $table->getNamespaceName(); + $isManyToManyTable = FALSE; + if ($this->option('schema') === NULL || + ($this->option('schema') !== NULL && ($this->option('schema') === $currentSchema || ($currentSchema === NULL && $this->option('schema') === $defaultSchema))) + ) { + + //Check if the table is a many to many relationship (having its primary key composed of 2 foreign keys) + $primaryKey = $table->getPrimaryKey(); + $foreignKeys = $table->getForeignKeys(); + + if ($primaryKey !== NULL && count($foreignKeys) === 2) { + $primaryKeyColumnNames = $table->getPrimaryKeyColumns(); + $foreignKeysColumnNames = []; + foreach ($foreignKeys as $foreignKey) { + $foreignKeysColumnNames = array_merge($foreignKeysColumnNames,$foreignKey->getColumns()); + } + if (count(array_intersect($foreignKeysColumnNames,$primaryKeyColumnNames)) === 2) { + $isManyToManyTable = TRUE; + } + } + + if (!$isManyToManyTable) { + $tableName = $table->getShortestName($currentSchema); + $tableNameToSingular = Str::singular($tableName); + + + + //Does not generate a model for many to many tables + if ($tableNameToSingular !== $tableName) { + $modelName = ucfirst(Str::camel(Str::singular($tableNameToSingular))); + $config->set('class_name',$modelName); + $config->set('table_name',$tableName); + $config->setSchemaName($table->getNamespaceName() ?? ""); + $config->setDefaultSchemaName($defaultSchema); + $model = $this->generator->generateModel($config); + $this->output->writeln(sprintf('Model %s generated', $model->getName()->getName())); + } + } + } + } + } else { + $model = $this->generator->generateModel($config); + $this->output->writeln(sprintf('Model %s generated', $model->getName()->getName())); + } } /** @@ -80,9 +127,9 @@ protected function createConfig() } $config[$option[0]] = $value; } - + $config['db_types'] = $this->appConfig->get('eloquent_model_generator.db_types'); - + return new Config($config, $this->appConfig->get('eloquent_model_generator.model_defaults')); } @@ -92,7 +139,7 @@ protected function createConfig() protected function getArguments() { return [ - ['class-name', InputArgument::REQUIRED, 'Model class name'], + ['class-name', InputArgument::OPTIONAL, 'Model class name'], ]; } @@ -109,7 +156,10 @@ protected function getOptions() ['no-timestamps', 'ts', InputOption::VALUE_NONE, 'Set timestamps property to false', null], ['date-format', 'df', InputOption::VALUE_OPTIONAL, 'dateFormat property', null], ['connection', 'cn', InputOption::VALUE_OPTIONAL, 'Connection property', null], - ['backup', 'b', InputOption::VALUE_NONE, 'Backup existing model', null] + ['backup', 'b', InputOption::VALUE_NONE, 'Backup existing model', null], + ['force-table-name', 'ftn', InputOption::VALUE_NONE, 'Force tableName property to be always set', null], + ['schema', 's', InputOption::VALUE_OPTIONAL, 'Name of the database schema to generates models from, only used when class-name argument is not provided', null], + ['no-class-phpdoc-block','ncpb', InputOption::VALUE_OPTIONAL, 'Does not generate the class php doc', null] ]; } } diff --git a/src/Config.php b/src/Config.php index 77bab66..53b0cbe 100644 --- a/src/Config.php +++ b/src/Config.php @@ -13,6 +13,16 @@ class Config */ protected $config; + /** + * @var string + */ + protected $defaultSchemaName; + + /** + * @var string + */ + protected $schemaName; + /** * Config constructor. * @param array $inputConfig @@ -29,6 +39,30 @@ public function __construct($inputConfig, $appConfig = null) $this->config = $this->merge($inputConfig, $this->getBaseConfig()); } + public function getSchemaNameForQuery() + { + $schemaName = $this->getSchemaName(); + //Cannot add the default schema name set in the connection for query + if ($schemaName === $this->defaultSchemaName) { + $schemaName = ""; + } + if($schemaName !== ""){ + $schemaName .= "."; + } + return $schemaName; + } + + public function getSchemaName() + { + $schemaName = ""; + if (isset($this->schemaName) && $this->schemaName !== "") { + $schemaName = $this->schemaName; + } elseif (isset($this->defaultSchemaName) && $this->defaultSchemaName !== "") { + $schemaName = $this->defaultSchemaName; + } + return $schemaName; + } + /** * @param string $key * @param mixed|null $default @@ -39,6 +73,17 @@ public function get($key, $default = null) return $this->has($key) ? $this->config[$key] : $default; } + /** + * @param string $key + * @param mixed $value + */ + public function set($key, $value) + { + $this->config[$key] = $value; + } + + + /** * @param string $key * @return bool @@ -48,6 +93,22 @@ public function has($key) return isset($this->config[$key]); } + /** + * @param string $schemaName + */ + public function setSchemaName(string $schemaName) + { + $this->schemaName = $schemaName; + } + + /** + * @param string $defaultSchemaName + */ + public function setDefaultSchemaName(string $defaultSchemaName) + { + $this->defaultSchemaName = $defaultSchemaName; + } + /** * @param array $high * @param array $low diff --git a/src/EloquentModelBuilder.php b/src/EloquentModelBuilder.php index d46be28..8d9f7d0 100644 --- a/src/EloquentModelBuilder.php +++ b/src/EloquentModelBuilder.php @@ -39,6 +39,10 @@ public function createModel(Config $config) { $model = new EloquentModel(); + if($config->get('no_class_phpdoc_block') === false){ + $model->setAddClassPhpDocBlock(FALSE); + } + $this->prepareProcessors(); foreach ($this->processors as $processor) { diff --git a/src/Model/EloquentModel.php b/src/Model/EloquentModel.php index 8127a5b..e778d4b 100644 --- a/src/Model/EloquentModel.php +++ b/src/Model/EloquentModel.php @@ -15,6 +15,8 @@ class EloquentModel extends ClassModel */ protected $tableName; + protected $addClassPhpDocBlock = TRUE; + /** * @param string $tableName * @@ -34,4 +36,18 @@ public function getTableName() { return $this->tableName; } + + public function setAddClassPhpDocBlock(bool $addClassPhpDocBlock){ + $this->addClassPhpDocBlock = $addClassPhpDocBlock; + } + + /** + * Convert virtual properties and methods to DocBlock content + */ + protected function prepareDocBlock() + { + if($this->addClassPhpDocBlock === FALSE){ + parent::prepareDocBlock(); + } + } } diff --git a/src/Processor/CustomPrimaryKeyProcessor.php b/src/Processor/CustomPrimaryKeyProcessor.php index bfef8ca..95cc82d 100644 --- a/src/Processor/CustomPrimaryKeyProcessor.php +++ b/src/Processor/CustomPrimaryKeyProcessor.php @@ -43,8 +43,7 @@ public function process(EloquentModel $model, Config $config) { $schemaManager = $this->databaseManager->connection($config->get('connection'))->getDoctrineSchemaManager(); $prefix = $this->databaseManager->connection($config->get('connection'))->getTablePrefix(); - - $tableDetails = $schemaManager->listTableDetails($prefix . $model->getTableName()); + $tableDetails = $schemaManager->listTableDetails($config->getSchemaNameForQuery() . $prefix . $model->getTableName()); $primaryKey = $tableDetails->getPrimaryKey(); if ($primaryKey === null) { return; diff --git a/src/Processor/ExistenceCheckerProcessor.php b/src/Processor/ExistenceCheckerProcessor.php index 0dedac4..1698060 100644 --- a/src/Processor/ExistenceCheckerProcessor.php +++ b/src/Processor/ExistenceCheckerProcessor.php @@ -35,8 +35,8 @@ public function process(EloquentModel $model, Config $config) $schemaManager = $this->databaseManager->connection($config->get('connection'))->getDoctrineSchemaManager(); $prefix = $this->databaseManager->connection($config->get('connection'))->getTablePrefix(); - if (!$schemaManager->tablesExist($prefix . $model->getTableName())) { - throw new GeneratorException(sprintf('Table %s does not exist', $prefix . $model->getTableName())); + if (!$schemaManager->tablesExist($config->getSchemaNameForQuery() . $prefix . $model->getTableName())) { + throw new GeneratorException(sprintf('Table %s does not exist', $config->getSchemaNameForQuery() . $prefix . $model->getTableName())); } } diff --git a/src/Processor/FieldProcessor.php b/src/Processor/FieldProcessor.php index 08fd9af..0e9bddb 100644 --- a/src/Processor/FieldProcessor.php +++ b/src/Processor/FieldProcessor.php @@ -45,7 +45,7 @@ public function process(EloquentModel $model, Config $config) $schemaManager = $this->databaseManager->connection($config->get('connection'))->getDoctrineSchemaManager(); $prefix = $this->databaseManager->connection($config->get('connection'))->getTablePrefix(); - $tableDetails = $schemaManager->listTableDetails($prefix . $model->getTableName()); + $tableDetails = $schemaManager->listTableDetails($config->getSchemaNameForQuery() . $prefix . $model->getTableName()); $primaryColumnNames = $tableDetails->getPrimaryKey() ? $tableDetails->getPrimaryKey()->getColumns() : []; $columnNames = []; diff --git a/src/Processor/RelationProcessor.php b/src/Processor/RelationProcessor.php index 1446b1c..6fedbdd 100644 --- a/src/Processor/RelationProcessor.php +++ b/src/Processor/RelationProcessor.php @@ -57,15 +57,16 @@ public function process(EloquentModel $model, Config $config) $schemaManager = $this->databaseManager->connection($config->get('connection'))->getDoctrineSchemaManager(); $prefix = $this->databaseManager->connection($config->get('connection'))->getTablePrefix(); - $foreignKeys = $schemaManager->listTableForeignKeys($prefix . $model->getTableName()); + $foreignKeys = $schemaManager->listTableForeignKeys($config->getSchemaNameForQuery() . $prefix . $model->getTableName()); foreach ($foreignKeys as $tableForeignKey) { $tableForeignColumns = $tableForeignKey->getForeignColumns(); if (count($tableForeignColumns) !== 1) { continue; } - + $foreignTable = $schemaManager->listTableDetails($tableForeignKey->getForeignTableName()); + $foreignTableTableNameWithoutSchema = $this->removePrefix($prefix, $foreignTable->getShortestName($foreignTable->getNamespaceName())); $relation = new BelongsTo( - $this->removePrefix($prefix, $tableForeignKey->getForeignTableName()), + $this->removePrefix($prefix, $foreignTableTableNameWithoutSchema), $tableForeignKey->getLocalColumns()[0], $tableForeignColumns[0] ); @@ -74,27 +75,43 @@ public function process(EloquentModel $model, Config $config) $tables = $schemaManager->listTables(); foreach ($tables as $table) { - if ($table->getName() === $prefix . $model->getTableName()) { + + if ($table->getName() === $config->getSchemaNameForQuery() . $prefix . $model->getTableName()) { continue; } $foreignKeys = $table->getForeignKeys(); + $primaryKeyColumnNames = []; + if ($table->getPrimaryKey()) { + $primaryKeyColumnNames = $table->getPrimaryKeyColumns(); + } + + $foreignKeysColumnNames = []; + if(count($foreignKeys) === 2){ + foreach ($foreignKeys as $foreignKey) { + $foreignKeysColumnNames = array_merge($foreignKeysColumnNames,$foreignKey->getColumns()); + } + } + foreach ($foreignKeys as $name => $foreignKey) { - if ($foreignKey->getForeignTableName() === $prefix . $model->getTableName()) { + if ($foreignKey->getForeignTableName() === $config->getSchemaNameForQuery() . $prefix . $model->getTableName()) { $localColumns = $foreignKey->getLocalColumns(); if (count($localColumns) !== 1) { continue; } - - if (count($foreignKeys) === 2 && count($table->getColumns()) === 2) { + + if (count($foreignKeys) === 2 && count(array_intersect($foreignKeysColumnNames,$primaryKeyColumnNames)) === 2) { + $tableNameWithoutSchema = $table->getShortestName($table->getNamespaceName()); + $keys = array_keys($foreignKeys); $key = array_search($name, $keys) === 0 ? 1 : 0; $secondForeignKey = $foreignKeys[$keys[$key]]; - $secondForeignTable = $this->removePrefix($prefix, $secondForeignKey->getForeignTableName()); + $secondForeignTable = $schemaManager->listTableDetails($secondForeignKey->getForeignTableName()); + $secondForeignTableNameWithoutSchema = $this->removePrefix($prefix, $secondForeignTable->getShortestName($secondForeignTable->getNamespaceName())); $relation = new BelongsToMany( - $secondForeignTable, - $this->removePrefix($prefix, $table->getName()), + $secondForeignTableNameWithoutSchema, + $this->removePrefix($prefix, $tableNameWithoutSchema), $localColumns[0], $secondForeignKey->getLocalColumns()[0] ); @@ -102,14 +119,16 @@ public function process(EloquentModel $model, Config $config) break; } else { - $tableName = $this->removePrefix($prefix, $foreignKey->getLocalTableName()); + $foreignTable = $foreignKey->getLocalTable(); + $foreignTableNameWithoutSchema = $foreignTable->getShortestName($foreignTable->getNamespaceName()); + $foreignTableNameWithoutSchema = $this->removePrefix($prefix, $foreignTableNameWithoutSchema); $foreignColumn = $localColumns[0]; $localColumn = $foreignKey->getForeignColumns()[0]; if ($this->isColumnUnique($table, $foreignColumn)) { - $relation = new HasOne($tableName, $foreignColumn, $localColumn); + $relation = new HasOne($foreignTableNameWithoutSchema, $foreignColumn, $localColumn); } else { - $relation = new HasMany($tableName, $foreignColumn, $localColumn); + $relation = new HasMany($foreignTableNameWithoutSchema, $foreignColumn, $localColumn); } $this->addRelation($model, $relation); diff --git a/src/Processor/TableNameProcessor.php b/src/Processor/TableNameProcessor.php index 6e34a72..11c08f6 100644 --- a/src/Processor/TableNameProcessor.php +++ b/src/Processor/TableNameProcessor.php @@ -42,9 +42,9 @@ public function process(EloquentModel $model, Config $config) $model->setName(new ClassNameModel($className, $this->helper->getShortClassName($baseClassName))); $model->addUses(new UseClassModel(ltrim($baseClassName, '\\'))); $model->setTableName($tableName ?: $this->helper->getDefaultTableName($className)); - - if ($model->getTableName() !== $this->helper->getDefaultTableName($className)) { - $property = new PropertyModel('table', 'protected', $model->getTableName()); + + if ($model->getTableName() !== $this->helper->getDefaultTableName($className) || $config->get('force_table_name')) { + $property = new PropertyModel('table', 'protected', $config->getSchemaName().".".$model->getTableName()); $property->setDocBlock(new DocBlockModel('The table associated with the model.', '', '@var string')); $model->addProperty($property); }