Tag Archive Yii 2

Byphunsanit

YII2 : RBAC สมาชิก กลุ่มและสิทธิ

yii2 มีระบบจัดการสิทธิต่างๆ เรียกว่า Role Based Access Control (RBAC) โดยสามารถกำหนดสิทธิได้โดยใช้ กลุ่ม (role) และกำหนดสิทธิให้รายคนได้ เพื่อที่จะควบคุมให้แต่ละคนสามารถเข้าไปใช้เมนูต่างๆ ได้ตามความเหมาะสม เราคงไม่ต้องการให้ใครก็ได้ แต่มาเปลี่ยนข้อมูล ตั้งค่าของระบบใหม่ หรือลบงานของคนอื่นออกไปโดยไม่มีเหตุอันควร เริ่มจากการกำหนด role โดย

  1. เพิ่ม component authManager ในไฟล์ common/config/main.php
        'components' => [
    ...
            'authManager' => [
                'class' => 'yii\rbac\DbManager',
            ],
    ...
        ],
    
  2. สร้างตาราง auth ก่อนโดย command
    yii migrate –migrationPath=@yii/rbac/migrations/
    

    ตอบ yes รอจนเห็น Migrated up successfully. จะเป็นการสร้างตาราง auth_assignment, auth_item, auth_item_child และ auth_rule
    ถ้าเห็น Exception ‘yii\base\InvalidConfigException’ with message ‘The configuration for the “user” component must contain a “class” element.’ ให้ไป comment config ทีระบุ user components ออกไปก่อน แลัวลองใหม่

  3. สร้างไฟล์ใหม่ /backend/controllers/RbacController.php
    <?php
    namespace backend\controllers;
    
    use Yii;
    use yii\helpers\Html;
    use yii\web\Controller;
    
    /**
     * Site controller
     */
    class RbacController extends Controller
    {
    
        private $auth = [];
    
        public function init()
        {
            parent::init();
    
            $this->auth = Yii::$app->authManager;
        }
    
        public function actionIndex()
        {
            return '<h1>RBAC Snippets</h1>' .
            '<ul>' .
            '<li>' . html::a('Create Role', 'createparentsrole', ['target' => 't1']) . '</li>' .
            '<li>' . html::a('Set Child Role', 'childrole', ['target' => 't2']) . '</li>' .
            '<li>' . html::a('Assign To User', 'assignrole', ['target' => 't3']) . '</li>' .
                '</ul>';
        }
    
        public function actionAssignrole()
        {
            $administratorsRole = $this->auth->getRole('administrators');
            if (is_null($this->auth->getAssignment('administrators', 1))) {
                $this->auth->assign($administratorsRole, 1);
            }
    
            $staffsRole = $this->auth->getRole('staffs');
            if (is_null($this->auth->getAssignment('staffs', 1))) {
                $this->auth->assign($staffsRole, 1);
            }
    
            /*
            show all roles from table auth_assignment
             */
            return '<h1>Assignments of user id = 1</h1>' .
            '<pre>' . print_r($this->auth->getAssignments(1), true) . '</pre>';
        }
    
        public function actionChildrole()
        {
            $administratorsRole = $this->auth->getRole('administrators');
            $guestsRole = $this->auth->getRole('guests');
    
            if (is_null($this->auth->hasChild($administratorsRole, $guestsRole))) {
                $this->auth->addChild($administratorsRole, $guestsRole);
            }
    
            /*
            show all roles from table auth_item_child
             */
            return '<h1>Children of "administrators" Role</h1>' .
            '<pre>' . print_r($this->auth->getChildren('administrators'), true) . '</pre>';
        }
    
        public function actionCreateparentsrole()
        {
            $roles = [
                'administrators',
                'guests',
                'staffs',
                'users',
            ];
    
            foreach ($roles as $role) {
                if (is_null($this->auth->getRole($role))) {
                    $newRole = $this->auth->createRole($role);
    
                    $newRole->description = 'parent role of ' . $role;
    
                    $this->auth->add($newRole);
                }
            }
    
            /*
            show all roles from table auth_item (type = 1)
             */
            return '<h1>Lists Of All Roles</h1>' .
            '<pre>' . print_r($this->auth->getRoles(), true) . '</pre>';
    
        }
    
    }
    

    ลองเรียก link http://localhost/advanced/backend/web/rbac และดูความเปลี่ยนแปลงตามลำดับ

ดูเพิ่มเติม

Byphunsanit

Yii2 Fixed jQuery version

