Skip to content

Commit

Permalink
Add "create:repository" command (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
rougin authored Oct 4, 2024
1 parent 5ee9957 commit a184c5e
Show file tree
Hide file tree
Showing 11 changed files with 425 additions and 10 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ combustor.yml
composer.lock
tests/Fixture/Sample/controllers
tests/Fixture/Sample/models
tests/Fixture/Sample/repositories
tests/Fixture/Sample/views
vendor
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ All notable changes to `Combustor` will be documented in this file.
- Command for creating `combustor.yml` configuration file
- Fields that can be excluded through `excluded_files`
- Specify customized `application` path using `app_path`
- `create:repository` for creating Entity Repositories

### Changed
- Code coverage provider to `Codecov`
Expand Down
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,23 @@ Create a new model.
$ vendor/bin/combustor create:model users --wildfire
```

### `create:repository`

Create a new entity repository.

**Arguments**

* `table` - name of the database table

**Example**

``` bash
$ vendor/bin/combustor create:repository users
```

> [!NOTE]
> This command is only applicable to a [Doctrine](https://roug.in/credo) implementation.
### `create:view`

Create view templates.
Expand Down Expand Up @@ -185,6 +202,9 @@ Create a new HTTP controller, model, and view templates.
$ vendor/bin/combustor create:scaffold users --bootstrap --wildfire
```

> [!NOTE]
> If `--doctrine` is selected, the command will also execute the `create:repository` command.
### `install:doctrine`

Install the [Doctrine](https://roug.in/credo/) package.
Expand Down
3 changes: 2 additions & 1 deletion TODO.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
[ ] --force
[x] custom fields
- [ ] email
[ ] multi relations
[ ] multi relations
[ ] create:repository
1 change: 1 addition & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ parameters:
- tests/Fixture/Plates
- tests/Fixture/Sample/controllers
- tests/Fixture/Sample/models
- tests/Fixture/Sample/repositories
- tests/Fixture/Sample/views
scanDirectories:
- vendor/rougin/codeigniter/src
Expand Down
6 changes: 6 additions & 0 deletions src/Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Rougin\Classidy\Generator;
use Rougin\Combustor\Template\Controller;
use Rougin\Combustor\Template\Doctrine\Model as DoctrineModel;
use Rougin\Combustor\Template\Repository;
use Rougin\Combustor\Template\Wildfire\Model as WildfireModel;

/**
Expand Down Expand Up @@ -146,6 +147,11 @@ protected function getTemplate($type)
return new WildfireModel($table, $cols, $this->excluded);
}

if ($this->name === 'create:repository')
{
return new Repository($table, $cols, $this->excluded);
}

return new Controller($table, $type);
}
}
60 changes: 60 additions & 0 deletions src/Commands/CreateRepo.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

namespace Rougin\Combustor\Commands;

use Rougin\Combustor\Command;
use Rougin\Combustor\Inflector;

/**
* @package Combustor
*
* @author Rougin Gutib <[email protected]>
*/
class CreateRepo extends Command
{
/**
* @var string
*/
protected $name = 'create:repository';

/**
* @var string
*/
protected $description = 'Create a new entity repository';

/**
* Executes the command.
*
* @return integer
*/
public function run()
{
/** @var string */
$table = $this->getArgument('table');

// Create the repository file -------------------
$name = Inflector::singular($table);

$name = ucfirst(Inflector::singular($table));

$path = $this->path . '/repositories/';

if (! is_dir($path))
{
mkdir($path);
}

$file = $path . $name . '_repository.php';

$plate = $this->getTemplate(self::TYPE_DOCTRINE);

$plate = $this->maker->make($plate);

file_put_contents($file, $plate);
// ----------------------------------------------

$this->showPass('Repository successfully created!');

return self::RETURN_SUCCESS;
}
}
6 changes: 6 additions & 0 deletions src/Commands/CreateScaffold.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ public function run()
$this->runCommand('create:views', $input);
// ----------------------------------------

// Execute the "create:repository" command ----
$input = array('table' => $table);

$this->runCommand('create:repository', $input);
// --------------------------------------------

return Command::RETURN_SUCCESS;
}
}
193 changes: 193 additions & 0 deletions src/Template/Repository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
<?php

namespace Rougin\Combustor\Template;

