Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Features #300

Merged
merged 50 commits into from
Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
258bab4
Made generate relation from current schema an configurable option
eluhr Sep 7, 2021
acbe3b7
fixed model relation 1:n (pick one) n:m (pick many)
eluhr Sep 7, 2021
f846803
disable pluralization
eluhr Sep 20, 2021
780075d
updated name generation for relations
eluhr Oct 8, 2021
e98dc79
Disable pluralization via property and append an "N" instead for n:m
eluhr Oct 8, 2021
a4caba4
updated model and crud generation
eluhr Oct 11, 2021
a3d439c
updated model and query template
eluhr Oct 12, 2021
77457e8
updated relation name and fixed view.php template
eluhr Oct 13, 2021
10381a9
Fixed relation provider
eluhr Oct 20, 2021
d57f308
Added translatables in view and index
eluhr Nov 4, 2021
c3d7fd8
translatable for detail tab label
eluhr Dec 9, 2021
667f8e2
updated controller
eluhr Dec 14, 2021
d2a659f
Grid max columns
eluhr Jan 20, 2022
1def178
Merge commit '1dbc6ede1e69d0a1d5064f8826fa2f2961d93b23' into feature/…
eluhr Jan 24, 2022
0e3376a
introduce different optional scenarios
eluhr Jan 24, 2022
813ccb4
removed not needed code
eluhr Feb 1, 2022
b4a80b9
another scenario for detail relation
eluhr Feb 22, 2022
6a2bc96
bug fix for not defined relations
eluhr Feb 22, 2022
f2352c7
merge with parent method calls
eluhr Mar 23, 2023
6c539d7
Merge branch 'master' into dev/elias
eluhr Mar 24, 2023
890f9e9
Merge commit 'f2352c7b39d14f36de493d5c780d2b232229ddd7' into dev/elias
eluhr Mar 24, 2023
40c195b
catch throwable because a component can be wrong implemented
eluhr Mar 24, 2023
08bd2a5
cleanup controller
eluhr Mar 24, 2023
47bf621
added comment for model extended
eluhr Mar 24, 2023
51972d6
className() is deprecated since 2.0.14
eluhr Mar 24, 2023
059de44
adapt changes from other experiences
eluhr Mar 24, 2023
9cdfdeb
render searchfile only when needed
eluhr Mar 24, 2023
e5579bc
call static method
eluhr Mar 24, 2023
9dd40b6
no meta search
eluhr Mar 25, 2023
b5dd8ee
generate translation trait if needed
eluhr Mar 27, 2023
4cd779f
fixed relation column name
eluhr Mar 27, 2023
f33a31c
simplify form view(s)
eluhr Mar 27, 2023
86aeff6
Fix controller syntax and structure + remove deprecations and not nee…
eluhr Jan 4, 2024
ea3447b
Merge commit 'f33a31c10cbb709d06c4c407e877288e179fbe63' into feature/…
eluhr Jan 4, 2024
a20f236
small cleanups
eluhr Jan 4, 2024
16dae88
php 8 deprecation string in trim fix
eluhr Jan 4, 2024
633c6e9
use getters
eluhr Jan 4, 2024
56cb77f
remove overhead
eluhr Jan 4, 2024
8850223
use datetime imutable instead of db expression
eluhr Jan 4, 2024
3eff8bd
unique validator with targetClass so in works for translations
eluhr Jan 4, 2024
c69b994
break out of loop to prevent overloading
eluhr Jan 29, 2024
3b4b63a
Fixed access definitions
eluhr Jan 29, 2024
5d9faae
remove go back to avoid void targets -> redirect to home screen
eluhr Jan 30, 2024
98f4794
Allow clear for relations which are nullable
eluhr Jan 31, 2024
c8a1f1e
allow list crud
eluhr Feb 6, 2024
2e2eb45
to remove potential out of memory error
eluhr Feb 12, 2024
53c7802
fix label in forms
eluhr Mar 25, 2024
db9af44
introduce enable or disable copy function
eluhr Mar 26, 2024
d1f3358
Merge branch 'master' into feature/dev-elias
schmunk42 Mar 26, 2024
38b96a8
added artifacts
schmunk42 Mar 26, 2024
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
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
Loading