งานที่ทำใช้ jQuery plugin ที่จำกัดอยู่ที่ไม่เกินเวอร์ชั่น 2.1.3 เท่านั้น แต่ทุกครั้งที่ update yii โดยใช้คำสั่ง composer update มันจะเปลี่ยนเจคิวรี่เป็นตัว 2.1.4 ทุกครั้ง ต้องมาเปลี่ยนทุกครั้งเลย แก้ได้โดยไปสั่งใช้คอมโพสเซอร์โหลดตัวที่ต้องการมา

  1. แก้ composer.json เพิ่ม
        "require": {
    ...
            "components/jquery": "2.1.3"
    ...
        },
    
  2. ไปใช้ command พิมพ์ composer update มันจะโหลดเจคิวรี่มาเก็บไว้ที่ \vendor\components\jquery
  3. สั่งให้ยีสองโหลด jquery ตัวนี้มาใช้โดยกำหนด
    ...
        'components'     => [
    ...
            'assetManager' => [
                'bundles' => [
                    'yii\web\JqueryAsset' => [
                        'baseUrl' => '@web',
                        'js' => [
                            '../../vendor/components/jquery/jquery.min.js',
                        ],
                        'sourcePath' => null
                    ],
                ],
            ],
    ...
    

yii จะเปลี่ยน link จาก

<script src="/YiiAdvanced/frontend/web/assets/41df07c8/jquery.js"></script>

เป็น

<script src="/YiiAdvanced/frontend/web/../../vendor/components/jquery/jquery.min.js"></script>

หลังจากนี้ถึงจะอัพเดตกี่ครั้ง jquery ก็จะยังเป็นตัวเดิมอยู่

Byphunsanit

แก้ validation error ใน YII 2

ฟอร์มของ yii จะมีการแจ้งเตือนถ้าหากพบว่าข้อมูล input ที่เรากรอกใน form ไม่ถูกต้อง โดยจะทำกรอบอินพุต ป้าย label เป็นสีแดงและมีข้อความแสดงใน help-block เพิ่มขึ้นมา บางครั้งก็ทำให้ฟอร์มที่จัดไว้แน่นๆ ไม่ใช่แบบบรรทัดละกล่องข้อความตามแบบเว็บสมัยใหม่ เวลาเจอความผิดพลาด มันก็จะถีบตัวอื่นออกไป หรือดูอัดแน่นเกินไปจนดูไม่สวย

ก็สามารถเอาออกได้โดยใช้ form template เหมือนเดิม โดยยังสามารถทำ validation ได้ตามปกติ

วิธีการคือ

  1. เปิดไฟล์ _form.php ใน view เป้าหมาย
  2. เปลี่ยน
    <?php $form = ActiveForm::begin(['id' => 'login-form']); ?>
    

    เป็น

    <?php $form = ActiveForm::begin([
        'fieldConfig' => [
            'template' => "{label}\n{input}\n{hint}"
        ],
        'id' => 'login-form'
    ]); ?>
    

อย่าลืมเปลี่ยน id นะครับ

ถ้าใช้

use yii\bootstrap\ActiveForm;

ให้เปลี่ยน template เป็น

'template' => "{label}\n{beginWrapper}\n{input}\n{hint}\n{endWrapper}"

Byphunsanit

YII2 GRUD GRID FROM หลายภาษา

จากเรื่องที่แล้ว ทำตาราง yii 2 ให้เก็บหลายภาษา โดยเราสามารถอ้างถึง attribute ตามรูปแบบ {attribute name}_{language} เช่น ในตาราง _lang ฟิลย์ชื่อ name ก็ใช้ $model->name_en, $model->name_jp, $model->name_th ในวิวถ้าต้องการแสดงผล

ในบทความที่ยังขาดตัวอย่างในการแสดงข้อมูล การใช้ในกริดที่แสดงรายการทั้งหมด, ฟอร์มที่จะกรอกข้อมูล และวิวที่จะแสดงสิ่งที่เราเก็บเอาไว้ออกมา ตัวอย่าง code ที่ผมใช้

GridView ต้องการให้แสดงภาษาอังกฤษเป็นหลัก อีกช่องที่เหลือแสดงสลับกันระหว่างภาษาไทย และญี่ปุ่น ทำได้โดยแทนที่จะอ้าง name_th หรือ name_jp ตรงๆ ก็อ้างผ่านตัวแปรไปแทน

...

if(Yii::$app->language == 'jp')
{
	$name = 'name_jp';
}
else
{
	$name = 'name_th';
}
...
echo GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
	['class' => 'yii\grid\SerialColumn'],
...
	'name_en',
	$name,
...
	'post_id',
	'status',
],
]);
...

form ก็สามารถใช้เหมือนรูบแบบปกติได้เลย โดยเราสามารถกรอกข้อมูล แก้ไขตัวแปลภาษาทั้งหมดได้พร้อมกันในครั้งเดียว เช่น

...
<?= $form->field($model, 'name_en')->textInput() ?>
<?= $form->field($model, 'name_jp')->textInput() ?>
<?= $form->field($model, 'name_th')->textInput() ?>
...

วิวก็ตามรูปแบบเหมือนตัวอื่นๆตามปกติ

...
<?= DetailView::widget([
        'model' => $model,
        'attributes' => [
            'post_id',
            'status',
...
            'name_en',
            'name_jp',
            'name_th',
...
            'date_publish',
            'date_expire',
            'log_created',
            'log_created_by',
            'log_updated',
            'log_updated_by',
        ],
    ]) ?>
...