diff --git a/Generator.php b/Generator.php new file mode 100644 index 0000000..d742bc0 --- /dev/null +++ b/Generator.php @@ -0,0 +1,665 @@ + + * @since 2.0 + */ +class Generator extends \yii\gii\generators\crud\Generator +{ + public $listFields; + public $formFields; + public $inputType; + + public $modelClass; + public $moduleID; + public $controllerClass; + public $baseControllerClass = 'yii\web\Controller'; + public $indexWidgetType = 'grid'; + public $searchModelClass = ''; + + public function fieldTypes() + { + return [ + 'text' => "text", + 'textarea' => "textarea", + 'password' => "password", + 'time' => "time", + 'date' => "date", + 'datetime' => "datetime", + 'dropDownList' => "dropDownList", + 'radioList' => "radioList", + 'checkbox' => "checkbox", + 'checkboxList' => "checkboxList", + 'select2' => 'Select2', + 'file' => 'upload file', + 'image' => 'upload image', + + // 'multipleInput' => "Input组", + // 'baiduUEditor' => "百度编辑器", + // 'image' => "图片上传", + // 'images' => "多图上传", + // 'file' => "文件上传", + // 'files' => "多文件上传", + // 'cropper' => "图片裁剪上传", + // 'latLngSelection' => "经纬度选择", + ]; + } + + /** + * @inheritdoc + */ + public function getName() + { + return 'Kartik CRUD Generator'; + } + + /** + * @inheritdoc + */ + public function getDescription() + { + return 'This generator generates a controller and views that implement CRUD (Create, Read, Update, Delete) + operations for the specified data model.'; + } + + /** + * @inheritdoc + */ + public function rules() + { + return array_merge(parent::rules(), [ + [['moduleID', 'controllerClass', 'modelClass', 'searchModelClass', 'baseControllerClass'], 'filter', 'filter' => 'trim'], + [['modelClass', 'controllerClass', 'baseControllerClass', 'indexWidgetType'], 'required'], + [['searchModelClass'], 'compare', 'compareAttribute' => 'modelClass', 'operator' => '!==', 'message' => 'Search Model Class must not be equal to Model Class.'], + [['modelClass', 'controllerClass', 'baseControllerClass', 'searchModelClass'], 'match', 'pattern' => '/^[\w\\\\]*$/', 'message' => 'Only word characters and backslashes are allowed.'], + [['modelClass'], 'validateClass', 'params' => ['extends' => BaseActiveRecord::className()]], + [['baseControllerClass'], 'validateClass', 'params' => ['extends' => Controller::className()]], + [['controllerClass'], 'match', 'pattern' => '/Controller$/', 'message' => 'Controller class name must be suffixed with "Controller".'], + [['controllerClass'], 'match', 'pattern' => '/(^|\\\\)[A-Z][^\\\\]+Controller$/', 'message' => 'Controller class name must start with an uppercase letter.'], + [['controllerClass', 'searchModelClass'], 'validateNewClass'], + [['indexWidgetType'], 'in', 'range' => ['grid', 'list']], + [['modelClass'], 'validateModelClass'], + [['moduleID'], 'validateModuleID'], + [['enableI18N'], 'boolean'], + [['messageCategory'], 'validateMessageCategory', 'skipOnEmpty' => false], + [['listFields', 'formFields', 'inputType'], 'safe'], + ]); + } + + /** + * @inheritdoc + */ + public function attributeLabels() + { + return array_merge(parent::attributeLabels(), [ + 'modelClass' => 'Model Class', + 'moduleID' => 'Module ID', + 'controllerClass' => 'Controller Class', + 'baseControllerClass' => 'Base Controller Class', + 'indexWidgetType' => 'Widget Used in Index Page', + 'searchModelClass' => 'Search Model Class', + ]); + } + + /** + * @inheritdoc + */ + public function hints() + { + return array_merge(parent::hints(), [ + 'modelClass' => 'This is the ActiveRecord class associated with the table that CRUD will be built upon. + You should provide a fully qualified class name, e.g., app\models\Post.', + 'controllerClass' => 'This is the name of the controller class to be generated. You should + provide a fully qualified namespaced class, .e.g, app\controllers\PostController. + The controller class name should follow the CamelCase scheme with an uppercase first letter', + 'baseControllerClass' => 'This is the class that the new CRUD controller class will extend from. + You should provide a fully qualified class name, e.g., yii\web\Controller.', + 'moduleID' => 'This is the ID of the module that the generated controller will belong to. + If not set, it means the controller will belong to the application.', + 'indexWidgetType' => 'This is the widget type to be used in the index page to display list of the models. + You may choose either GridView or ListView', + 'searchModelClass' => 'This is the name of the search model class to be generated. You should provide a fully + qualified namespaced class name, e.g., app\models\PostSearch.', + ]); + } + + /** + * @inheritdoc + */ + public function requiredTemplates() + { + return ['controller.php']; + } + + /** + * @inheritdoc + */ + public function stickyAttributes() + { + return array_merge(parent::stickyAttributes(), ['baseControllerClass', 'moduleID', 'indexWidgetType']); + } + + /** + * Checks if model class is valid + */ + public function validateModelClass() + { + /** @var ActiveRecord $class */ + $class = $this->modelClass; + $pk = $class::primaryKey(); + if (empty($pk)) { + $this->addError('modelClass', "The table associated with $class must have primary key(s)."); + } + } + + /** + * Checks if model ID is valid + */ + public function validateModuleID() + { + if (!empty($this->moduleID)) { + $module = Yii::$app->getModule($this->moduleID); + if ($module === null) { + $this->addError('moduleID', "Module '{$this->moduleID}' does not exist."); + } + } + } + + /** + * @inheritdoc + */ + public function generate() + { + $controllerFile = Yii::getAlias('@' . str_replace('\\', '/', ltrim($this->controllerClass, '\\')) . '.php'); + + $files = [ + new CodeFile($controllerFile, $this->render('controller.php')), + ]; + + if (!empty($this->searchModelClass)) { + $searchModel = Yii::getAlias('@' . str_replace('\\', '/', ltrim($this->searchModelClass, '\\') . '.php')); + $files[] = new CodeFile($searchModel, $this->render('search.php')); + } + + $viewPath = $this->getViewPath(); + $templatePath = $this->getTemplatePath() . '/views'; + foreach (scandir($templatePath) as $file) { + if (empty($this->searchModelClass) && $file === '_search.php') { + continue; + } + if (is_file($templatePath . '/' . $file) && pathinfo($file, PATHINFO_EXTENSION) === 'php') { + $files[] = new CodeFile("$viewPath/$file", $this->render("views/$file")); + } + } + + return $files; + } + + /** + * @return string the controller ID (without the module ID prefix) + */ + public function getControllerID() + { + $pos = strrpos($this->controllerClass, '\\'); + $class = substr(substr($this->controllerClass, $pos + 1), 0, -10); + + return Inflector::camel2id($class); + } + + /** + * @return string the action view file path + */ + public function getViewPath() + { + $module = empty($this->moduleID) ? Yii::$app : Yii::$app->getModule($this->moduleID); + + return $module->getViewPath() . '/' . $this->getControllerID(); + } + + public function getNameAttribute() + { + foreach ($this->getColumnNames() as $name) { + if (!strcasecmp($name, 'name') || !strcasecmp($name, 'title')) { + return $name; + } + } + /** @var \yii\db\ActiveRecord $class */ + $class = $this->modelClass; + $pk = $class::primaryKey(); + + return $pk[0]; + } + + /** + * Generates code for active field + * @param string $attribute + * @return string + */ + + public function generateActiveField($attribute) + { + $model = new $this->modelClass(); + $attributeLabels = $model->attributeLabels(); + $tableSchema = $this->getTableSchema(); + if ($tableSchema === false || !isset($tableSchema->columns[$attribute])) { + if (preg_match('/^(password|pass|passwd|passcode)$/i', $attribute)) { + return "'$attribute' => ['type' => TabularForm::INPUT_PASSWORD,'options' => ['placeholder' => 'Enter " . $attributeLabels[$attribute] . "...']],"; + //return "\$form->field(\$model, '$attribute')->passwordInput()"; + } else { + return "'$attribute' => ['type' => TabularForm::INPUT_TEXT, 'options' => ['placeholder' => 'Enter " . $attributeLabels[$attribute] . "...']],"; + //return "\$form->field(\$model, '$attribute')"; + } + } + $column = $tableSchema->columns[$attribute]; + $type = $this->inputType[$attribute]; + if ($type === 'radioList') { + //return "\$form->field(\$model, '$attribute')->checkbox()"; + return "'$attribute' => [ + 'type' => Form::INPUT_RADIO_LIST, + 'label' => '" . $attributeLabels[$attribute] . "', + 'items' => [true => 'Active', false => 'Inactive', 'ok'=> 'radioList'], + 'options' => ['inline' => true], + ],"; + + } elseif ($type === 'checkbox') { + return "'$attribute' => [ + 'type' => Form::INPUT_CHECKBOX, + 'label' => '" . $attributeLabels[$attribute] . "', + ],"; + } elseif ($type === 'checkboxList') { + return "'$attribute' => ['type' => Form::INPUT_CHECKBOX_LIST, + 'items'=>[ 'value1' => 'v1', 'value2' => 'v2'], + 'options'=>['text' => 'Please select', 'options' => ['value' => 'none', 'class' => 'prompt', 'label' => 'Select " . $attributeLabels[$attribute] . "']], + ],"; + } elseif ($type === 'dropDownList') { + return "'$attribute' => ['type' => Form::INPUT_DROPDOWN_LIST, + 'items'=>[ 'value1' => 'value 1', 'value2' =>'value 2'], + 'options'=>['text' => 'Please select', 'options' => ['value' => 'none', 'class' => 'prompt', 'label' => 'Select " . $attributeLabels[$attribute] . "']], + ],"; + } elseif ($type === 'text') { + return "'$attribute' => ['type' => Form::INPUT_TEXT, 'options' => ['placeholder' => 'Enter " . $attributeLabels[$attribute] . "...','rows' => 6]],"; + } elseif ($type === 'textarea') { + //return "\$form->field(\$model, '$attribute')->textarea(['rows' => 6])"; + return "'$attribute' => ['type' => Form::INPUT_TEXTAREA, 'options' => ['placeholder' => 'Enter " . $attributeLabels[$attribute] . "...','rows' => 6]],"; + } elseif ($type === 'date') { + return "'$attribute' => ['type' => Form::INPUT_WIDGET, 'widgetClass' => DateControl::classname(),'options' => ['type' => DateControl::FORMAT_DATE]],"; + } elseif ($type === 'time') { + return "'$attribute' => ['type' => Form::INPUT_WIDGET, 'widgetClass' => DateControl::classname(),'options' => ['type' => DateControl::FORMAT_TIME]],"; + } elseif ($type === 'datetime' || $type === 'timestamp') { + return "'$attribute' => ['type' => Form::INPUT_WIDGET, 'widgetClass' => DateControl::classname(),'options' => ['type' => DateControl::FORMAT_DATETIME]],"; + + } elseif ($type === 'select2') { + return "'$attribute' => [ + 'type' => Form::INPUT_WIDGET, + 'widgetClass' => '\kartik\select2\Select2', + 'options' => [ + 'data' => [true => 'Active', false => 'Inactive', 'ok' => 'radioList'], + 'pluginOptions' => [ + 'allowClear' => true, + 'closeOnSelect' => false, + 'tags' => true, + 'multiple' => true, + 'tokenSeparators' => [',', ' '], + // 'placeholder' => 'Select ...', + 'hint' => 'Type and select state', + ], + ], + ],"; + } elseif ($type === 'file') { + return "'$attribute' => ['type' => Form::INPUT_WIDGET, 'widgetClass' => FileInput::classname(), + 'options' => [ + 'options' => ['accept' => 'image/*', 'multiple' => true], + 'pluginOptions' => [ + // 'allowedFileExtensions' => ['csv'], + 'showUpload' => true, + 'browseLabel' => 'upload file', + 'removeLabel' => '', + 'showPreview' => true, + ], + ], + ],"; + } elseif ($type === 'image') { + return "'$attribute' => [ + 'type' => Form::INPUT_WIDGET, + 'widgetClass' => FileInput::classname(), + 'name' => 'attachment_3', + 'attribute' => 'attachment_1[]', + 'options' => [ + 'options' => ['accept' => 'image/*', 'multiple' => true], + 'pluginOptions' => [ + // 'allowedFileExtensions' => ['csv'], + 'showUpload' => true, + 'browseLabel' => 'upload image', + 'removeLabel' => '', + 'showPreview' => true, + ], + ], + ],"; + } elseif ($type === 'password') { + return "'$attribute' => [ + 'type' => Form::INPUT_PASSWORD, + 'options' => ['placeholder' => 'Enter Password...'] + ],"; + } else { + if (preg_match('/^(password|pass|passwd|passcode)$/i', $column->name)) { + $input = 'INPUT_PASSWORD'; + } else { + $input = 'INPUT_TEXT'; + } + if ($column->phpType !== 'string' || $column->size === null) { + //return "\$form->field(\$model, '$attribute')->$input()"; + return "'$attribute' => ['type' => Form::" . $input . ", 'options' => ['placeholder' => 'Enter " . $attributeLabels[$attribute] . "...']],"; + } else { + //return "\$form->field(\$model, '$attribute')->$input(['maxlength' => $column->size])"; + return "'$attribute' => ['type' => Form::" . $input . ", 'options' => ['placeholder' => 'Enter " . $attributeLabels[$attribute] . "...', 'maxlength' => " . $column->size . "]],"; + } + } + } + + /** + * Generates code for active search field + * @param string $attribute + * @return string + */ + public function generateActiveSearchField($attribute) + { + $tableSchema = $this->getTableSchema(); + if ($tableSchema === false) { + return "\$form->field(\$model, '$attribute')"; + } + $column = $tableSchema->columns[$attribute]; + if ($column->phpType === 'boolean') { + return "\$form->field(\$model, '$attribute')->checkbox()"; + } else { + return "\$form->field(\$model, '$attribute')"; + } + } + + /** + * Generates column format + * @param \yii\db\ColumnSchema $column + * @return string + */ + public function generateColumnFormat($column) + { + if ($column->phpType === 'tinyint') { + return 'boolean'; + } elseif ($column->type === 'text') { + return 'ntext'; + } elseif (stripos($column->name, 'time') !== false && $column->phpType === 'integer') { + return 'datetime'; + } elseif (stripos($column->name, 'email') !== false) { + return 'email'; + } elseif (stripos($column->name, 'url') !== false) { + return 'url'; + } else { + return 'text'; + } + } + + /** + * Generates validation rules for the search model. + * @return array the generated validation rules + */ + public function generateSearchRules() + { + if (($table = $this->getTableSchema()) === false) { + return ["[['" . implode("', '", $this->getColumnNames()) . "'], 'safe']"]; + } + $types = []; + foreach ($table->columns as $column) { + switch ($column->type) { + case Schema::TYPE_SMALLINT: + case Schema::TYPE_INTEGER: + case Schema::TYPE_BIGINT: + $types['integer'][] = $column->name; + break; + case Schema::TYPE_BOOLEAN: + $types['boolean'][] = $column->name; + break; + case Schema::TYPE_FLOAT: + case Schema::TYPE_DECIMAL: + case Schema::TYPE_MONEY: + $types['number'][] = $column->name; + break; + case Schema::TYPE_DATE: + case Schema::TYPE_TIME: + case Schema::TYPE_DATETIME: + case Schema::TYPE_TIMESTAMP: + default: + $types['safe'][] = $column->name; + break; + } + } + + $rules = []; + foreach ($types as $type => $columns) { + $rules[] = "[['" . implode("', '", $columns) . "'], '$type']"; + } + + return $rules; + } + + /** + * @return array searchable attributes + */ + public function getSearchAttributes() + { + return $this->getColumnNames(); + } + + /** + * Generates the attribute labels for the search model. + * @return array the generated attribute labels (name => label) + */ + public function generateSearchLabels() + { + /** @var \yii\base\Model $model */ + $model = new $this->modelClass(); + $attributeLabels = $model->attributeLabels(); + $labels = []; + foreach ($this->getColumnNames() as $name) { + if (isset($attributeLabels[$name])) { + $labels[$name] = $attributeLabels[$name]; + } else { + if (!strcasecmp($name, 'id')) { + $labels[$name] = 'ID'; + } else { + $label = Inflector::camel2words($name); + if (strcasecmp(substr($label, -3), ' id') === 0) { + $label = substr($label, 0, -3) . ' ID'; + } + $labels[$name] = $label; + } + } + } + + return $labels; + } + + /** + * Generates search conditions + * @return array + */ + public function generateSearchConditions() + { + $columns = []; + if (($table = $this->getTableSchema()) === false) { + $class = $this->modelClass; + /** @var \yii\base\Model $model */ + $model = new $class(); + foreach ($model->attributes() as $attribute) { + $columns[$attribute] = 'unknown'; + } + } else { + foreach ($table->columns as $column) { + $columns[$column->name] = $column->type; + } + } + + $likeConditions = []; + $hashConditions = []; + foreach ($columns as $column => $type) { + switch ($type) { + case Schema::TYPE_SMALLINT: + case Schema::TYPE_INTEGER: + case Schema::TYPE_BIGINT: + case Schema::TYPE_BOOLEAN: + case Schema::TYPE_FLOAT: + case Schema::TYPE_DECIMAL: + case Schema::TYPE_MONEY: + case Schema::TYPE_DATE: + case Schema::TYPE_TIME: + case Schema::TYPE_DATETIME: + case Schema::TYPE_TIMESTAMP: + $hashConditions[] = "'{$column}' => \$this->{$column},"; + break; + default: + $likeConditions[] = "->andFilterWhere(['like', '{$column}', \$this->{$column}])"; + break; + } + } + + $conditions = []; + if (!empty($hashConditions)) { + $conditions[] = "\$query->andFilterWhere([\n" + . str_repeat(' ', 12) . implode("\n" . str_repeat(' ', 12), $hashConditions) + . "\n" . str_repeat(' ', 8) . "]);\n"; + } + if (!empty($likeConditions)) { + $conditions[] = "\$query" . implode("\n" . str_repeat(' ', 12), $likeConditions) . ";\n"; + } + + return $conditions; + } + + /** + * Generates URL parameters + * @return string + */ + public function generateUrlParams() + { + /** @var ActiveRecord $class */ + $class = $this->modelClass; + $pks = $class::primaryKey(); + if (count($pks) === 1) { + if (is_subclass_of($class, 'yii\mongodb\ActiveRecord')) { + return "'id' => (string)\$model->{$pks[0]}"; + } else { + return "'id' => \$model->{$pks[0]}"; + } + } else { + $params = []; + foreach ($pks as $pk) { + if (is_subclass_of($class, 'yii\mongodb\ActiveRecord')) { + $params[] = "'$pk' => (string)\$model->$pk"; + } else { + $params[] = "'$pk' => \$model->$pk"; + } + } + + return implode(', ', $params); + } + } + + /** + * Generates action parameters + * @return string + */ + public function generateActionParams() + { + /** @var ActiveRecord $class */ + $class = $this->modelClass; + $pks = $class::primaryKey(); + if (count($pks) === 1) { + return '$id'; + } else { + return '$' . implode(', $', $pks); + } + } + + /** + * Generates parameter tags for phpdoc + * @return array parameter tags for phpdoc + */ + public function generateActionParamComments() + { + /** @var ActiveRecord $class */ + $class = $this->modelClass; + $pks = $class::primaryKey(); + if (($table = $this->getTableSchema()) === false) { + $params = []; + foreach ($pks as $pk) { + $params[] = '@param ' . (substr(strtolower($pk), -2) == 'id' ? 'integer' : 'string') . ' $' . $pk; + } + + return $params; + } + if (count($pks) === 1) { + return ['@param ' . $table->columns[$pks[0]]->phpType . ' $id']; + } else { + $params = []; + foreach ($pks as $pk) { + $params[] = '@param ' . $table->columns[$pk]->phpType . ' $' . $pk; + } + + return $params; + } + } + + /** + * Returns table schema for current model class or false if it is not an active record + * @return boolean|\yii\db\TableSchema + */ + public function getTableSchema() + { + /** @var ActiveRecord $class */ + $class = $this->modelClass; + if (is_subclass_of($class, 'yii\db\ActiveRecord')) { + return $class::getTableSchema(); + } else { + return false; + } + } + + /** + * @return array model column names + */ + public function getColumnNames() + { + /** @var ActiveRecord $class */ + $class = $this->modelClass; + if (is_subclass_of($class, 'yii\db\ActiveRecord')) { + return $class::getTableSchema()->getColumnNames(); + } else { + /** @var \yii\base\Model $model */ + $model = new $class(); + + return $model->attributes(); + } + } +} diff --git a/README.md b/README.md index 615b7a6..feee2f3 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,14 @@ +## Enhances: + +bulk-del brach. +1. add support more fieldtypes ,such as select2,file upload,checkbox,checkboxList,dropdowlist and so. +2. bulk delete on index page + +![image](https://raw.githubusercontent.com/zhangyc310/yii2-kartikgii/bulk-del/images/gii-types.png) + +![image](https://raw.githubusercontent.com/zhangyc310/yii2-kartikgii/bulk-del/images/bulk-del.png) +============= + I would like to apologize for not following up with this plugin because i has been migrate over to Laravel. However i would like to thanks everyone for using this plugin. Please do let me know is there any nice fork of this project, i will share to link for everyone here. yii2-kartikgii @@ -25,13 +36,15 @@ The preferred way to install this extension is through [composer](http://getcomp Either run ``` -$ php composer.phar require warrence/yii2-kartikgii "dev-master" +$ php composer.phar require zhangyc310/yii2-kartikgii "bulk-del" +//$ php composer.phar require warrence/yii2-kartikgii "dev-master" ``` or add ``` -"warrence/yii2-kartikgii": "dev-master" +"zhangyc310/yii2-kartikgii": "bulk-del" +//"warrence/yii2-kartikgii": "dev-master" ``` to the ```require``` section of your `composer.json` file. @@ -48,9 +61,14 @@ $config['modules']['gii']['class'] = 'yii\gii\Module'; ```php //Add this into backend/config/main-local.php +// $config['modules']['gii']['generators'] = [ - 'kartikgii-crud' => ['class' => 'warrence\kartikgii\crud\Generator'], + 'kartikgii-crud' => ['class' => 'zhangyc310\kartikgii\crud\Generator'], ]; + +// $config['modules']['gii']['generators'] = [ +// 'kartikgii-crud' => ['class' => 'warrence\kartikgii\crud\Generator'], +// ]; ``` ```php diff --git a/_form.php b/_form.php new file mode 100644 index 0000000..99f1249 --- /dev/null +++ b/_form.php @@ -0,0 +1,56 @@ +modelClass; +$safeAttributes = $model->safeAttributes(); +if (empty($safeAttributes)) { + $safeAttributes = $model->attributes(); +} + +echo " + +use yii\helpers\Html; +use kartik\widgets\ActiveForm; +use kartik\builder\Form; +use kartik\datecontrol\DateControl; +use kartik\widgets\FileInput +/** + * @var yii\web\View $this + * @var modelClass, '\\');?> $model + * @var yii\widgets\ActiveForm $form + */ +?> + +
+ + $form = ActiveForm::begin(['type' => ActiveForm::TYPE_HORIZONTAL]); echo Form::widget([ + + 'model' => $model, + 'form' => $form, + 'columns' => 1, + 'attributes' => [ + + + generateActiveField($attribute) . "\n\n";?> + + ] + + ]); + + echo Html::submitButton($model->isNewRecord ? Yii::t('app', 'Create') : Yii::t('app', 'Update'), + ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary'] + ); + ActiveForm::end(); ?> + +
diff --git a/_search.php b/_search.php new file mode 100644 index 0000000..d665ff2 --- /dev/null +++ b/_search.php @@ -0,0 +1,48 @@ + + +use yii\helpers\Html; +use yii\widgets\ActiveForm; + +/** + * @var yii\web\View $this + * @var searchModelClass, '\\') ?> $model + * @var yii\widgets\ActiveForm $form + */ +?> + + diff --git a/composer.json b/composer.json index f316b8c..0f83d4b 100644 --- a/composer.json +++ b/composer.json @@ -1,17 +1,17 @@ { - "name": "warrence/yii2-kartikgii", + "name": "zhangyc310/yii2-kartikgii", "description": "Gii Generator base on Kartik-V extension https://github.com/kartik-v", "authors": [ { - "name": "Warrence", + "name": "zhangyc", - "email": "warrence@gmail.com" + "email": "yqf0215@gmail.com" } ], "autoload": { "psr-4": { - "warrence\\kartikgii\\": "" + "zhangyc310\\kartikgii\\": "" } }, "require": { @@ -22,6 +22,6 @@ "kartik-v/yii2-helpers": "*", "kartik-v/yii2-builder": "*", "kartik-v/yii2-detail-view": "*", - "php": ">=5.3.0" + "php": ">=5.6" } } diff --git a/controller.php b/controller.php new file mode 100644 index 0000000..e8d3348 --- /dev/null +++ b/controller.php @@ -0,0 +1,187 @@ +controllerClass); +$modelClass = StringHelper::basename($generator->modelClass); +$searchModelClass = StringHelper::basename($generator->searchModelClass); +if ($modelClass === $searchModelClass) { + $searchModelAlias = $searchModelClass . 'Search'; +} + +/** @var ActiveRecordInterface $class */ +$class = $generator->modelClass; +$pks = $class::primaryKey(); +$urlParams = $generator->generateUrlParams(); +$actionParams = $generator->generateActionParams(); +$actionParamComments = $generator->generateActionParamComments(); + +echo " + +namespace controllerClass, '\\'));?>; + +use Yii; +use modelClass, '\\');?>; +searchModelClass)): ?> +use searchModelClass, '\\') . (isset($searchModelAlias) ? " as $searchModelAlias" : "");?>; + +use yii\data\ActiveDataProvider; + +use baseControllerClass, '\\');?>; +use yii\web\NotFoundHttpException; +use yii\filters\VerbFilter; + +/** + * implements the CRUD actions for model. + */ +class extends baseControllerClass) . "\n";?> +{ + public function behaviors() + { + return [ + 'verbs' => [ + 'class' => VerbFilter::className(), + 'actions' => [ + 'delete' => ['post'], + ], + ], + ]; + } + + /** + * Lists all models. + * @return mixed + */ + public function actionIndex() + { +searchModelClass)): ?> + $searchModel = new ; + $dataProvider = $searchModel->search(Yii::$app->request->getQueryParams()); + + return $this->render('index', [ + 'dataProvider' => $dataProvider, + 'searchModel' => $searchModel, + ]); + + $dataProvider = new ActiveDataProvider([ + 'query' => ::find(), + ]); + + return $this->render('index', [ + 'dataProvider' => $dataProvider, + ]); + + } + + public function actionDeleteAll($id) + { + + + ::deleteAll('id in (' . $id . ')'); + + return $this->redirect(Yii::$app->request->referrer); + } + + /** + * Displays a single model. + * + * @return mixed + */ + public function actionView() + { + $model = $this->findModel(); + + if ($model->load(Yii::$app->request->post()) && $model->save()) { + return $this->redirect(['view', 'id' => $model->getTableSchema()->primaryKey[0];?>]); + + } else { + return $this->render('view', ['model' => $model]); + } + } + + /** + * Creates a new model. + * If creation is successful, the browser will be redirected to the 'view' page. + * @return mixed + */ + public function actionCreate() + { + $model = new ; + + if ($model->load(Yii::$app->request->post()) && $model->save()) { + return $this->redirect(['view', ]); + } else { + return $this->render('create', [ + 'model' => $model, + ]); + } + } + + /** + * Updates an existing model. + * If update is successful, the browser will be redirected to the 'view' page. + * + * @return mixed + */ + public function actionUpdate() + { + $model = $this->findModel(); + + if ($model->load(Yii::$app->request->post()) && $model->save()) { + return $this->redirect(['index']); + } else { + return $this->render('update', [ + 'model' => $model, + ]); + } + } + + /** + * Deletes an existing model. + * If deletion is successful, the browser will be redirected to the 'index' page. + * + * @return mixed + */ + public function actionDelete() + { + $this->findModel()->delete(); + + return $this->redirect(['index']); + } + + /** + * Finds the model based on its primary key value. + * If the model is not found, a 404 HTTP exception will be thrown. + * + * @return the loaded model + * @throws NotFoundHttpException if the model cannot be found + */ + protected function findModel() + { + \$$pk"; + } + $condition = '[' . implode(', ', $condition) . ']'; +} +?> + if (($model = ::findOne()) !== null) { + return $model; + } else { + throw new NotFoundHttpException('The requested page does not exist.'); + } + } +} diff --git a/create.php b/create.php new file mode 100644 index 0000000..f296290 --- /dev/null +++ b/create.php @@ -0,0 +1,36 @@ + + +use yii\helpers\Html; +use yii\widgets\Breadcrumbs; +/** + * @var yii\web\View $this + * @var modelClass, '\\');?> $model + */ + +$this->title = generateString('Create {modelClass}', ['modelClass' => Inflector::camel2words(StringHelper::basename($generator->modelClass))]);?>; +$this->params['breadcrumbs'][] = ['label' => generateString(Inflector::pluralize(Inflector::camel2words(StringHelper::basename($generator->modelClass))));?>, 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +echo Breadcrumbs::widget([ + 'links' => $this->params['breadcrumbs'] , +]); +?> +
+ + $this->render('_form', [ + 'model' => $model, + ]) ?> + +
diff --git a/crud/Generator.php b/crud/Generator.php index daa7f6b..d85597d 100644 --- a/crud/Generator.php +++ b/crud/Generator.php @@ -5,7 +5,8 @@ * @license http://www.yiiframework.com/license/ */ -namespace warrence\kartikgii\crud; +//namespace warrence\kartikgii\crud; +namespace zhangyc310\kartikgii\crud; use Yii; use yii\db\ActiveRecord; @@ -30,12 +31,44 @@ */ class Generator extends \yii\gii\generators\crud\Generator { + public $listFields; + public $formFields; + public $inputType; + public $modelClass; public $moduleID; public $controllerClass; public $baseControllerClass = 'yii\web\Controller'; - public $indexWidgetType = 'grid'; - public $searchModelClass = ''; + public $indexWidgetType = 'grid'; + public $searchModelClass = ''; + + public function fieldTypes() + { + return [ + 'text' => "text", + 'textarea' => "textarea", + 'password' => "password", + 'time' => "time", + 'date' => "date", + 'datetime' => "datetime", + 'dropDownList' => "dropDownList", + 'radioList' => "radioList", + 'checkbox' => "checkbox", + 'checkboxList' => "checkboxList", + 'select2' => 'Select2', + 'file' => 'upload file', + 'image' => 'upload image', + + // 'multipleInput' => "Input组", + // 'baiduUEditor' => "百度编辑器", + // 'image' => "图片上传", + // 'images' => "多图上传", + // 'file' => "文件上传", + // 'files' => "多文件上传", + // 'cropper' => "图片裁剪上传", + // 'latLngSelection' => "经纬度选择", + ]; + } /** * @inheritdoc @@ -74,6 +107,7 @@ public function rules() [['moduleID'], 'validateModuleID'], [['enableI18N'], 'boolean'], [['messageCategory'], 'validateMessageCategory', 'skipOnEmpty' => false], + [['listFields', 'formFields', 'inputType'], 'safe'], ]); } @@ -83,12 +117,12 @@ public function rules() public function attributeLabels() { return array_merge(parent::attributeLabels(), [ - 'modelClass' => 'Model Class', - 'moduleID' => 'Module ID', - 'controllerClass' => 'Controller Class', + 'modelClass' => 'Model Class', + 'moduleID' => 'Module ID', + 'controllerClass' => 'Controller Class', 'baseControllerClass' => 'Base Controller Class', - 'indexWidgetType' => 'Widget Used in Index Page', - 'searchModelClass' => 'Search Model Class', + 'indexWidgetType' => 'Widget Used in Index Page', + 'searchModelClass' => 'Search Model Class', ]); } @@ -98,18 +132,18 @@ public function attributeLabels() public function hints() { return array_merge(parent::hints(), [ - 'modelClass' => 'This is the ActiveRecord class associated with the table that CRUD will be built upon. + 'modelClass' => 'This is the ActiveRecord class associated with the table that CRUD will be built upon. You should provide a fully qualified class name, e.g., app\models\Post.', - 'controllerClass' => 'This is the name of the controller class to be generated. You should + 'controllerClass' => 'This is the name of the controller class to be generated. You should provide a fully qualified namespaced class, .e.g, app\controllers\PostController. The controller class name should follow the CamelCase scheme with an uppercase first letter', 'baseControllerClass' => 'This is the class that the new CRUD controller class will extend from. You should provide a fully qualified class name, e.g., yii\web\Controller.', - 'moduleID' => 'This is the ID of the module that the generated controller will belong to. + 'moduleID' => 'This is the ID of the module that the generated controller will belong to. If not set, it means the controller will belong to the application.', - 'indexWidgetType' => 'This is the widget type to be used in the index page to display list of the models. + 'indexWidgetType' => 'This is the widget type to be used in the index page to display list of the models. You may choose either GridView or ListView', - 'searchModelClass' => 'This is the name of the search model class to be generated. You should provide a fully + 'searchModelClass' => 'This is the name of the search model class to be generated. You should provide a fully qualified namespaced class name, e.g., app\models\PostSearch.', ]); } @@ -137,7 +171,7 @@ public function validateModelClass() { /** @var ActiveRecord $class */ $class = $this->modelClass; - $pk = $class::primaryKey(); + $pk = $class::primaryKey(); if (empty($pk)) { $this->addError('modelClass', "The table associated with $class must have primary key(s)."); } @@ -169,10 +203,10 @@ public function generate() if (!empty($this->searchModelClass)) { $searchModel = Yii::getAlias('@' . str_replace('\\', '/', ltrim($this->searchModelClass, '\\') . '.php')); - $files[] = new CodeFile($searchModel, $this->render('search.php')); + $files[] = new CodeFile($searchModel, $this->render('search.php')); } - $viewPath = $this->getViewPath(); + $viewPath = $this->getViewPath(); $templatePath = $this->getTemplatePath() . '/views'; foreach (scandir($templatePath) as $file) { if (empty($this->searchModelClass) && $file === '_search.php') { @@ -191,7 +225,7 @@ public function generate() */ public function getControllerID() { - $pos = strrpos($this->controllerClass, '\\'); + $pos = strrpos($this->controllerClass, '\\'); $class = substr(substr($this->controllerClass, $pos + 1), 0, -10); return Inflector::camel2id($class); @@ -204,7 +238,7 @@ public function getViewPath() { $module = empty($this->moduleID) ? Yii::$app : Yii::$app->getModule($this->moduleID); - return $module->getViewPath() . '/' . $this->getControllerID() ; + return $module->getViewPath() . '/' . $this->getControllerID(); } public function getNameAttribute() @@ -216,7 +250,7 @@ public function getNameAttribute() } /** @var \yii\db\ActiveRecord $class */ $class = $this->modelClass; - $pk = $class::primaryKey(); + $pk = $class::primaryKey(); return $pk[0]; } @@ -226,33 +260,112 @@ public function getNameAttribute() * @param string $attribute * @return string */ + public function generateActiveField($attribute) { - $model = new $this->modelClass(); + $model = new $this->modelClass(); $attributeLabels = $model->attributeLabels(); - $tableSchema = $this->getTableSchema(); + $tableSchema = $this->getTableSchema(); if ($tableSchema === false || !isset($tableSchema->columns[$attribute])) { if (preg_match('/^(password|pass|passwd|passcode)$/i', $attribute)) { - return "'$attribute' => ['type' => TabularForm::INPUT_PASSWORD,'options' => ['placeholder' => 'Enter ".$attributeLabels[$attribute]."...']],"; + return "'$attribute' => ['type' => TabularForm::INPUT_PASSWORD,'options' => ['placeholder' => 'Enter " . $attributeLabels[$attribute] . "...']],"; //return "\$form->field(\$model, '$attribute')->passwordInput()"; } else { - return "'$attribute' => ['type' => TabularForm::INPUT_TEXT, 'options' => ['placeholder' => 'Enter ".$attributeLabels[$attribute]."...']],"; + return "'$attribute' => ['type' => TabularForm::INPUT_TEXT, 'options' => ['placeholder' => 'Enter " . $attributeLabels[$attribute] . "...']],"; //return "\$form->field(\$model, '$attribute')"; } } $column = $tableSchema->columns[$attribute]; - if ($column->phpType === 'boolean') { + if ($this->inputType){ + $type = $this->inputType[$attribute]; + } + if ($type === 'radioList') { //return "\$form->field(\$model, '$attribute')->checkbox()"; - return "'$attribute' => ['type' => Form::INPUT_CHECKBOX, 'options' => ['placeholder' => 'Enter ".$attributeLabels[$attribute]."...']],"; - } elseif ($column->type === 'text') { + return "'$attribute' => [ + 'type' => Form::INPUT_RADIO_LIST, + 'items' => [true => 'Active', false => 'Inactive', 'ok'=> 'radioList'], + 'options' => ['inline' => true], + ],"; + + } elseif ($type === 'checkbox') { + return "'$attribute' => [ + 'type' => Form::INPUT_CHECKBOX, + 'label' => 'Remember your settings?', + ],"; + } elseif ($type === 'checkboxList') { + return "'$attribute' => ['type' => Form::INPUT_CHECKBOX_LIST, + 'items'=>[ 'value1' => 'v1', 'value2' => 'v2'], + 'options'=>['text' => 'Please select', 'options' => ['value' => 'none', 'class' => 'prompt', 'label' => 'Select']], + ],"; + } elseif ($type === 'dropDownList') { + return "'$attribute' => ['type' => Form::INPUT_DROPDOWN_LIST, + 'items'=>[ 'value1' => 'value 1', 'value2' =>'value 2'], + 'options'=>['text' => 'Please select', 'options' => ['value' => 'none', 'class' => 'prompt', 'label' => 'Select']], + ],"; + } elseif ($type === 'text') { + return "'$attribute' => ['type' => Form::INPUT_TEXT, 'options' => ['placeholder' => 'Enter " . $attributeLabels[$attribute] . "...','rows' => 6]],"; + } elseif ($type === 'textarea') { //return "\$form->field(\$model, '$attribute')->textarea(['rows' => 6])"; - return "'$attribute' => ['type' => Form::INPUT_TEXTAREA, 'options' => ['placeholder' => 'Enter ".$attributeLabels[$attribute]."...','rows' => 6]],"; - } elseif ($column->type === 'date') { + return "'$attribute' => ['type' => Form::INPUT_TEXTAREA, 'options' => ['placeholder' => 'Enter " . $attributeLabels[$attribute] . "...','rows' => 6]],"; + } elseif ($type === 'date') { return "'$attribute' => ['type' => Form::INPUT_WIDGET, 'widgetClass' => DateControl::classname(),'options' => ['type' => DateControl::FORMAT_DATE]],"; - } elseif ($column->type === 'time') { + } elseif ($type === 'time') { return "'$attribute' => ['type' => Form::INPUT_WIDGET, 'widgetClass' => DateControl::classname(),'options' => ['type' => DateControl::FORMAT_TIME]],"; - } elseif ($column->type === 'datetime' || $column->type === 'timestamp') { + } elseif ($type === 'datetime' || $type === 'timestamp') { return "'$attribute' => ['type' => Form::INPUT_WIDGET, 'widgetClass' => DateControl::classname(),'options' => ['type' => DateControl::FORMAT_DATETIME]],"; + + } elseif ($type === 'select2') { + return "'$attribute' => [ + 'type' => Form::INPUT_WIDGET, + 'widgetClass' => '\kartik\select2\Select2', + 'options' => [ + 'data' => [true => 'Active', false => 'Inactive', 'ok' => 'radioList'], + 'pluginOptions' => [ + 'allowClear' => true, + 'closeOnSelect' => false, + 'tags' => true, + 'multiple' => true, + 'tokenSeparators' => [',', ' '], + // 'placeholder' => 'Select ...', + 'hint' => 'Type and select state', + ], + ], + ],"; + } elseif ($type === 'file') { + return "'$attribute' => ['type' => Form::INPUT_WIDGET, 'widgetClass' => FileInput::classname(), + 'options' => [ + 'options' => ['accept' => 'image/*', 'multiple' => true], + 'pluginOptions' => [ + // 'allowedFileExtensions' => ['csv'], + 'showUpload' => true, + 'browseLabel' => 'upload file', + 'removeLabel' => '', + 'showPreview' => true, + ], + ], + ],"; + } elseif ($type === 'image') { + return "'$attribute' => [ + 'type' => Form::INPUT_WIDGET, + 'widgetClass' => FileInput::classname(), + 'name' => 'attachment_3', + 'attribute' => 'attachment_1[]', + 'options' => [ + 'options' => ['accept' => 'image/*', 'multiple' => true], + 'pluginOptions' => [ + // 'allowedFileExtensions' => ['csv'], + 'showUpload' => true, + 'browseLabel' => 'upload image', + 'removeLabel' => '', + 'showPreview' => true, + ], + ], + ],"; + } elseif ($type === 'password') { + return "'$attribute' => [ + 'type' => Form::INPUT_PASSWORD, + 'options' => ['placeholder' => 'Enter Password...'] + ],"; } else { if (preg_match('/^(password|pass|passwd|passcode)$/i', $column->name)) { $input = 'INPUT_PASSWORD'; @@ -261,10 +374,10 @@ public function generateActiveField($attribute) } if ($column->phpType !== 'string' || $column->size === null) { //return "\$form->field(\$model, '$attribute')->$input()"; - return "'$attribute' => ['type' => Form::".$input.", 'options' => ['placeholder' => 'Enter ".$attributeLabels[$attribute]."...']],"; + return "'$attribute' => ['type' => Form::" . $input . ", 'options' => ['placeholder' => 'Enter " . $attributeLabels[$attribute] . "...']],"; } else { //return "\$form->field(\$model, '$attribute')->$input(['maxlength' => $column->size])"; - return "'$attribute' => ['type' => Form::".$input.", 'options' => ['placeholder' => 'Enter ".$attributeLabels[$attribute]."...', 'maxlength' => ".$column->size."]],"; + return "'$attribute' => ['type' => Form::" . $input . ", 'options' => ['placeholder' => 'Enter " . $attributeLabels[$attribute] . "...', 'maxlength' => " . $column->size . "]],"; } } } @@ -295,7 +408,7 @@ public function generateActiveSearchField($attribute) */ public function generateColumnFormat($column) { - if ($column->phpType === 'boolean') { + if ($column->phpType === 'tinyint') { return 'boolean'; } elseif ($column->type === 'text') { return 'ntext'; @@ -368,9 +481,9 @@ public function getSearchAttributes() public function generateSearchLabels() { /** @var \yii\base\Model $model */ - $model = new $this->modelClass(); + $model = new $this->modelClass(); $attributeLabels = $model->attributeLabels(); - $labels = []; + $labels = []; foreach ($this->getColumnNames() as $name) { if (isset($attributeLabels[$name])) { $labels[$name] = $attributeLabels[$name]; @@ -436,8 +549,8 @@ public function generateSearchConditions() $conditions = []; if (!empty($hashConditions)) { $conditions[] = "\$query->andFilterWhere([\n" - . str_repeat(' ', 12) . implode("\n" . str_repeat(' ', 12), $hashConditions) - . "\n" . str_repeat(' ', 8) . "]);\n"; + . str_repeat(' ', 12) . implode("\n" . str_repeat(' ', 12), $hashConditions) + . "\n" . str_repeat(' ', 8) . "]);\n"; } if (!empty($likeConditions)) { $conditions[] = "\$query" . implode("\n" . str_repeat(' ', 12), $likeConditions) . ";\n"; @@ -454,7 +567,7 @@ public function generateUrlParams() { /** @var ActiveRecord $class */ $class = $this->modelClass; - $pks = $class::primaryKey(); + $pks = $class::primaryKey(); if (count($pks) === 1) { if (is_subclass_of($class, 'yii\mongodb\ActiveRecord')) { return "'id' => (string)\$model->{$pks[0]}"; @@ -483,7 +596,7 @@ public function generateActionParams() { /** @var ActiveRecord $class */ $class = $this->modelClass; - $pks = $class::primaryKey(); + $pks = $class::primaryKey(); if (count($pks) === 1) { return '$id'; } else { @@ -499,7 +612,7 @@ public function generateActionParamComments() { /** @var ActiveRecord $class */ $class = $this->modelClass; - $pks = $class::primaryKey(); + $pks = $class::primaryKey(); if (($table = $this->getTableSchema()) === false) { $params = []; foreach ($pks as $pk) { diff --git a/crud/default/controller.php b/crud/default/controller.php index efe8b52..1e1eec4 100644 --- a/crud/default/controller.php +++ b/crud/default/controller.php @@ -10,40 +10,40 @@ * @var yii\gii\generators\crud\Generator $generator */ -$controllerClass = StringHelper::basename($generator->controllerClass); -$modelClass = StringHelper::basename($generator->modelClass); +$controllerClass = StringHelper::basename($generator->controllerClass); +$modelClass = StringHelper::basename($generator->modelClass); $searchModelClass = StringHelper::basename($generator->searchModelClass); if ($modelClass === $searchModelClass) { $searchModelAlias = $searchModelClass . 'Search'; } /** @var ActiveRecordInterface $class */ -$class = $generator->modelClass; -$pks = $class::primaryKey(); -$urlParams = $generator->generateUrlParams(); -$actionParams = $generator->generateActionParams(); +$class = $generator->modelClass; +$pks = $class::primaryKey(); +$urlParams = $generator->generateUrlParams(); +$actionParams = $generator->generateActionParams(); $actionParamComments = $generator->generateActionParamComments(); echo " -namespace controllerClass, '\\')) ?>; +namespace controllerClass, '\\'))?>; use Yii; -use modelClass, '\\') ?>; +use modelClass, '\\')?>; searchModelClass)): ?> -use searchModelClass, '\\') . (isset($searchModelAlias) ? " as $searchModelAlias" : "") ?>; +use searchModelClass, '\\') . (isset($searchModelAlias) ? " as $searchModelAlias" : "")?>; use yii\data\ActiveDataProvider; - -use baseControllerClass, '\\') ?>; + +use baseControllerClass, '\\')?>; use yii\web\NotFoundHttpException; use yii\filters\VerbFilter; /** - * implements the CRUD actions for model. + * implements the CRUD actions for model. */ -class extends baseControllerClass) . "\n" ?> +class extends baseControllerClass) . "\n"?> { public function behaviors() { @@ -58,13 +58,13 @@ public function behaviors() } /** - * Lists all models. + * Lists all models. * @return mixed */ public function actionIndex() { searchModelClass)): ?> - $searchModel = new ; + $searchModel = new ; $dataProvider = $searchModel->search(Yii::$app->request->getQueryParams()); return $this->render('index', [ @@ -73,23 +73,28 @@ public function actionIndex() ]); $dataProvider = new ActiveDataProvider([ - 'query' => ::find(), + 'query' => ::find(), ]); return $this->render('index', [ 'dataProvider' => $dataProvider, ]); - + + } + public function actionDeleteAll($id) + { + ::deleteAll('id in (' . $id . ')'); + return $this->redirect(Yii::$app->request->referrer); } /** - * Displays a single model. - * + * Displays a single model. + * * @return mixed */ - public function actionView() + public function actionView() { - $model = $this->findModel(); + $model = $this->findModel(); if ($model->load(Yii::$app->request->post()) && $model->save()) { return $this->redirect(['view', 'id' => $model->getTableSchema()->primaryKey[0]?>]); @@ -99,16 +104,16 @@ public function actionView() } /** - * Creates a new model. + * Creates a new model. * If creation is successful, the browser will be redirected to the 'view' page. * @return mixed */ public function actionCreate() { - $model = new ; + $model = new ; if ($model->load(Yii::$app->request->post()) && $model->save()) { - return $this->redirect(['view', ]); + return $this->redirect(['view', ]); } else { return $this->render('create', [ 'model' => $model, @@ -117,17 +122,17 @@ public function actionCreate() } /** - * Updates an existing model. + * Updates an existing model. * If update is successful, the browser will be redirected to the 'view' page. - * + * * @return mixed */ - public function actionUpdate() + public function actionUpdate() { - $model = $this->findModel(); + $model = $this->findModel(); if ($model->load(Yii::$app->request->post()) && $model->save()) { - return $this->redirect(['view', ]); + return $this->redirect(['view', ]); } else { return $this->render('update', [ 'model' => $model, @@ -136,26 +141,26 @@ public function actionUpdate() } /** - * Deletes an existing model. + * Deletes an existing model. * If deletion is successful, the browser will be redirected to the 'index' page. - * + * * @return mixed */ - public function actionDelete() + public function actionDelete() { - $this->findModel()->delete(); + $this->findModel()->delete(); return $this->redirect(['index']); } /** - * Finds the model based on its primary key value. + * Finds the model based on its primary key value. * If the model is not found, a 404 HTTP exception will be thrown. - * - * @return the loaded model + * + * @return the loaded model * @throws NotFoundHttpException if the model cannot be found */ - protected function findModel() + protected function findModel() { ) $condition = '[' . implode(', ', $condition) . ']'; } ?> - if (($model = ::findOne()) !== null) { + if (($model = ::findOne()) !== null) { return $model; } else { throw new NotFoundHttpException('The requested page does not exist.'); diff --git a/crud/default/views/_form.php b/crud/default/views/_form.php index 7814dea..edb5da2 100644 --- a/crud/default/views/_form.php +++ b/crud/default/views/_form.php @@ -24,7 +24,7 @@ use kartik\widgets\ActiveForm; use kartik\builder\Form; use kartik\datecontrol\DateControl; - +use kartik\widgets\FileInput; /** * @var yii\web\View $this * @var modelClass, '\\') ?> $model diff --git a/crud/default/views/create.php b/crud/default/views/create.php index 7f25114..10208fc 100644 --- a/crud/default/views/create.php +++ b/crud/default/views/create.php @@ -12,7 +12,7 @@ ?> use yii\helpers\Html; - +use yii\widgets\Breadcrumbs; /** * @var yii\web\View $this * @var modelClass, '\\') ?> $model @@ -21,6 +21,9 @@ $this->title = generateString('Create {modelClass}', ['modelClass' => Inflector::camel2words(StringHelper::basename($generator->modelClass))]) ?>; $this->params['breadcrumbs'][] = ['label' => generateString(Inflector::pluralize(Inflector::camel2words(StringHelper::basename($generator->modelClass)))) ?>, 'url' => ['index']]; $this->params['breadcrumbs'][] = $this->title; +echo Breadcrumbs::widget([ + 'links' => $this->params['breadcrumbs'] , +]); ?>