linyaostalker
5 years ago
4 changed files with 198 additions and 103 deletions
-
76backend/controllers/ConfigController.php
-
163backend/logic/PermissionManager.php
-
27backend/views/config/index.php
-
35console/controllers/MenuController.php
@ -1,76 +0,0 @@ |
|||||
<?php |
|
||||
|
|
||||
namespace backend\controllers; |
|
||||
|
|
||||
use Yii; |
|
||||
use backend\models\ars\Category; |
|
||||
use yii\web\Controller; |
|
||||
use yii\web\NotFoundHttpException; |
|
||||
use yii\filters\VerbFilter; |
|
||||
|
|
||||
/** |
|
||||
* CategoryController implements the CRUD actions for Category model. |
|
||||
*/ |
|
||||
class ConfigController extends Controller |
|
||||
{ |
|
||||
/** |
|
||||
* {@inheritdoc} |
|
||||
*/ |
|
||||
public function behaviors() |
|
||||
{ |
|
||||
return [ |
|
||||
'verbs' => [ |
|
||||
'class' => VerbFilter::className(), |
|
||||
'actions' => [ |
|
||||
'delete' => ['POST'], |
|
||||
], |
|
||||
], |
|
||||
]; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Lists all Category models. |
|
||||
* @return mixed |
|
||||
*/ |
|
||||
public function actionIndex() |
|
||||
{ |
|
||||
return $this->render('index'); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* Updates an existing Category model. |
|
||||
* If update is successful, the browser will be redirected to the 'view' page. |
|
||||
* @param integer $id |
|
||||
* @return mixed |
|
||||
* @throws NotFoundHttpException if the model cannot be found |
|
||||
*/ |
|
||||
public function actionUpdate($id) |
|
||||
{ |
|
||||
$model = $this->findModel($id); |
|
||||
|
|
||||
if ($model->load(Yii::$app->request->post()) && $model->save()) { |
|
||||
return $this->redirect('index'); |
|
||||
} |
|
||||
|
|
||||
return $this->render('update', [ |
|
||||
'model' => $model, |
|
||||
]); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Finds the Category model based on its primary key value. |
|
||||
* If the model is not found, a 404 HTTP exception will be thrown. |
|
||||
* @param integer $id |
|
||||
* @return Category the loaded model |
|
||||
* @throws NotFoundHttpException if the model cannot be found |
|
||||
*/ |
|
||||
protected function findModel($id) |
|
||||
{ |
|
||||
if (($model = Category::findOne($id)) !== null) { |
|
||||
return $model; |
|
||||
} |
|
||||
|
|
||||
throw new NotFoundHttpException('The requested page does not exist.'); |
|
||||
} |
|
||||
} |
|
@ -0,0 +1,163 @@ |
|||||
|
<?php |
||||
|
namespace backend\logic; |
||||
|
|
||||
|
use ReflectionClass; |
||||
|
use ReflectionException; |
||||
|
use yii; |
||||
|
|
||||
|
class PermissionManager |
||||
|
{ |
||||
|
/** |
||||
|
* 获取app的已做标记控制器的权限 |
||||
|
* DESCRIBE 控制器描述,只有控制器的注释添加了该描述,才会自动匹配该控制器;使用例子:DESCRIBE {controllerDescribe} DESCRIBE |
||||
|
* ACTION 方法描述,只有控制器下action方法的注释添加了该描述,才会自动匹配该action方法;使用例子:ACTION {actionDescribe} ACTION |
||||
|
* 匹配控制器中actions的方法,需要添加id参数并且在标明含义,例子: |
||||
|
* '{actionName}' => [ |
||||
|
* 'class' => 'xxx\xxx\xxx', |
||||
|
* 'id' => '{actionDescribe}' |
||||
|
* ] |
||||
|
* @return array 返回已匹配到的权限。返回例子:[["{controllerDescribe}"=>["{actionDescribe}"=>"action route"]]] |
||||
|
* @throws yii\base\InvalidConfigException |
||||
|
* @throws ReflectionException |
||||
|
*/ |
||||
|
public static function getAppPermission() |
||||
|
{ |
||||
|
$permission = []; |
||||
|
$permission = self::getControllersAndActions($permission); //获取该app的所有controller权限
|
||||
|
$permission = self::getModuleControllerAndAction($permission); //获取该app引用module的所有controller权限
|
||||
|
return $permission; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取app下controller已标记的action方法权限 |
||||
|
* 这个方法先是获取该app下controller的路径,控制器的命名空间,然后匹配该路径下面的所有控制器文件 |
||||
|
* 截取控制器文件的控制器基础名称,转换为相应url规则名称,拼接为相应类名 |
||||
|
* 根据控制器id,通过[[Module::createControllerByID]]方法实例化该控制器,最后通过[[PermissionManager::constructingPermissionArray]]获取所有已标记的权限 |
||||
|
* @param array $permission 权限数组 |
||||
|
* @return array 权限数组 |
||||
|
* @throws yii\base\InvalidConfigException |
||||
|
* @throws ReflectionException |
||||
|
*/ |
||||
|
private static function getControllersAndActions($permission = []) |
||||
|
{ |
||||
|
$dir = Yii::$app->getControllerPath(); |
||||
|
$nameSpace = Yii::$app->controllerNamespace . "\\"; |
||||
|
$fileList = glob($dir."/*Controller.php"); |
||||
|
foreach ($fileList as $file) { |
||||
|
$baseName = substr(basename($file), 0, -14); |
||||
|
|
||||
|
//根据路由规则转换控制器名称
|
||||
|
$name = strtolower(preg_replace('/(?<![A-Z])[A-Z]/', ' \0', $baseName)); |
||||
|
$id = ltrim(str_replace(' ', '-', $name), '-'); |
||||
|
|
||||
|
$className = $nameSpace . $baseName . 'Controller'; |
||||
|
$controller = Yii::$app->createControllerByID($id); |
||||
|
$permission = self::constructingPermissionArray($controller, $className, $permission); |
||||
|
} |
||||
|
return $permission; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取该app下关联module的已标记controller的权限 |
||||
|
* 这个方法通过[[Module::getModules]]获取该app下关联的module并循环 |
||||
|
* 去除gii和debug,通过[[Module::getModule]]获取子类module,获取命名空间,文件位置,然后匹配该路径下面的所有控制器文件 |
||||
|
* 截取控制器文件的控制器基础名称,转换为相应url规则名称,拼接为相应类名 |
||||
|
* 通过[[BaseYii::createObject]]实例化,最后通过[[PermissionManager::constructingPermissionArray]]获取所有已标记的权限 |
||||
|
* @param array $permission 权限数组 |
||||
|
* @return array 权限数组 |
||||
|
* @throws yii\base\InvalidConfigException |
||||
|
* @throws ReflectionException |
||||
|
*/ |
||||
|
private static function getModuleControllerAndAction($permission = []) |
||||
|
{ |
||||
|
foreach (Yii::$app->getModules() as $id => $child) { |
||||
|
if(in_array($id, ['gii', 'debug'])) { |
||||
|
continue; |
||||
|
} |
||||
|
$module = Yii::$app->getModule($id); |
||||
|
$nameSpace = $module->controllerNamespace."\\"; |
||||
|
$dir = $module->controllerPath; |
||||
|
$fileList = glob($dir."/*Controller.php"); |
||||
|
foreach ($fileList as $file) { |
||||
|
$baseName = substr(basename($file), 0, -14); |
||||
|
$name = strtolower(preg_replace('/(?<![A-Z])[A-Z]/', ' \0', $baseName)); |
||||
|
$id = $module->id.'/'.ltrim(str_replace(' ', '-', $name), '-'); |
||||
|
$className = $nameSpace . $baseName . 'Controller'; |
||||
|
$controller = Yii::createObject($className, [$id, $module]); |
||||
|
$permission = self::constructingPermissionArray($controller, $className, $permission); |
||||
|
} |
||||
|
} |
||||
|
return $permission; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 构建权限数组 |
||||
|
* 根据类名,使用ReflectionClass方法获取该类的信息 |
||||
|
* 通过该类的注释,判断是否存在DESCRIBE标记,以此判断是否要记录该类的权限 |
||||
|
* 若存在标记,则通过[[PermissionManager::getActionsInController]]获取actions里面的方法权限数组,通过[[PermissionManager::getActionInController]]获取该类下面的action方法权限数组 |
||||
|
* @param $controllerObject |
||||
|
* @param $className |
||||
|
* @param array $permission 权限数组 |
||||
|
* @return array 权限数组 |
||||
|
* @throws ReflectionException |
||||
|
*/ |
||||
|
private static function constructingPermissionArray($controllerObject, $className, $permission = []) |
||||
|
{ |
||||
|
$prefix = '/'.$controllerObject->id.'/'; |
||||
|
$reflection = new ReflectionClass($className); //通过ReflectionClass方法获取该类的所有信息,包括参数方法等
|
||||
|
$controllerComment = $reflection->getDocComment(); |
||||
|
$controllerPregRes = preg_match("/(?<=DESCRIBE ).*?(?= DESCRIBE)/", $controllerComment, $controllerDescribe); |
||||
|
if ($controllerPregRes) { |
||||
|
$permission = self::getActionsInController($controllerObject, $controllerDescribe, $prefix, $permission); |
||||
|
$permission = self::getActionInController($reflection, $prefix, $controllerDescribe, $permission); |
||||
|
} |
||||
|
return $permission; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取控制器类中actions的方法权限 |
||||
|
* 根据实例化的控制器类,获取actions的方法并且循环,方法存在id这个参数,则记录 |
||||
|
* 最后放回权限数组 |
||||
|
* @param $controllerObject |
||||
|
* @param $controllerDescribe |
||||
|
* @param $prefix |
||||
|
* @param array $permission 权限数组 |
||||
|
* @return array 权限数组 |
||||
|
*/ |
||||
|
private static function getActionsInController($controllerObject, $controllerDescribe, $prefix, $permission = []) |
||||
|
{ |
||||
|
foreach ($controllerObject->actions() as $id => $item) { |
||||
|
if (isset($item['id'])) { |
||||
|
$permission[$controllerDescribe[0]][$item['id']] = $prefix . $id; |
||||
|
} |
||||
|
} |
||||
|
return $permission; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取控制器类中的action方法权限 |
||||
|
* 获取所有的action方法,若注释中存在ACTION标记,则记录 |
||||
|
* @param $controllerObject |
||||
|
* @param $prefix |
||||
|
* @param $controllerDescribe |
||||
|
* @param array $permission 权限数组 |
||||
|
* @return array 权限数组 |
||||
|
*/ |
||||
|
private static function getActionInController($controllerObject, $prefix, $controllerDescribe, $permission = []) |
||||
|
{ |
||||
|
foreach ($controllerObject->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) { |
||||
|
//action的注释
|
||||
|
$actionComment = $method->getDocComment(); |
||||
|
$actionPregRes = preg_match("/(?<=ACTION ).*?(?= ACTION)/", $actionComment, $actionDescribe); |
||||
|
if ($actionPregRes) { |
||||
|
$actionName = $method->getName(); |
||||
|
if ($actionName != 'actions' && strpos($actionName, 'action') === 0) { |
||||
|
$name = strtolower(preg_replace('/(?<![A-Z])[A-Z]/', ' \0', substr($actionName, 6))); |
||||
|
$id = $prefix . ltrim(str_replace(' ', '-', $name), '-'); |
||||
|
$permission[$controllerDescribe[0]][$actionDescribe[0]] = $id; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return $permission; |
||||
|
} |
||||
|
} |
@ -1,27 +0,0 @@ |
|||||
<?php |
|
||||
/* |
|
||||
* The MIT License |
|
||||
* |
|
||||
* Copyright 2019 Blobt. |
|
||||
* |
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy |
|
||||
* of this software and associated documentation files (the "Software"), to deal |
|
||||
* in the Software without restriction, including without limitation the rights |
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
||||
* copies of the Software, and to permit persons to whom the Software is |
|
||||
* furnished to do so, subject to the following conditions: |
|
||||
* |
|
||||
* The above copyright notice and this permission notice shall be included in |
|
||||
* all copies or substantial portions of the Software. |
|
||||
* |
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
||||
* THE SOFTWARE. |
|
||||
*/ |
|
||||
?>
|
|
||||
|
|
||||
配置页 |
|
@ -0,0 +1,35 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace console\controllers; |
||||
|
|
||||
|
use Yii; |
||||
|
use yii\console\Controller; |
||||
|
use yii\helpers\Console; |
||||
|
|
||||
|
/** |
||||
|
* Description of RbacsetController |
||||
|
* |
||||
|
* @author blobt |
||||
|
*/ |
||||
|
class TestController extends Controller { |
||||
|
|
||||
|
public function actionIndex() { |
||||
|
//Yii::$aa->security->generateRandomString(8);
|
||||
|
$security = Yii::createObject("yii\base\Security"); |
||||
|
$n = 0; |
||||
|
for ($i = 1; $i < 1000; $i++) { |
||||
|
//$key = $security->generateRandomString(8);
|
||||
|
$key = rand(10000000, 99999999); |
||||
|
//$key = strtolower($key);
|
||||
|
//$key = str_replace(['_', '-'], 'a', $key);
|
||||
|
$ret[$key] += 1; |
||||
|
} |
||||
|
|
||||
|
$this->stdout("duplicate data:\n", Console::FG_RED); |
||||
|
foreach ($ret as $k => $v) { |
||||
|
if ($v > 1) { |
||||
|
echo "$k $v\n"; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue