123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- <?php
- namespace Encore\Admin\Console;
- use Illuminate\Database\Eloquent\Model;
- class ResourceGenerator
- {
- /**
- * @var Model
- */
- protected $model;
- /**
- * @var array
- */
- protected $formats = [
- 'form_field' => "\$form->%s('%s', '%s')",
- 'show_field' => "\$show->%s('%s')",
- 'grid_column' => "\$grid->%s('%s')",
- ];
- /**
- * @var array
- */
- private $doctrineTypeMapping = [
- 'string' => [
- 'enum', 'geometry', 'geometrycollection', 'linestring',
- 'polygon', 'multilinestring', 'multipoint', 'multipolygon',
- 'point',
- ],
- ];
- /**
- * @var array
- */
- protected $fieldTypeMapping = [
- 'ip' => 'ip',
- 'email' => 'email|mail',
- 'password' => 'password|pwd',
- 'url' => 'url|link|src|href',
- 'mobile' => 'mobile|phone',
- 'color' => 'color|rgb',
- 'image' => 'image|img|avatar|pic|picture|cover',
- 'file' => 'file|attachment',
- ];
- /**
- * ResourceGenerator constructor.
- *
- * @param mixed $model
- */
- public function __construct($model)
- {
- $this->model = $this->getModel($model);
- }
- /**
- * @param mixed $model
- *
- * @return mixed
- */
- protected function getModel($model)
- {
- if ($model instanceof Model) {
- return $model;
- }
- if (!class_exists($model) || !is_string($model) || !is_subclass_of($model, Model::class)) {
- throw new \InvalidArgumentException("Invalid model [$model] !");
- }
- return new $model();
- }
- /**
- * @return string
- */
- public function generateForm()
- {
- $reservedColumns = $this->getReservedColumns();
- $output = '';
- foreach ($this->getTableColumns() as $column) {
- $name = $column->getName();
- if (in_array($name, $reservedColumns)) {
- continue;
- }
- $type = $column->getType()->getName();
- $default = $column->getDefault();
- $defaultValue = '';
- // set column fieldType and defaultValue
- switch ($type) {
- case 'boolean':
- case 'bool':
- $fieldType = 'switch';
- break;
- case 'json':
- case 'array':
- case 'object':
- $fieldType = 'text';
- break;
- case 'string':
- $fieldType = 'text';
- foreach ($this->fieldTypeMapping as $type => $regex) {
- if (preg_match("/^($regex)$/i", $name) !== 0) {
- $fieldType = $type;
- break;
- }
- }
- $defaultValue = "'{$default}'";
- break;
- case 'integer':
- case 'bigint':
- case 'smallint':
- case 'timestamp':
- $fieldType = 'number';
- break;
- case 'decimal':
- case 'float':
- case 'real':
- $fieldType = 'decimal';
- break;
- case 'datetime':
- $fieldType = 'datetime';
- $defaultValue = "date('Y-m-d H:i:s')";
- break;
- case 'date':
- $fieldType = 'date';
- $defaultValue = "date('Y-m-d')";
- break;
- case 'time':
- $fieldType = 'time';
- $defaultValue = "date('H:i:s')";
- break;
- case 'text':
- case 'blob':
- $fieldType = 'textarea';
- break;
- default:
- $fieldType = 'text';
- $defaultValue = "'{$default}'";
- }
- $defaultValue = $defaultValue ?: $default;
- $label = $this->formatLabel($name);
- $output .= sprintf($this->formats['form_field'], $fieldType, $name, $label);
- if (trim($defaultValue, "'\"")) {
- $output .= "->default({$defaultValue})";
- }
- $output .= ";\r\n";
- }
- return $output;
- }
- public function generateShow()
- {
- $output = '';
- foreach ($this->getTableColumns() as $column) {
- $name = $column->getName();
- // set column label
- $label = $this->formatLabel($name);
- $output .= sprintf($this->formats['show_field'], $name, $label);
- $output .= ";\r\n";
- }
- return $output;
- }
- public function generateGrid()
- {
- $output = '';
- foreach ($this->getTableColumns() as $column) {
- $name = $column->getName();
- $label = $this->formatLabel($name);
- $output .= sprintf($this->formats['grid_column'], $name, $label);
- $output .= ";\r\n";
- }
- return $output;
- }
- protected function getReservedColumns()
- {
- return [
- $this->model->getKeyName(),
- $this->model->getCreatedAtColumn(),
- $this->model->getUpdatedAtColumn(),
- 'deleted_at',
- ];
- }
- /**
- * Get columns of a giving model.
- *
- * @throws \Exception
- *
- * @return \Doctrine\DBAL\Schema\Column[]
- */
- protected function getTableColumns()
- {
- if (!$this->model->getConnection()->isDoctrineAvailable()) {
- throw new \Exception(
- 'You need to require doctrine/dbal: ~2.3 in your own composer.json to get database columns. '
- );
- }
- $table = $this->model->getConnection()->getTablePrefix().$this->model->getTable();
- /** @var \Doctrine\DBAL\Schema\MySqlSchemaManager $schema */
- $schema = $this->model->getConnection()->getDoctrineSchemaManager($table);
- // custom mapping the types that doctrine/dbal does not support
- $databasePlatform = $schema->getDatabasePlatform();
- foreach ($this->doctrineTypeMapping as $doctrineType => $dbTypes) {
- foreach ($dbTypes as $dbType) {
- $databasePlatform->registerDoctrineTypeMapping($dbType, $doctrineType);
- }
- }
- $database = null;
- if (strpos($table, '.')) {
- list($database, $table) = explode('.', $table);
- }
- return $schema->listTableColumns($table, $database);
- }
- /**
- * Format label.
- *
- * @param string $value
- *
- * @return string
- */
- protected function formatLabel($value)
- {
- return ucfirst(str_replace(['-', '_'], ' ', $value));
- }
- }
|