Behavior AccessControl Rules From Database

Hello buddy :lol:

I make Simple Access Rule Control Form here, may be useful

First Create Table on Database


CREATE TABLE `user_access` (

	`id` INT(11) NOT NULL AUTO_INCREMENT,

	`level` CHAR(32) NOT NULL,

	`module` CHAR(50) NOT NULL,

	`controller` CHAR(50) NOT NULL,

	`action` TEXT NULL,

	PRIMARY KEY (`id`)

)

COLLATE='latin1_swedish_ci'

ENGINE=InnoDB

AUTO_INCREMENT=2

;



Insert Some Data




INSERT IGNORE INTO `user_access` (`id`, `level`, `module`, `controller`, `action`) VALUES

	(1, 'SUPERADMIN', 'app-backend', 'user-access', '{"index":true}'),



Create Controller (UserAccessController.php)




<?php


namespace backend\controllers;


use Yii;

use yii\web\Controller;

use yii\filters\VerbFilter;

use backend\models\UserAccess;


/**

 * UserAccessController implements the CRUD actions for UserAccess model.

 */

class UserAccessController extends Controller

{

    /**

     * @inheritdoc

     */

    public function behaviors()

    {

        return [

            'access' => [

                'class' => \yii\filters\AccessControl::className(),

                'rules' => [

                    

                    [

                        'actions' => ['create', 'update', 'delete', 'index', 'view'],

                        'allow' => true,

                        'matchCallback' => function() {


                            $access = UserAccess::findOne([

                                'level' => Yii::$app->user->identity->level, 

                                'module' => Yii::$app->controller->module->id, 

                                'controller' => Yii::$app->controller->id

                            ]);


                            if (is_null($access) == false)

                            {

                                $auth = \yii\helpers\BaseJson::decode($access['action'], true);


                                if (array_key_exists(Yii::$app->controller->action->id, $auth))

                                {

                                    return $auth[Yii::$app->controller->action->id];

                                }

                            }


                        },


                    ],


                ],


                'denyCallback' => function ($rule, $action) {


                    $messages = 'Anda tidak diautorisasikan untuk mengakses halaman ini !


                                 1. Silahkan menghubungi Administrator

                                 2. Melakukan setting di halaman "Access User" pada menu [ Sistem -> Access User ]


                                 Terimakasih.';


                    throw new \yii\web\ForbiddenHttpException($messages);

                }


            ],

            'verbs' => [

                'class' => VerbFilter::className(),

                'actions' => [

                    'delete' => ['POST'],

                ],

            ],

        ];

    }


    /**

     * Lists all UserAccess models.

     * @return mixed

     */

    public function actionIndex()

    {

        $model = new UserAccess();


        if ($model->load(Yii::$app->request->post())) {


            /* I WILL UPDATE SOON FOR INSERT TO JSON */


            $model->save();


            return $this->redirect(['index', 'level' => $model->level, 'module' => $model->module]);


        } else {


            return $this->render('index', [

                'model' => $model,

                'controller' => $this->actionGetcontrollersandactions(),

            ]);


        }

    }

    

    

    /* Code From Andreas Hinderberger (https://stackoverflow.com/questions/27912988/retrieving-array-of-controllers-actions) */


    protected function actionGetcontrollersandactions()

    {

        $fulllist = [];

        $controllerlist = [];


        if ($handle = opendir(Yii::getAlias('@app/controllers'))) 

        {

            while (false !== ($file = readdir($handle))) 

            {

                if ($file != "." && $file != ".." && substr($file, strrpos($file, '.') - 10) == 'Controller.php') 

                {

                    $controllerlist[] = $file;

                }

            }


            closedir($handle);

        }


        asort($controllerlist);

        

        foreach ($controllerlist as $controller)

        {

            $handle = fopen(Yii::getAlias('@app/controllers') . '/' . $controller, "r");


            if ($handle) 

            {

                while (($line = fgets($handle)) !== false) 

                {

                    if (preg_match('/public function action(.*?)\(/', $line, $display))

                    {

                        if (strlen($display[1]) > 2)

                        {

                            /* Start Touched by Me */


                            $fix_controller = preg_replace('/Controller.php/', '', $controller);

                            $divide_controller = preg_split('/(?=[A-Z])/', $fix_controller, -1, PREG_SPLIT_NO_EMPTY);

                            $make_low_letter = strtolower(implode($divide_controller, '-'));

                              

                            /* End Touched by Me */


                            $fulllist[$make_low_letter][] = strtolower($display[1]);

                        }

                    }

                }

            }


            fclose($handle);

        }


        return $fulllist;

    }

}




Create Model (UserAccess.php)


<?php


namespace backend\models;


use Yii;


/**

 * This is the model class for table "user_access".

 *

 * @property integer $id

 * @property string $level

 * @property string $module

 * @property string $controller

 * @property string $action

 */

class UserAccess extends \yii\db\ActiveRecord

{

    /**

     * @inheritdoc

     */

    public static function tableName()

    {

        return 'user_access';

    }


    /**

     * @inheritdoc

     */

    public function rules()

    {

        return [

            [['level', 'module'], 'required'],

            [['controller'], 'safe'],

            [['action'], 'string'],

            [['level'], 'string', 'max' => 32],

            [['module', 'controller'], 'string', 'max' => 50],

        ];

    }


    /**

     * @inheritdoc

     */

