├── AutoloadExample.php ├── Bootstrap.php ├── Module.php ├── README.md ├── User.php ├── composer.json ├── controllers └── DefaultController.php ├── messages ├── en │ └── auth.php └── zh-CN │ └── auth.php ├── migrations └── m141208_201489_auth_init.php ├── models ├── AuthOperation.php ├── AuthRole.php └── AuthRoleSearch.php ├── views └── default │ ├── _form.php │ ├── _search.php │ ├── create.php │ ├── index.php │ ├── update.php │ └── view.php └── yii2-auth-preview.png /AutoloadExample.php: -------------------------------------------------------------------------------- 1 | i18n->translations['funson86/auth']) && !isset($app->i18n->translations['funson86/*'])) { 19 | $app->i18n->translations['funson86/auth'] = [ 20 | 'class' => 'yii\i18n\PhpMessageSource', 21 | 'basePath' => '@funson86/auth/messages', 22 | 'forceTranslation' => true, 23 | 'fileMap' => [ 24 | 'funson86/auth' => 'auth.php', 25 | ] 26 | ]; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Module.php: -------------------------------------------------------------------------------- 1 | setViewPath('@funson86/auth/views'); 17 | } 18 | 19 | /** 20 | * Translates a message to the specified language. 21 | * 22 | * This is a shortcut method of [[\yii\i18n\I18N::translate()]]. 23 | * 24 | * The translation will be conducted according to the message category and the target language will be used. 25 | * 26 | * You can add parameters to a translation message that will be substituted with the corresponding value after 27 | * translation. The format for this is to use curly brackets around the parameter name as you can see in the following example: 28 | * 29 | * ```php 30 | * $username = 'Alexander'; 31 | * echo \Yii::t('app', 'Hello, {username}!', ['username' => $username]); 32 | * ``` 33 | * 34 | * Further formatting of message parameters is supported using the [PHP intl extensions](http://www.php.net/manual/en/intro.intl.php) 35 | * message formatter. See [[\yii\i18n\I18N::translate()]] for more details. 36 | * 37 | * @param string $category the message category. 38 | * @param string $message the message to be translated. 39 | * @param array $params the parameters that will be used to replace the corresponding placeholders in the message. 40 | * @param string $language the language code (e.g. `en-US`, `en`). If this is null, the current 41 | * [[\yii\base\Application::language|application language]] will be used. 42 | * 43 | * @return string the translated message. 44 | */ 45 | public static function t($category, $message, $params = [], $language = null) 46 | { 47 | return Yii::t('funson86/' . $category, $message, $params, $language); 48 | } 49 | 50 | /** 51 | * Check if module is used for backend application. 52 | * 53 | * @return boolean true if it's used for backend application 54 | */ 55 | public function getIsBackend() 56 | { 57 | if ($this->_isBackend === null) { 58 | $this->_isBackend = strpos($this->controllerNamespace, 'backend') === false ? false : true; 59 | } 60 | 61 | return $this->_isBackend; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Yii2 Auth 2 | ========= 3 | Yii2 Auth could manage operations in category, you could integrate it to [Yii2 Adminlte](https://github.com/funson86/yii2-adminlte) 4 | 5 | Installation 6 | ------------ 7 | 8 | The preferred way to install this extension is through [composer](http://getcomposer.org/download/). 9 | 10 | Either run 11 | 12 | ``` 13 | php composer.phar require funson86/yii2-auth "dev-master" 14 | ``` 15 | 16 | or add 17 | 18 | ``` 19 | "funson86/yii2-auth": "*" 20 | ``` 21 | 22 | to the require section of your `composer.json` file. 23 | 24 | 25 | Usage 26 | ----- 27 | 28 | Once the extension is installed, simply use it in your code by : 29 | 30 | ### Migration 31 | 32 | Migration run 33 | 34 | ```php 35 | yii migrate --migrationPath=@funson86/auth/migrations 36 | ``` 37 | 38 | Or insert to table `setting` manually. 39 | ```php 40 | CREATE TABLE `auth_operation` ( 41 | `id` int(11) NOT NULL AUTO_INCREMENT, 42 | `parent_id` int(11) NOT NULL DEFAULT 0, 43 | `name` varchar(32) NOT NULL, 44 | PRIMARY KEY (`id`), 45 | KEY `parent_id` (`parent_id`) 46 | ) ENGINE=InnoDB AUTO_INCREMENT=100000 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='Auth Operation'; 47 | 48 | CREATE TABLE `auth_role` ( 49 | `id` int(11) NOT NULL AUTO_INCREMENT, 50 | `name` varchar(64) NOT NULL, 51 | `description` varchar(255) DEFAULT NULL, 52 | `operation_list` text, 53 | PRIMARY KEY (`id`) 54 | ) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='Auth Role'; 55 | 56 | INSERT INTO `auth_role` VALUES ('1', 'Super Admin', '', 'all'); 57 | INSERT INTO `auth_role` VALUES ('3', 'Normal Admin', '', 'backendLogin;viewUser;viewRole'); 58 | 59 | INSERT INTO `auth_operation` VALUES ('111', '0', 'basic'); 60 | INSERT INTO `auth_operation` VALUES ('113', '0', 'user'); 61 | INSERT INTO `auth_operation` VALUES ('114', '0', 'role'); 62 | INSERT INTO `auth_operation` VALUES ('11101', '111', 'backendLogin'); 63 | INSERT INTO `auth_operation` VALUES ('11302', '113', 'viewUser'); 64 | INSERT INTO `auth_operation` VALUES ('11303', '113', 'createUser'); 65 | INSERT INTO `auth_operation` VALUES ('11304', '113', 'updateUser'); 66 | INSERT INTO `auth_operation` VALUES ('11305', '113', 'deleteUser'); 67 | INSERT INTO `auth_operation` VALUES ('11402', '114', 'viewRole'); 68 | INSERT INTO `auth_operation` VALUES ('11403', '114', 'createRole'); 69 | INSERT INTO `auth_operation` VALUES ('11404', '114', 'updateRole'); 70 | INSERT INTO `auth_operation` VALUES ('11405', '114', 'deleteRole'); 71 | 72 | ALTER TABLE `user` ADD COLUMN `auth_role` int(11) AFTER `status`; 73 | UPDATE `user` set `auth_role`=3; 74 | UPDATE `user` set `auth_role`=1 where `username` = 'admin'; 75 | ``` 76 | 77 | ### Config /common/config/main.php to check authority 78 | After add the following code, the code 79 | *if(!Yii::$app->user->can('createRole')) throw new ForbiddenHttpException(Yii::t('app', 'No Auth'));* 80 | in each action of controller could check whether current user have the authority to run this action or not. 81 | ```php 82 | 'components' => [ 83 | 'user' => [ 84 | 'class' => 'funson86\auth\User', 85 | 'enableAutoLogin' => true, 86 | ], 87 | ], 88 | ``` 89 | 90 | ### CRUD Auth Role with operation at backend 91 | Config backend modules in backend/config/main.php to manage settings 92 | 93 | ```php 94 | 'modules' => [ 95 | 'auth' => [ 96 | 'class' => 'funson86\auth\Module', 97 | ], 98 | ], 99 | ``` 100 | Access backend url: http://you-domain/backend/web/auth 101 | 102 | ### Add Your Auth Operation 103 | You could add your new operation based on business by migration or insert to table `auth_operation` manually. 104 | ```php 105 | INSERT INTO `auth_operation` VALUES ('115', '0', 'Service'); 106 | INSERT INTO `auth_operation` VALUES ('11501', '115', 'viewService'); 107 | ``` 108 | 109 | ### Use Your Operation Check 110 | Once you add new operation in `auth_operation`, add 111 | `if (!Yii::$app->user->can('viewService')) throw new ForbiddenHttpException(Yii::t('app', 'No Auth'))` 112 | at the beginning of action of controller like the following: 113 | ```php 114 | class ServiceController extends Controller 115 | { 116 | public function actionView($id) 117 | { 118 | if (!Yii::$app->user->can('viewService')) throw new ForbiddenHttpException(Yii::t('app', 'No Auth')); 119 | // you business code 120 | } 121 | } 122 | ``` 123 | 124 | ### Translation 125 | If no translation, it will show you 'viewService' at the backend management. You could add the translation 126 | in backend/messages/en/auth.php or backend/messages/zh-CN/auth.php. Like the following: 127 | ```php 128 | return [ 129 | 'viewService' => 'View Service', 130 | ]; 131 | ``` 132 | 133 | Preview 134 | ------- 135 |  136 | -------------------------------------------------------------------------------- /User.php: -------------------------------------------------------------------------------- 1 | user->getIsGuest()) { 36 | return false; 37 | } 38 | 39 | if ($allowCaching && isset($this->_operations)) { 40 | $operations = $this->_operations; 41 | } else { 42 | $operations = AuthRole::findOne(Yii::$app->user->identity->auth_role)->operation_list; 43 | $this->_operations = $operations; 44 | } 45 | 46 | //super admin 47 | if ($operations == 'all') 48 | return true; 49 | 50 | if (strpos(';' . $operations . ';', $permissionName) === false) 51 | return false; 52 | else 53 | return true; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "funson86/yii2-auth", 3 | "description": "Yii2 Auth with Operation Category", 4 | "type": "yii2-extension", 5 | "keywords": ["yii2","extension","auth","role","rbac"], 6 | "license": "Apache-2.0", 7 | "authors": [ 8 | { 9 | "name": "Funson Lee", 10 | "email": "funson86@gmail.com" 11 | } 12 | ], 13 | "require": { 14 | "yiisoft/yii2": "*" 15 | }, 16 | "autoload": { 17 | "psr-4": { 18 | "funson86\\auth\\": "" 19 | } 20 | }, 21 | "extra": { 22 | "bootstrap": "funson86\\auth\\Bootstrap" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /controllers/DefaultController.php: -------------------------------------------------------------------------------- 1 | [ 22 | 'class' => VerbFilter::className(), 23 | 'actions' => [ 24 | 'delete' => ['post'], 25 | ], 26 | ], 27 | 'access' => [ 28 | 'class' => AccessControl::className(), 29 | 'rules' => [ 30 | [ 31 | 'allow' => true, 32 | 'roles' => ['@'] 33 | ] 34 | ] 35 | ], 36 | ]; 37 | } 38 | 39 | /** 40 | * Lists all AuthRole models. 41 | * @return mixed 42 | */ 43 | public function actionIndex() 44 | { 45 | if(!Yii::$app->user->can('viewRole')) throw new ForbiddenHttpException(Yii::t('app', 'No Auth')); 46 | 47 | $searchModel = new AuthRoleSearch(); 48 | $dataProvider = $searchModel->search(Yii::$app->request->queryParams); 49 | 50 | return $this->render('index', [ 51 | 'searchModel' => $searchModel, 52 | 'dataProvider' => $dataProvider, 53 | ]); 54 | } 55 | 56 | /** 57 | * Displays a single AuthRole model. 58 | * @param integer $id 59 | * @return mixed 60 | */ 61 | public function actionView($id) 62 | { 63 | if(!Yii::$app->user->can('viewRole')) throw new ForbiddenHttpException(Yii::t('app', 'No Auth')); 64 | 65 | $model = $this->findModel($id); 66 | 67 | $strOperation = ''; 68 | $i = 0; 69 | if($model->operation_list) 70 | { 71 | $arrayOperation = explode(';', $model->operation_list); 72 | foreach($arrayOperation as $item) 73 | { 74 | $strOperation .= Yii::t('auth', $item) . ' | '; 75 | $i++; 76 | if($i % 5 == 0) 77 | $strOperation .= "\n"; 78 | } 79 | } 80 | 81 | return $this->render('view', [ 82 | 'model' => $this->findModel($id), 83 | 'strOperation' => $strOperation, 84 | ]); 85 | } 86 | 87 | /** 88 | * Creates a new AuthRole model. 89 | * If creation is successful, the browser will be redirected to the 'view' page. 90 | * @return mixed 91 | */ 92 | public function actionCreate() 93 | { 94 | if(!Yii::$app->user->can('createRole')) throw new ForbiddenHttpException(Yii::t('app', 'No Auth')); 95 | 96 | $model = new AuthRole(); 97 | 98 | if ($model->load(Yii::$app->request->post())) { 99 | $operations = $this->prepareOperations(Yii::$app->request->post()); 100 | $model->operation_list = implode(';', $operations); 101 | 102 | if($model->save()) 103 | return $this->redirect(['view', 'id' => $model->id]); 104 | } else { 105 | //generate all operations 106 | $operations = []; 107 | $rootOperations = AuthOperation::find()->where(['parent_id' => 0])->all(); 108 | foreach($rootOperations as $rootOperation) 109 | { 110 | $operations[$rootOperation->id]['name'] = $rootOperation->name; 111 | } 112 | $subOperations = AuthOperation::find()->where('parent_id <> 0')->all(); 113 | foreach($subOperations as $subOperation) 114 | { 115 | $operations[$subOperation->parent_id]['sub'][$subOperation->name] = Yii::t('auth', $subOperation->name); 116 | } 117 | 118 | return $this->render('create', [ 119 | 'model' => $model, 120 | 'operations' => $operations, 121 | ]); 122 | } 123 | } 124 | 125 | /** 126 | * Updates an existing AuthRole model. 127 | * If update is successful, the browser will be redirected to the 'view' page. 128 | * @param integer $id 129 | * @return mixed 130 | */ 131 | public function actionUpdate($id) 132 | { 133 | if(!Yii::$app->user->can('updateRole')) throw new ForbiddenHttpException(Yii::t('app', 'No Auth')); 134 | if($id == 1) throw new ForbiddenHttpException(Yii::t('app', 'No Auth')); 135 | 136 | $model = $this->findModel($id); 137 | 138 | if ($model->load(Yii::$app->request->post())) { 139 | $operations = $this->prepareOperations(Yii::$app->request->post()); 140 | $model->operation_list = implode(';', $operations); 141 | 142 | if($model->save()) 143 | return $this->redirect(['view', 'id' => $model->id]); 144 | } else { 145 | //generate all operations 146 | $operations = []; 147 | $rootOperations = AuthOperation::find()->where(['parent_id' => 0])->all(); 148 | foreach($rootOperations as $rootOperation) 149 | { 150 | $operations[$rootOperation->id]['name'] = $rootOperation->name; 151 | } 152 | $subOperations = AuthOperation::find()->where('parent_id <> 0')->all(); 153 | foreach($subOperations as $subOperation) 154 | { 155 | $operations[$subOperation->parent_id]['sub'][$subOperation->name] = Yii::t('auth', $subOperation->name); 156 | } 157 | 158 | //generate selected operations 159 | $model->_operations = explode(';', $model->operation_list); 160 | 161 | return $this->render('update', [ 162 | 'model' => $model, 163 | 'operations' => $operations, 164 | ]); 165 | } 166 | } 167 | 168 | /** 169 | * Deletes an existing AuthRole model. 170 | * If deletion is successful, the browser will be redirected to the 'index' page. 171 | * @param integer $id 172 | * @return mixed 173 | */ 174 | public function actionDelete($id) 175 | { 176 | if(!Yii::$app->user->can('deleteRole')) throw new ForbiddenHttpException(Yii::t('app', 'No Auth')); 177 | if(1 == $id) throw new ForbiddenHttpException(Yii::t('app', 'No Auth')); 178 | 179 | $this->findModel($id)->delete(); 180 | 181 | return $this->redirect(['index']); 182 | } 183 | 184 | /** 185 | * Finds the AuthRole model based on its primary key value. 186 | * If the model is not found, a 404 HTTP exception will be thrown. 187 | * @param integer $id 188 | * @return AuthRole the loaded model 189 | * @throws NotFoundHttpException if the model cannot be found 190 | */ 191 | protected function findModel($id) 192 | { 193 | if (($model = AuthRole::findOne($id)) !== null) { 194 | return $model; 195 | } else { 196 | throw new NotFoundHttpException('The requested page does not exist.'); 197 | } 198 | } 199 | 200 | /** 201 | * prepare Operations 202 | * @param array $post 203 | * @return array 204 | */ 205 | protected function prepareOperations($post) { 206 | return (isset($post['AuthRole']['_operations']) && 207 | is_array($post['AuthRole']['_operations'])) ? $post['AuthRole']['_operations'] : []; 208 | } 209 | } 210 | -------------------------------------------------------------------------------- /messages/en/auth.php: -------------------------------------------------------------------------------- 1 | 'Parent', 12 | 'Name' => 'Name', 13 | 'Description' => 'Description', 14 | 'Operation List' => 'Operation List', 15 | 16 | 'basic' => 'Basic', 17 | 'user' => 'User', 18 | 'role' => 'Role', 19 | 20 | 'backendLogin' => 'Backend Login', 21 | 22 | 'viewUser' => 'View User', 23 | 'createUser' => 'Create User', 24 | 'updateUser' => 'Update User', 25 | 'deleteUser' => 'Delete User', 26 | 27 | 'viewRole' => 'View Role', 28 | 'createRole' => 'Create Role', 29 | 'updateRole' => 'Update Role', 30 | 'deleteRole' => 'Delete Role', 31 | 32 | ]; -------------------------------------------------------------------------------- /messages/zh-CN/auth.php: -------------------------------------------------------------------------------- 1 | '名称', 12 | 'Description' => '描述', 13 | 'Operation List' => '权限列表', 14 | 15 | 'basic' => '基本', 16 | 'user' => '管理员', 17 | 'role' => '角色', 18 | 19 | 'backendLogin' => '后台登录', 20 | 21 | 'viewUser' => '查看管理员', 22 | 'createUser' => '创建管理员', 23 | 'updateUser' => '更新管理员', 24 | 'deleteUser' => '删除管理员', 25 | 26 | 'viewRole' => '查看角色', 27 | 'createRole' => '创建角色', 28 | 'updateRole' => '更新角色', 29 | 'deleteRole' => '删除角色', 30 | 31 | ]; -------------------------------------------------------------------------------- /migrations/m141208_201489_auth_init.php: -------------------------------------------------------------------------------- 1 | createTable( 28 | '{{%auth_operation}}', 29 | [ 30 | 'id' => Schema::TYPE_PK, 31 | 'parent_id' => Schema::TYPE_INTEGER . ' NOT NULL DEFAULT 0', 32 | 'name' => Schema::TYPE_STRING . '(32) DEFAULT NULL', 33 | ], 34 | $tableOptions 35 | ); 36 | 37 | // table auth_role 38 | $this->createTable( 39 | '{{%auth_role}}', 40 | [ 41 | 'id' => Schema::TYPE_PK, 42 | 'name' => Schema::TYPE_STRING . '(64) NOT NULL', 43 | 'description' => Schema::TYPE_STRING . '(255) DEFAULT NULL', 44 | 'operation_list' => Schema::TYPE_TEXT . '', 45 | ], 46 | $tableOptions 47 | ); 48 | 49 | // Indexes 50 | $this->createIndex('parent_id', '{{%auth_operation}}', 'parent_id'); 51 | 52 | // Add default setting 53 | $this->execute($this->getOperationSql()); 54 | $this->execute($this->getRoleSql()); 55 | $this->execute($this->getUserSql()); 56 | } 57 | 58 | /** 59 | * @return string SQL to insert first user 60 | */ 61 | private function getOperationSql() 62 | { 63 | return "INSERT INTO {{%auth_operation}} (`id`, `parent_id`, `name`) VALUES 64 | ('111', '0', 'basic'), 65 | ('113', '0', 'user'), 66 | ('114', '0', 'role'), 67 | ('11101', '111', 'backendLogin'), 68 | ('11302', '113', 'viewUser'), 69 | ('11303', '113', 'createUser'), 70 | ('11304', '113', 'updateUser'), 71 | ('11305', '113', 'deleteUser'), 72 | ('11402', '114', 'viewRole'), 73 | ('11403', '114', 'createRole'), 74 | ('11404', '114', 'updateRole'), 75 | ('11405', '114', 'deleteRole') 76 | "; 77 | } 78 | 79 | /** 80 | * @return string SQL to insert first user 81 | */ 82 | private function getRoleSql() 83 | { 84 | return "INSERT INTO {{%auth_role}} (`id`, `name`, `description`, `operation_list`) VALUES 85 | ('1', 'Super Admin', '', 'all'), 86 | ('3', 'Normal Admin', '', 'backendLogin;viewUser;viewRole') 87 | "; 88 | } 89 | 90 | /** 91 | * @return string SQL to insert first user 92 | */ 93 | private function getUserSql() 94 | { 95 | return "ALTER TABLE {{%user}} ADD COLUMN `auth_role` int(11) AFTER `email`; 96 | UPDATE {{%user}} set `auth_role` = 3; 97 | UPDATE {{%user}} set `auth_role` = 1 where `username` = 'admin'; 98 | "; 99 | } 100 | 101 | /** 102 | * @inheritdoc 103 | */ 104 | public function down() 105 | { 106 | $this->execute("ALTER TABLE {{%user}} DROP COLUMN `auth_role`"); 107 | $this->dropTable('{{%auth_role}}'); 108 | $this->dropTable('{{%auth_operation}}'); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /models/AuthOperation.php: -------------------------------------------------------------------------------- 1 | 32] 33 | ]; 34 | } 35 | 36 | /** 37 | * @inheritdoc 38 | */ 39 | public function attributeLabels() 40 | { 41 | return [ 42 | 'id' => Module::t('auth', 'ID'), 43 | 'parent_id' => Module::t('auth', 'Parent ID'), 44 | 'name' => Module::t('auth', 'Name'), 45 | ]; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /models/AuthRole.php: -------------------------------------------------------------------------------- 1 | 64], 43 | [['description'], 'string', 'max' => 255] 44 | ]; 45 | } 46 | 47 | /** 48 | * @inheritdoc 49 | */ 50 | public function attributeLabels() 51 | { 52 | return [ 53 | 'id' => Module::t('auth', 'ID'), 54 | 'name' => Module::t('auth', 'Name'), 55 | 'description' => Module::t('auth', 'Description'), 56 | 'operation_list' => Module::t('auth', 'Operation List'), 57 | ]; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /models/AuthRoleSearch.php: -------------------------------------------------------------------------------- 1 | $query, 48 | ]); 49 | 50 | if (!($this->load($params) && $this->validate())) { 51 | return $dataProvider; 52 | } 53 | 54 | $query->andFilterWhere([ 55 | 'id' => $this->id, 56 | ]); 57 | 58 | $query->andFilterWhere(['like', 'name', $this->name]) 59 | ->andFilterWhere(['like', 'description', $this->description]) 60 | ->andFilterWhere(['like', 'operation_list', $this->operation_list]); 61 | 62 | return $dataProvider; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /views/default/_form.php: -------------------------------------------------------------------------------- 1 | 11 | 12 |
25 | = Html::checkbox($operation['name'], false, ['label' => Yii::t('auth', $operation['name']), 'id'=>$operation['name'], 'suboperation'=> implode(',', array_keys($operation['sub']))]) ?> 26 | $value) 29 | $str .= '$("input[value=\'' . $key . '\']").prop("checked", this.checked);'; 30 | $this->registerJs( 31 | ' 32 | $("#' . $operation['name'] . '").click(function() { 33 | ' . $str . ' 34 | }); 35 | ' 36 | ); ?> 37 | | 38 |field($model, '_operations')->checkboxList($operation['sub'], ['unselect' => null])->label(false); ?> | 39 |
19 | = Html::a(Yii::t('app', 'Create ') . Yii::t('app', 'Auth Role'), ['create'], ['class' => 'btn btn-success']) ?> 20 |
21 | 22 | = GridView::widget([ 23 | 'dataProvider' => $dataProvider, 24 | 'filterModel' => $searchModel, 25 | 'columns' => [ 26 | ['class' => 'yii\grid\SerialColumn'], 27 | 28 | 'id', 29 | 'name', 30 | 'description', 31 | //'operation_list:ntext', 32 | 33 | ['class' => 'yii\grid\ActionColumn'], 34 | ], 35 | ]); ?> 36 | 37 |16 | = Html::a(Yii::t('app', 'Update'), ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?> 17 | = Html::a(Yii::t('app', 'Delete'), ['delete', 'id' => $model->id], [ 18 | 'class' => 'btn btn-danger', 19 | 'data' => [ 20 | 'confirm' => Yii::t('app', 'Are you sure you want to delete this item?'), 21 | 'method' => 'post', 22 | ], 23 | ]) ?> 24 |
25 | 26 | = DetailView::widget([ 27 | 'model' => $model, 28 | 'attributes' => [ 29 | 'id', 30 | 'name', 31 | 'description', 32 | [ 33 | 'attribute' => 'operation_list', 34 | 'value' => $strOperation,//implode(';', call_user_func_array('Yii::t', explode(';', $model->operation_list))), 35 | ], 36 | ], 37 | ]) ?> 38 | 39 |