Skip to content

Commit

Permalink
Merge pull request #300 from schmunk42/feature/dev-elias
Browse files Browse the repository at this point in the history
Features
  • Loading branch information
schmunk42 authored Mar 26, 2024
2 parents 000a425 + 38b96a8 commit c24c2c0
Show file tree
Hide file tree
Showing 40 changed files with 1,096 additions and 693 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/docker-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,9 @@ jobs:
cd tests
make all
make test
- name: 'Upload Test Report'
uses: actions/upload-artifact@v4
with:
path: tests/_output
retention-days: 7
49 changes: 44 additions & 5 deletions src/commands/BatchController.php
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,16 @@ class BatchController extends Controller
*/
public $enableI18N = true;

/**
* @var bool whether to enable or disable the pluralization of the models name
*/
public $disablePluralization = false;

/**
* @var string prefix to prepend to the many many relation methods
*/
public $modelManyManyRelationSuffix = '';

/**
* @var bool whether the entity names will be singular or the same as the table name
*/
Expand Down Expand Up @@ -299,13 +309,26 @@ class BatchController extends Controller
* @var bool This indicates whether the generator should generate attribute hints by using the comments of the corresponding DB columns
*/
public $modelGenerateHintsFromComments = true;

/**
* @var bool Generate Relations from Current Schema
*/
public $modelGenerateRelationsFromCurrentSchema = true;

public $modelTranslationTableAdditions = ['name' => 'meta', 'fallbackLanguage' => false];

/**
* Whether the copy functionality for a crud should be created or not
*/
public $crudEnableCopy = true;

/**
* @var array application configuration for creating temporary applications
*/
protected $appConfig;

/**
* @var instance of class schmunk42\giiant\generators\model\Generator
* @var \schmunk42\giiant\generators\model\Generator instance of class schmunk42\giiant\generators\model\Generator
*/
protected $modelGenerator;

Expand Down Expand Up @@ -345,6 +368,8 @@ public function options($id)
'modelRemoveDuplicateRelations',
'modelCacheRelationsData',
'modelGenerateRelations',
'modelGenerateRelationsFromCurrentSchema',
'modelTranslationTableAdditions',
'modelGenerateJunctionRelationMode',
'modelGenerateQuery',
'modelQueryNamespace',
Expand All @@ -367,7 +392,9 @@ public function options($id)
'crudOverwriteSearchModelClass',
'crudOverwriteRestControllerClass',
'crudOverwriteControllerClass',
'generateAccessFilterMigrations'
'generateAccessFilterMigrations',
'disablePluralization',
'crudEnableCopy'
]
);
}
Expand Down Expand Up @@ -463,13 +490,17 @@ public function actionModels()
'removeDuplicateRelations' => $this->modelRemoveDuplicateRelations,
'cacheRelationsData' => $this->modelCacheRelationsData,
'generateRelations' => $this->modelGenerateRelations,
'generateRelationsFromCurrentSchema' => $this->modelGenerateRelationsFromCurrentSchema,
'translationTableAdditions' => $this->modelTranslationTableAdditions,
'generateJunctionRelationMode' => $this->modelGenerateJunctionRelationMode,
'tableNameMap' => $this->tableNameMap,
'generateQuery' => $this->modelGenerateQuery,
'queryNs' => $this->modelQueryNamespace,
'queryBaseClass' => $this->modelQueryBaseClass,
'generateLabelsFromComments' => $this->modelGenerateLabelsFromComments,
'generateHintsFromComments' => $this->modelGenerateHintsFromComments,
'disablePluralization' => $this->disablePluralization,
'manyManyRelationSuffix' => $this->modelManyManyRelationSuffix
];
$route = 'gii/giiant-model';