use Rougin\Classidy\Classidy;
use Rougin\Classidy\Method;
use Rougin\Combustor\Inflector;

/**
* @package Combustor
*
* @author Rougin Gutib <[email protected]>
*/
class Repository extends Classidy
{
/**
* @var \Rougin\Describe\Column[]
*/
protected $cols;

/**
* @var string[]
*/
protected $excluded = array();

/**
* @param string $table
* @param \Rougin\Describe\Column[] $cols
* @param string[] $excluded
*/
public function __construct($table, $cols, $excluded = array())
{
$this->cols = $cols;

$this->excluded = $excluded;

$this->init($table);
}

/**
* @param string $table
*
* @return void
*/
public function init($table)
{
$model = ucfirst(Inflector::singular($table));

$this->setName($model . '_repository');
$this->extendsTo('Rougin\Credo\Repository');

$comment = '@extends \Rougin\Credo\Repository<\\' . $model . '>';
$this->setComment($comment);

$this->addClassProperty('db', 'CI_DB_query_builder')->asTag();

$method = new Method('create');
$method->addArrayArgument('data', 'array<string, mixed>');
$method->addClassArgument('entity', '\\' . $model);
$this->addMethod($method->asTag());

$method = new Method('delete');
$method->addClassArgument('entity', '\\' . $model);
$this->addMethod($method->asTag());

$method = new Method('find');
$method->setReturn('\\' . $model . '|null');
$method->addIntegerArgument('id');
$this->addMethod($method->asTag());

$method = new Method('get');
$method->setReturn('\\' . $model . '[]');
$method->addIntegerArgument('limit', true);
$method->addIntegerArgument('offset', true);
$this->addMethod($method->asTag());

$method = new Method('set');
$method->setReturn('\\' . $model);
$method->addArrayArgument('data', 'array<string, mixed>');
$method->addClassArgument('entity', '\\' . $model);
$method->addIntegerArgument('id', true);
$this->addMethod($method->asTag());

$method = new Method('update');
$method->addClassArgument('entity', '\\' . $model);
$method->addArrayArgument('data', 'array<string, mixed>');
$this->addMethod($method->asTag());

$this->setExistsMethod();

$this->setSetMethod($table);
}

/**
* @return void
*/
protected function setExistsMethod()
{
$method = new Method('exists');

$method->setReturn('boolean');

$method->addArrayArgument('data', 'array<string, mixed>');

$method->addIntegerArgument('id', true);

$method->setCodeLine(function ($lines)
{
$lines[] = '// Specify logic here if applicable ---';
$lines[] = '// ------------------------------------';
$lines[] = '';
$lines[] = 'return false;';

return $lines;
});

$this->addMethod($method);
}

/**
* @param string $table
*
* @return void
*/
protected function setSetMethod($table)
{
$model = ucfirst(Inflector::singular($table));

$method = new Method('set');

$method->setReturn($model);
$method->addArrayArgument('data', 'array<string, mixed>');
$method->addClassArgument('entity', $model);
$method->addIntegerArgument('id', true);

$cols = $this->cols;

$method->setCodeLine(function ($lines) use ($cols)
{
$lines[] = '// List editable fields from table ---';

foreach ($cols as $index => $col)
{
$name = $col->getField();

if ($col->isPrimaryKey() || in_array($name, $this->excluded))
{
continue;
}

$type = $col->getDataType();

if ($col->isNull())
{
$type = $type . '|null';
}

$lines[] = '/** @var ' . $type . ' */';
$lines[] = '$' . $name . ' = $data[\'' . $name . '\'];';

if ($col->isNull())
{
$lines[] = 'if ($' . $name . ')';
$lines[] = '{';
$lines[] = ' $entity->set_' . $name . '($' . $name . ');';
$lines[] = '}';
}
else
{
$lines[] = '$entity->set_' . $name . '($' . $name . ');';
}

if (array_key_exists($index + 1, $cols))
{
$next = $cols[$index + 1];

if (! in_array($next->getField(), $this->excluded))
{
$lines[] = '';
}
}
}

$lines[] = '// -----------------------------------';
$lines[] = '';
$lines[] = 'return $entity;';

return $lines;
});

$this->addMethod($method);
}
}
Loading

0 comments on commit a184c5e

Please sign in to comment.