    public function attributeLabels()

    {

        return [

            'id' => 'ID',

            'level' => 'Level',

            'module' => 'Module',

            'controller' => 'Controller',

            'action' => 'Action',

        ];

    }

}



Create view Form (c_form.php)


<?php


use yii\helpers\Url;

use yii\helpers\Html;

use yii\helpers\ArrayHelper;

use yii\widgets\ActiveForm;

use kartik\select2\Select2;

use backend\models\UserLevel;

use backend\models\UserAccess;


/* @var $this yii\web\View */

/* @var $model backend\models\UserAccess */

/* @var $form yii\widgets\ActiveForm */


foreach ($controller as $key => $val)

{

	$control[] = $key; //array('key' => $key, 'val' => $key);

}


$level = ArrayHelper::map(UserLevel::find()->asArray()->all(), function($model, $defaultValue) {

        return md5($model['code']);

    }, 'name'

);


?>


<div class="user-access-form">


    <?php $form = ActiveForm::begin(); ?>


    <div class="row">


    	<div class="col-lg-4">


		    <?= $form->field($model, 'level')->textInput()->widget(Select2::classname(), [ 

		    	'initValueText' => $model->isNewRecord ? Yii::$app->request->get('level') : $model->level,

		        'data' => $level,

		        'disabled' => $model->isNewRecord ? false : true,

		        'options' => [

		            'placeholder' => 'Pilih Level',

		            'value' => $model->isNewRecord ? Yii::$app->request->get('level') : $model->level,

		        ],

		        'pluginOptions' => [

		            'allowClear' => true

		        ],

		    ]); ?>


		</div>


		<div class="col-lg-4">


		    <?= $form->field($model, 'module')->dropDownList(['' => '',  'app-backend' => 'app-backend', 'app-frontend' => 'app-frontend', ], ['options' => [$model->isNewRecord ? Yii::$app->request->get('module') : $model->module => ['Selected'=>'selected']]], ['prompt' => '']) ?>


		</div>


		<div class="col-lg-4">


		    <div class="form-group">

                <label class="control-label" for="check-button">&nbsp;</label>

                <button id="check-button" class="btn btn-success form-control">Check</button>

            </div>


		    <?php /*$form->field($model, 'controller')->widget(Select2::classname(),[

	            'data' => $control,

	            'options' => ['placeholder' => 'Pilih Controller'],

	            'pluginOptions' => [

	                'allowClear' => true

	            ],

		    ])*/ ?>


		</div>


	</div>


	<div class="row">


		<div class="col-lg-12">


			<table class="table table-bordered">


				<thead>

					<tr>

						<th>Controller</th>

						<th>Action</th>

					</tr>

				</thead>

				<tbody>

				    <?php


				    foreach ($controller as $key => $val)

				    {

				    	echo '<tr><td>' . $key . '</td><td>';


				    	foreach($val as $value)

					    {

                            echo '&nbsp;&nbsp;<input type="checkbox" name="checkbox['. $key.']" value="' . $value.'"';


                            $access = UserAccess::findOne([

                                'level' => Yii::$app->request->get('level'), 

                                'module' => Yii::$app->request->get('module'), 

                                'controller' => $key

                            ]);


                            if (is_null($access['action']) == false)

                            {

                                $auth = \yii\helpers\BaseJson::decode($access['action'], true);


                                foreach($auth as $tor => $rot)

                                {

                                	if ($tor == $value)

                                	{

                                		echo 'checked';

                                	}

                                	else

                                	{

                                		echo '';

                                	}

                                }

                            }


                            echo '>&nbsp;' . $value;


			    		}


				    	echo  '</td></tr>';

				    }


				    ?>

				</tbody>


			</table>


		    <?= $form->field($model, 'action')->hiddenInput(['rows' => 6])->label(false) ?>


		    <div class="form-group">

		        <?= Html::submitButton($model->isNewRecord ? 'Simpan' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>

		    </div>


		</div>


	</div>


    <?php ActiveForm::end(); ?>


</div>


<?php




$current = $model->isNewRecord ? 'create' : 'update';

$id = $model->isNewRecord ? '' : $model->id;


$url_user_access = Url::to(['user-access/index' , 'id' => $id]);


$js = <<< JS


    $('#check-button').on('click', function(e){

    	e.preventDefault();

        window.location = '$url_user_access' + 

          '&level=' + $('#useraccess-level').val() +

          '&module=' + $('#useraccess-module').val();

    });


JS;


$this->registerJs($js);


?>



Create view index (user-access/index.php)




<?php


use yii\helpers\Html;




/* @var $this yii\web\View */

/* @var $model backend\models\UserAccess */


$this->title = 'Form User Access';

$this->params['breadcrumbs'][] = ['label' => 'User Access', 'url' => ['index']];

$this->params['breadcrumbs'][] = $this->title;

?>

<div class="user-access-create">


    <h2 class="text-center"><?= Html::encode($this->title) ?></h2><hr>


    <?= $this->render('_form', [

        'model' => $model,

        'controller' => $controller,

    ]) ?>


</div>



Thanks to Allah SWT & prophet Muhammad SAW

#sorryForBadEnglish :rolleyes:

Hello @adyoi, I’ve implemented you tutorial and thanks I really like it.
I would like to see this “module” in his final version, how it works and all. My question is… have you finish the parts that save the data in json? Can you or anyone help me with that?