Expand Down Expand Up @@ -540,6 +571,9 @@ public function actionCruds()
'gridMaxColumns' => $this->crudGridMaxColumns,
'generateAccessFilterMigrations' => $this->generateAccessFilterMigrations,
'actionButtonColumnPosition' => $this->crudActionButtonColumnPosition,
'disablePluralization' => $this->disablePluralization,
'gridMaxColumns' => $this->crudGridMaxColumns,
'enableCopy' => $this->crudEnableCopy
];
$route = 'gii/giiant-crud';
$app = \Yii::$app;
Expand Down Expand Up @@ -612,9 +646,14 @@ private function closeTempAppConnections(Application $app)
// since we don't know if there are any other than the "known" modelDb
if (isset($app->components)) {
foreach ($app->components as $cid => $component) {
$cObj = $app->get($cid);
if ($cObj instanceof \yii\db\Connection) {
$cObj->close();
try {
$cObj = $app->get($cid);
if ($cObj instanceof \yii\db\Connection) {
$cObj->close();
}
} catch (\Throwable $e) {
// ignore because we don't know if the component is a db connection
Yii::warning($e->getMessage());
}
}
}
Expand Down
118 changes: 109 additions & 9 deletions src/generators/crud/Generator.php
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,11 @@ class Generator extends \yii\gii\generators\crud\Generator
*/
public $fixOptions = '';

/**
* @var bool whether to enable or disable the pluralization of the models name
*/
public $disablePluralization = false;

/**
* @var string form field for selecting and loading saved gii forms
*/
Expand All @@ -158,6 +163,10 @@ class Generator extends \yii\gii\generators\crud\Generator

private $_p = [];

public $translateRelations = ['translation', 'translation_meta'];

public $enableCopy = true;

/**
* {@inheritdoc}
*/
Expand Down Expand Up @@ -230,6 +239,7 @@ public function rules()
'generateAccessFilterMigrations',
'singularEntities',
'modelMessageCategory',
'enableCopy'
],
'safe',
],
Expand Down Expand Up @@ -270,6 +280,7 @@ public function formAttributes()
'accessFilter',
'singularEntities',
'modelMessageCategory',
'enableCopy'
];
}

Expand Down Expand Up @@ -305,20 +316,20 @@ public function getControllerID()
public function getModuleId()
{
if (!$this->moduleNs) {
$controllerNs = \yii\helpers\StringHelper::dirname(ltrim($this->controllerClass, '\\'));
$this->moduleNs = \yii\helpers\StringHelper::dirname(ltrim($controllerNs, '\\'));
$controllerNs = StringHelper::dirname(ltrim($this->controllerClass, '\\'));
$this->moduleNs = StringHelper::dirname(ltrim($controllerNs, '\\'));
}

return \yii\helpers\StringHelper::basename($this->moduleNs);
return StringHelper::basename($this->moduleNs);
}

