. * */ namespace Vvveb\System\User; use function Vvveb\pregMatch; use function Vvveb\pregMatchAll; use Vvveb\System\Event; use Vvveb\System\Sqlp\Sqlp; class Role { static private $data = null; /* * Checks for permission * * $permission string or array */ public static function has($permission, $allowRules = [], $denyRules = [], $role_id = 0) { //$allowRules = ['*', 'content/posts/*', 'settings']; //$denyRules = ['*/save', '*/delete', 'product/*', 'tools/*', 'users/*', 'theme/*', 'plugin/*']; //allow $allowRegex = '@^' . (str_replace('*', '.+?', implode('$|^', $allowRules))) . '$@m'; //deny $denyRegex = '@^' . (str_replace('*', '.+?', implode('$|^', $denyRules))) . '$@m'; $result = []; if (is_array($permission)) { $permissions = $permission; } else { $permissions = [$permission]; } /* foreach ($permissions as $perm) { $hasPermission = false; if (preg_match($allowRegex, $perm)) { $allow = true; } else { $allow = false; } if (preg_match($denyRegex, $perm)) { $deny = true; } else { $deny = false; } $hasPermission = $allow && ! $deny; $result[$perm] = $hasPermission; }*/ $list = implode("\n", $permissions); $allowList = []; if (preg_match_all($allowRegex, $list, $matches)) { //$allowList = array_map(fn ($value) => true, array_flip($matches[0])); $allowList = array_map(function ($value) { return true; }, array_flip($matches[0])); } $denyList = []; if (preg_match_all($denyRegex, $list, $matches)) { //$denyList = array_map(fn ($value) => false, array_flip($matches[0])); $denyList = array_map(function ($value) {return false; }, array_flip($matches[0])); } //rules that match exactly the permission takes precedence (does not have *) $exactAllow = array_intersect($allowRules, $permissions); $exactDeny = array_intersect($denyRules, $permissions); if ($exactAllow) { $exactAllow = array_map(function ($value) { return true; }, array_flip($exactAllow)); } if ($exactDeny) { $exactDeny = array_map(function ($value) { return false; }, array_flip($exactDeny)); } $result = $exactDeny + $exactAllow + $denyList + $allowList; if (is_array($permission)) { return $result; } else { return $result[$permission] ?? false; } } public static function mkmap($dir, &$path = [], $app = 'admin') { if ($dir[0] == '.') { return; } if (is_dir($dir)) { if ($dh = opendir($dir)) { while (($file = readdir($dh)) !== false) { if ($file[0] == '.') { continue; } $name = basename($dir); $filename = str_replace('.php', '', $file); if (is_dir($dir . '/' . $file)) { self::mkmap($dir . '/' . $file, $path[$name]); } else { if (! in_array($filename, ['base', 'crud', 'listing', 'error404', 'error403', 'error500'])) { //$path[$name][$filename] = self::getActions2($dir . '/' . $file); $class = str_replace(DIR_ROOT . $app . DS . 'controller' . DS, '', $dir . DS . $filename); $class = str_replace('/', '\\', $class); //echo $class; $actions = self::getActions($class, $filename); if ($actions) { $path[$name][$filename] = $actions; } } } } closedir($dh); } } return []; } public static function controllers($app = 'admin') { $tree = []; self::mkmap(DIR_ROOT . $app . DS . 'controller', $tree); return $tree['controller'] ?? []; } public static function getActions($file) { //echo $file; $permission = str_replace('\\', '/', $file); $class = '\\Vvveb\\Controller\\' . $file; //if plugin add namespace if (strpos($file, 'plugins/')) { $pluginName = pregMatch('@/plugins/(.+?)/@', $file, 1); $permission = "plugins/$pluginName$permission"; } if (class_exists($class)) { $methods = get_class_methods($class); $data = []; //add index by default $data['index'] = $permission; if ($methods) { foreach ($methods as $method) { //ignore constructor if ($method[0] != '_' && $method != 'init' && $method != 'goToHelp') { if ($method == 'index') { $data[$method] = $permission; } else { $data[$method] = "$permission/$method"; } } } } return $data; } return []; } public static function getActions2($file) { $permission = substr($file, strpos($file, '/controller/') + 12); //remove extension $permission = substr($permission, 0, strrpos($permission, '.')); //if plugin add namespace if (strpos($file, 'plugins/')) { $pluginName = pregMatch('@/plugins/(.+?)/@', $file, 1); $permission = "plugins/$pluginName$permission"; } $data = []; //$data[$permission] = $permission; $controllerCode = file_get_contents($file); //get all public methods $methods = pregMatchAll('/(? 0) { $next = array_shift($path); foreach (glob("$next/*") as $file) { if (is_dir($file)) { $path[] = $file; } if (is_file($file)) { if (! in_array(basename($file, '.php'), ['base', 'crud', 'listing', 'error404', 'error403', 'error500'])) { $files[] = $file; } } } } sort($files); $data['permissions'] = []; $tree = []; foreach ($files as $file) { //keep only relative controller path $permission = substr($file, strpos($file, '/controller/') + 12); //remove extension $permission = substr($permission, 0, strrpos($permission, '.')); //if plugin add namespace if (strpos($file, 'plugins/')) { $pluginName = pregMatch('@/plugins/(.+?)/@', $file, 1); $permission = "plugins/$pluginName$permission"; } $data['permissions'][] = $permission; $controllerCode = file_get_contents($file); //get all public methods $methods = pregMatchAll('/(? $options) { //rest //$path = $options['module'];//str_replace('/rest/', '/', $route); $path = str_replace('/rest/', '', $route); if (! $path) { $path = 'index'; } if (isset($options['schema'])) { //$path = $options['schema']; } if (strpos($path, '/')) { $slash = explode('/', $path); if ($slash) { $current = &$routeSchemas; foreach ($slash as $name) { if (! isset($current[$name])) { $current[$name] = []; } $current = &$current[$name]; } } } else { $current = &$routeSchemas[$path]; } if (isset($options['methods'])) { foreach ($options['methods'] as $method) { $current[$method] = $path . '/' . $method; } } else { //$routeSchemas[$options['module']] = $options['module']; } } return $routeSchemas; } public static function models($app = 'admin') { $dirSQL = DIR_ROOT . 'admin' . DS . 'sql' . DS . DB_ENGINE . DS; $sqlp = new Sqlp(); $models = []; $files = glob("$dirSQL*.sql"); //var_dump($files); foreach ($files as $file) { $sqlp->parseSqlPfile($file); $tree = $sqlp->getModel(); $model = basename($file, '.sql'); foreach ($tree as $method => $options) { $methodName = $model . '/' . $method; $models[$model][$method] = $methodName; } } return $models; } }