Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 58 additions & 8 deletions src/Command/GenerateModelCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()));
}
}

/**
Expand Down Expand Up @@ -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'));
}

Expand All @@ -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'],
];
}

Expand All @@ -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]
];
}
}
61 changes: 61 additions & 0 deletions src/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ class Config
*/
protected $config;

/**
* @var string
*/
protected $defaultSchemaName;

/**
* @var string
*/
protected $schemaName;

/**
* Config constructor.
* @param array $inputConfig
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
4 changes: 4 additions & 0 deletions src/EloquentModelBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
16 changes: 16 additions & 0 deletions src/Model/EloquentModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ class EloquentModel extends ClassModel
*/
protected $tableName;

protected $addClassPhpDocBlock = TRUE;

/**
* @param string $tableName
*
Expand All @@ -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();
}
}
}
3 changes: 1 addition & 2 deletions src/Processor/CustomPrimaryKeyProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions src/Processor/ExistenceCheckerProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -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()));
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/Processor/FieldProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [];
Expand Down
45 changes: 32 additions & 13 deletions src/Processor/RelationProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -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]
);
Expand All @@ -74,42 +75,60 @@ 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]
);
$this->addRelation($model, $relation);

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);
Expand Down
6 changes: 3 additions & 3 deletions src/Processor/TableNameProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down