public function generate()
{
$accessDefinitions = require $this->getTemplatePath().'/access_definition.php';

$this->controllerNs = \yii\helpers\StringHelper::dirname(ltrim($this->controllerClass, '\\'));
$this->moduleNs = \yii\helpers\StringHelper::dirname(ltrim($this->controllerNs, '\\'));
$controllerName = substr(\yii\helpers\StringHelper::basename($this->controllerClass), 0, -10);
$this->controllerNs = StringHelper::dirname(ltrim($this->controllerClass, '\\'));
$this->moduleNs = StringHelper::dirname(ltrim($this->controllerNs, '\\'));
$controllerName = substr(StringHelper::basename($this->controllerClass), 0, -10);

if ($this->singularEntities) {
$this->modelClass = Inflector::singularize($this->modelClass);
Expand All @@ -345,7 +356,7 @@ public function generate()
}

$files[] = new CodeFile($baseControllerFile, $this->render('controller.php', ['accessDefinitions' => $accessDefinitions]));
$params['controllerClassName'] = \yii\helpers\StringHelper::basename($this->controllerClass);
$params['controllerClassName'] = StringHelper::basename($this->controllerClass);

if ($this->overwriteControllerClass || !is_file($controllerFile)) {
$files[] = new CodeFile($controllerFile, $this->render('controller-extended.php', $params));
Expand All @@ -365,12 +376,32 @@ public function generate()
$viewPath = $this->getViewPath();
$templatePath = $this->getTemplatePath().'/views';

$model = Yii::createObject($this->modelClass);
if (array_key_exists('crud-form', $model->scenarios())) {
$model->setScenario('crud-form');
} else {
$model->setScenario('crud');
}

$safeAttributes = $model->safeAttributes();
if (empty($safeAttributes)) {
$model->setScenario('default');
$safeAttributes = $model->safeAttributes();
}
if (empty($safeAttributes)) {
$safeAttributes = $model::getTableSchema()->columnNames;
}

foreach (scandir($templatePath) as $file) {
if (empty($this->searchModelClass) && $file === '_search.php') {
if ($file === '_search.php' && !$this->getRenderWithSearch()) {
continue;
}
if (is_file($templatePath.'/'.$file) && pathinfo($file, PATHINFO_EXTENSION) === 'php') {
$files[] = new CodeFile("$viewPath/$file", $this->render("views/$file", ['permisions' => $permisions]));
$files[] = new CodeFile("$viewPath/$file", $this->render("views/$file", [
'model' => $model,
'safeAttributes' => $safeAttributes,
'accessDefinitions' => $accessDefinitions
]));
}
}

Expand Down Expand Up @@ -462,4 +493,73 @@ public function var_export54($var, $indent = '')
return var_export($var, true);
}
}

/**
* @return array
* @throws \yii\base\InvalidConfigException
*/
public function generateSearchRules()
{

$rules = parent::generateSearchRules();
$model = \Yii::createObject($this->modelClass);
foreach ($model->behaviors() as $key => $behavior) {
if (!empty($behavior['translationAttributes'])) {
$rules[] = "[['" . implode("', '", $behavior['translationAttributes']) . "'], 'safe']";
}
}
return $rules;
}

/**
* @return array
* @throws \yii\base\InvalidConfigException
*/
public function generateSearchConditions()
{

$searchConditions = parent::generateSearchConditions();
$model = \Yii::createObject($this->modelClass);
foreach ($model->behaviors() as $key => $behavior) {
if (!empty($behavior['translationAttributes'])) {
foreach ($behavior['translationAttributes'] as $translationAttribute) {
$searchConditions[] = "\$query->andFilterWhere(['like','{$translationAttribute}', \$this->$translationAttribute]);";
}
}
}
return $searchConditions;
}


/**
* @return array
*/
public function getTranslationRelationModels()
{
$translationRelationModels = [];
foreach ($this->translateRelations as $translateRelation) {
$translationRelationModels[] = $this->modelClass . Inflector::camelize($translateRelation);
}
return $translationRelationModels;
}

/**
* @return string
*/
public function getTranslationModelClass() {
return '\\' . $this->modelClass . Inflector::camelize('translation');
}

/**
* @return bool
* @throws \yii\base\InvalidConfigException
*/
public function getHasTranslationRelation() {
return isset(\Yii::createObject($this->modelClass)->behaviors()['translation']);
}

public function getRenderWithSearch()
{
return $this->indexWidgetType !== 'grid' && $this->searchModelClass !== '';
}
}
36 changes: 21 additions & 15 deletions src/generators/crud/ModelTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public function getModelByTableName($name)
*
* return values can be filtered by types 'belongs_to', 'many_many', 'has_many', 'has_one', 'pivot'
*
* @param ActiveRecord $modelClass
* @param \yii\db\ActiveRecord $modelClass
* @param array $types
*
* @return array
Expand All @@ -73,13 +73,15 @@ public function getModelRelations($modelClass, $types = [])
$reflector = new \ReflectionClass($modelClass);
$model = new $modelClass();
$stack = [];
$modelGenerator = new ModelGenerator();
$modelGenerator = new ModelGenerator([
'disablePluralization' => $this->disablePluralization
]);
foreach ($reflector->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
if (in_array(substr($method->name, 3), $this->skipRelations)) {
if (in_array(substr($method->name, 3), $this->skipRelations, true)) {
continue;
}
// look for getters
if (substr($method->name, 0, 3) !== 'get') {
if (strpos($method->name, 'get') !== 0) {
continue;
}
// skip class specific getters
Expand All @@ -90,7 +92,7 @@ public function getModelRelations($modelClass, $types = [])
'getAttribute',
'getAttributeLabel',
'getAttributeHint',
'getOldAttribute',
'getOldAttribute',
'getErrorSummary',
];
if (in_array($method->name, $skipMethods)) {
Expand All @@ -117,13 +119,17 @@ public function getModelRelations($modelClass, $types = [])
$relationType = 'has_many';
}
// if types is empty, return all types -> no filter
if ((count($types) == 0) || in_array($relationType, $types)) {
$name = $modelGenerator->generateRelationName(
[$relation],
$model->getTableSchema(),
substr($method->name, 3),
$relation->multiple
);
if ((count($types) === 0) || in_array($relationType, $types, true)) {
if ($this->disablePluralization) {
$name = str_replace('get','', $method->name);
} else {
$name = $modelGenerator->generateRelationName(
[$relation],
$model->getTableSchema(),
substr($method->name, 3),
$relation->multiple
);
}
$stack[$name] = $relation;
}
}
Expand All @@ -146,6 +152,7 @@ public function getColumnByAttribute($attribute, $model = null)
$model = $this;
}


// omit schema for NOSQL models
if (method_exists($model,'getTableSchema') && $model->getTableSchema()) {
return $model->getTableSchema()->getColumn($attribute);
Expand All @@ -164,12 +171,12 @@ public function getRelationByColumn($model, $column, $types = ['belongs_to', 'ma
$relations = $this->getModelRelations($model, $types);
foreach ($relations as $relation) {
// TODO: check multiple link(s)
if ($relation->link && reset($relation->link) == $column->name) {
if ($relation->link && reset($relation->link) === $column->name) {
return $relation;
}
}

return;
return null;
}

public function createRelationRoute($relation, $action)
Expand All @@ -179,7 +186,6 @@ public function createRelationRoute($relation, $action)
'-',
true
).'/'.$action;

return $route;
}

Expand Down
Loading

0 comments on commit c24c2c0

Please sign in to comment.