Yii Framework Forum: Behavior AccessControl Rules From Database - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Behavior AccessControl Rules From Database User Access Control Rate Topic: ***** 1 Votes

#1 User is offline   adyoi 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 6
  • Joined: 13-June 17

Posted 21 January 2018 - 05:59 PM

Hello buddy :lol:

Posted Image

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:
2

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users