first commit

This commit is contained in:
2020-06-11 16:42:43 +02:00
commit 449ca1d987
5099 changed files with 622034 additions and 0 deletions
@@ -0,0 +1,108 @@
<?php
namespace AdminAddonUserManager;
/**
* Class Dot
*
* @package SelvinOrtiz\Dot
*
* https://github.com/selvinortiz/dot
*/
class Dot
{
/**
* Returns whether or not the $key exists within $arr
*
* @param array $arr
* @param string $key
*
* @return bool
*/
public static function has($arr, $key)
{
if (strpos($key, '.') !== false && count(($keys = explode('.', $key)))) {
foreach ($keys as $key) {
if (!array_key_exists($key, $arr)) {
return false;
}
$arr = $arr[$key];
}
return true;
}
return array_key_exists($key, $arr);
}
/**
* Returns he value of $key if found in $arr or $default
*
* @param array $arr
* @param string $key
* @param null|mixed $default
*
* @return mixed
*/
public static function get($arr, $key, $default = null)
{
if (strpos($key, '.') !== false && count(($keys = explode('.', $key)))) {
foreach ($keys as $key) {
if (!array_key_exists($key, $arr)) {
return $default;
}
$arr = $arr[$key];
}
return $arr;
}
return array_key_exists($key, $arr) ? $arr[$key] : $default;
}
/**
* Sets the $value identified by $key inside $arr
*
* @param array &$arr
* @param string $key
* @param mixed $value
*/
public static function set(array &$arr, $key, $value)
{
if (strpos($key, '.') !== false && ($keys = explode('.', $key)) && count($keys)) {
while (count($keys) > 1) {
$key = array_shift($keys);
if (!isset($arr[$key]) || !is_array($arr[$key])) {
$arr[$key] = [];
}
$arr = &$arr[$key];
}
$arr[array_shift($keys)] = $value;
} else {
$arr[$key] = $value;
}
}
/**
* Deletes a $key and its value from the $arr
*
* @param array &$arr
* @param string $key
*/
public static function delete(array &$arr, $key)
{
if (strpos($key, '.') !== false && ($keys = explode('.', $key)) && count($keys)) {
while (count($keys) > 1) {
$arr = &$arr[array_shift($keys)];
}
unset($arr[array_shift($keys)]);
} else {
unset($arr[$key]);
}
}
}
@@ -0,0 +1,164 @@
<?php
// Copied from Grav source because it has issues which has been fixed here
namespace AdminAddonUserManager;
use Grav\Common\Data\Blueprints;
use Grav\Common\Data\Data;
use Grav\Common\File\CompiledYamlFile;
use Grav\Common\Grav;
use Grav\Common\Utils;
class Group extends Data {
/**
* Get the groups list
*
* @return array
*/
public static function groups() {
$groups = Grav::instance()['config']->get('groups', []);
$blueprints = new Blueprints;
$blueprint = $blueprints->get('user/group');
foreach ($groups as $groupname => &$content) {
if (!isset($content['groupname'])) {
$content['groupname'] = $groupname;
}
$content = new Group($content, $blueprint);
}
return $groups;
}
/**
* Get the groups list
*
* @return array
*/
public static function groupNames() {
$groups = [];
foreach(Grav::instance()['config']->get('groups', []) as $groupname => $group) {
$groups[$groupname] = isset($group['readableName']) ? $group['readableName'] : $groupname;
}
return $groups;
}
/**
* Checks if a group exists
*
* @param string $groupname
*
* @return bool
*/
public static function groupExists($groupname) {
return isset(self::groups()[$groupname]);
}
/**
* Get a group by name
*
* @param string $groupname
*
* @return object
*/
public static function load($groupname) {
if (self::groupExists($groupname)) {
$group = self::groups()[$groupname];
} else {
$blueprints = new Blueprints;
$blueprint = $blueprints->get('user/group');
$content = ['groupname' => $groupname];
$group = new Group($content, $blueprint);
}
return $group;
}
/**
* Save a group
*/
public function save() {
$grav = Grav::instance();
$config = $grav['config'];
$blueprints = new Blueprints;
$blueprint = $blueprints->get('user/group');
$fields = $blueprint->fields();
$config->set("groups.$this->groupname", []);
foreach ($fields as $field) {
if ($field['type'] == 'text') {
$value = $field['name'];
if (isset($this->items[$value])) {
$config->set("groups.$this->groupname.$value", $this->items[$value]);
}
}
if ($field['type'] == 'array' || $field['type'] == 'permissions') {
$value = $field['name'];
$arrayValues = Utils::getDotNotation($this->items, $field['name']);
if ($arrayValues) {
foreach ($arrayValues as $arrayIndex => $arrayValue) {
$config->set("groups.$this->groupname.$value.$arrayIndex", $arrayValue);
}
}
}
}
$type = 'groups';
$obj = new Data($config->get($type), $blueprint);
$file = CompiledYamlFile::instance($grav['locator']->findResource('config://') . DS . "{$type}.yaml");
$obj->file($file);
$obj->save();
}
/**
* Remove a group
*
* @param string $groupname
*
* @return bool True if the action was performed
*/
public static function remove($groupname) {
$grav = Grav::instance();
$config = $grav['config'];
$blueprints = new Blueprints;
$blueprint = $blueprints->get('user/group');
$groups = $config->get('groups', []);
if (!isset($groups[$groupname])) {
return false;
}
unset($groups[$groupname]);
$config->set('groups', $groups);
$type = 'groups';
$obj = new Data($config->get($type), $blueprint);
$file = CompiledYamlFile::instance($grav['locator']->findResource("config://{$type}.yaml"));
$obj->file($file);
$obj->save();
return true;
}
public function authorize($access) {
if (empty($this->items)) {
return false;
}
if (!isset($this->items['access'])) {
return false;
}
$val = Utils::getDotNotation($this->items['access'], $access);
return Utils::isPositive($val) === true;
}
}
@@ -0,0 +1,242 @@
<?php
namespace AdminAddonUserManager\Groups;
use Grav\Common\Grav;
use Grav\Plugin\AdminAddonUserManagerPlugin;
use Grav\Common\Assets;
use RocketTheme\Toolbox\Event\Event;
use AdminAddonUserManager\Manager as IManager;
use AdminAddonUserManager\Pagination\ArrayPagination;
use \Grav\Common\Utils;
use AdminAddonUserManager\Group;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use \Grav\Common\User\User;
use \AdminAddonUserManager\Users\Manager as UsersManager;
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
use Symfony\Component\ExpressionLanguage\ExpressionFunction;
class Manager implements IManager, EventSubscriberInterface {
private $grav;
private $plugin;
private $adminController;
public function __construct(Grav $grav, AdminAddonUserManagerPlugin $plugin) {
$this->grav = $grav;
$this->plugin = $plugin;
$this->grav['events']->addSubscriber($this);
}
public static function getSubscribedEvents() {
return [
'onAdminControllerInit' => ['onAdminControllerInit', 0],
'onAdminData' => ['onAdminData', 0]
];
}
public function onAdminControllerInit($e) {
$controller = $e['controller'];
$this->adminController = $controller;
}
public function onAdminData($e) {
$type = $e['type'];
if (preg_match('|group-manager|', $type) && ($group = $this->grav['uri']->param('name', false))) {
$obj = Group::load($group);
$post = $this->adminController->data;
if (isset($post['users'])) {
$usersInGroup = $post['users'];
unset($post['users']);
} else {
$usersInGroup = [];
}
$obj->merge($post);
$e['data_type'] = $obj;
foreach (UsersManager::$instance->users() as $u) {
$groups = $u->get('groups', []);
if (in_array($u['username'], $usersInGroup)) {
if (!in_array($obj['groupname'], $groups)) {
$u['groups'] = array_merge($groups, [$obj['groupname']]);
$u->save();
}
} else {
if (in_array($obj['groupname'], $groups)) {
$u['groups'] = array_diff($groups, [$obj['groupname']]);
if (empty($u['groups'])) {
unset($u['groups']);
}
$u->save();
}
}
}
}
}
/**
* Returns the required permission to access the manager
*
* @return string
*/
public function getRequiredPermission() {
return $this->plugin->name . '.groups';
}
/**
* Returns the location of the manager
* It will be accessible at this path
*
* @return string
*/
public function getLocation() {
return 'group-manager';
}
/**
* Returns the plugin hooked nav array
*
* @return array
*/
public function getNav() {
return [
'label' => 'PLUGIN_ADMIN_ADDON_USER_MANAGER.GROUP_MANAGER',
'location' => $this->getLocation(),
'icon' => 'fa-group',
'authorize' => $this->getRequiredPermission(),
'badge' => [
'count' => count($this->groups())
]
];
}
/**
* Initialiaze required assets
*
* @param \Grav\Common\Assets $assets
* @return void
*/
public function initializeAssets(Assets $assets) {
$this->grav['assets']->addCss('plugin://' . $this->plugin->name . '/assets/groups/style.css');
}
/**
* Handle task requests
*
* @param \RocketTheme\Toolbox\Event\Event $event
* @return boolean
*/
public function handleTask(Event $event) {
$method = $event['method'];
if ($method === 'taskGroupDelete' && ($group = $this->grav['uri']->param('name', false))) {
Group::remove($group);
$this->grav->redirect($this->grav['uri']->url($this->getLocation()));
return true;
}
return false;
}
/**
* Logic of the manager goes here
*
* @return array The array to be merged to Twig vars
*/
public function handleRequest() {
$vars = [];
$twig = $this->grav['twig'];
$uri = $this->grav['uri'];
// Bulk actions
if (isset($_POST['selected'])) {
$groupnames = $_POST['selected'];
if (isset($_POST['bulk_delete'])) {
// Bulk delete groups
foreach ($groupnames as $groupname) {
Group::remove($groupname);
}
$this->grav->redirect($this->plugin->getPreviousUrl());
}
}
$group = $this->grav['uri']->param('name', false);
if ($group) {
$vars['exists'] = Group::groupExists($group);
$vars['group'] = $group = Group::load($group);
$users = [];
foreach (UsersManager::$instance->users() as $u) {
if (in_array($group['groupname'], $u->get('groups', []))) {
$users[] = $u->username;
}
}
$group['users'] = $users;
} else {
$vars['fields'] = $this->plugin->getModalsConfiguration()['add_group']['fields'];
$vars['bulkFields'] = $this->plugin->getModalsConfiguration()['bulk_group']['fields'];
$groups = $this->groups();
foreach ($groups as &$group) {
$group['users'] = 0;
foreach (UsersManager::$instance->users() as $u) {
if (in_array($group['groupname'], $u->get('groups', []))) {
$group['users'] += 1;
}
}
}
// Filtering
$filterException = false;
$filter = (empty($_GET['filter'])) ? '' : $_GET['filter'];
$vars['filter'] = $filter;
if ($filter) {
try {
$language = new ExpressionLanguage();
$language->addFunction(ExpressionFunction::fromPhp('count'));
foreach ($groups as $k => $group) {
if (!$language->evaluate($_GET['filter'], ['group' => $group])) {
unset($groups[$k]);
}
}
} catch (\Exception $exception) {
$vars['filterException'] = $exception;
$filterException = true;
}
}
if ($filterException) {
$groups = [];
}
// Pagination
$perPage = $this->plugin->getPluginConfigValue('pagination.per_page', 10);
$pagination = new ArrayPagination($groups, $perPage);
$pagination->paginate($uri->param('page'));
$vars['pagination'] = [
'current' => $pagination->getCurrentPage(),
'count' => $pagination->getPagesCount(),
'total' => $pagination->getRowsCount(),
'perPage' => $pagination->getRowsPerPage(),
'startOffset' => $pagination->getStartOffset(),
'endOffset' => $pagination->getEndOffset()
];
$groups = $pagination->getPaginatedRows();
$vars['groups'] = $groups;
}
return $vars;
}
public function groups() {
return Group::groups();
}
}
@@ -0,0 +1,58 @@
<?php
namespace AdminAddonUserManager;
use Grav\Common\Grav;
use Grav\Plugin\AdminAddonUserManagerPlugin;
use Grav\Common\Assets;
use RocketTheme\Toolbox\Event\Event;
interface Manager {
public function __construct(Grav $grav, AdminAddonUserManagerPlugin $plugin);
/**
* Returns the required permission to access the manager
*
* @return string
*/
public function getRequiredPermission();
/**
* Returns the location of the manager
* It will be accessible at this path
*
* @return string
*/
public function getLocation();
/**
* Returns the plugin hooked nav array
*
* @return array
*/
public function getNav();
/**
* Initialiaze required assets
*
* @param \Grav\Common\Assets $assets
* @return void
*/
public function initializeAssets(Assets $assets);
/**
* Handle task requests
*
* @param \RocketTheme\Toolbox\Event\Event $event
* @return void
*/
public function handleTask(Event $event);
/**
* Logic of the manager goes here
*
* @return array The array to be merged to Twig vars
*/
public function handleRequest();
}
@@ -0,0 +1,81 @@
<?php
namespace AdminAddonUserManager\Pagination;
use AdminAddonUserManager\Pagination\Pagination;
class ArrayPagination implements Pagination {
protected $data;
protected $rowsPerPage;
protected $page;
private $rowsCount = null;
private $slicedData = null;
public function __construct($data, $rowsPerPage = 10) {
$this->data = $data;
$this->rowsPerPage = $rowsPerPage;
$this->page = 1;
}
public function paginate($page) {
if ($page > $this->getPagesCount()) {
$page = $page;
}
if ($page < 1) {
$page = 1;
}
$this->page = $page;
$this->slicedData = null;
}
public function getRowsPerPage() {
return $this->rowsPerPage;
}
public function getRowsCount() {
if ($this->rowsCount !== null) {
return $this->rowsCount;
}
return $this->rowsCount = count($this->data);
}
public function getCurrentPage() {
return $this->page;
}
public function getPagesCount() {
return ceil($this->getRowsCount() / $this->getRowsPerPage());
}
public function getStartOffset() {
return ($this->getCurrentPage() - 1) * $this->getRowsPerPage();
}
public function getEndOffset() {
$endOffset = $this->getStartOffset() + $this->getRowsPerPage();
if ($endOffset > $this->getRowsCount()) {
$endOffset = $this->getRowsCount();
}
return $endOffset;
}
public function getPaginatedRowsCount() {
return $this->getEndOffset() - $this->getStartOffset();
}
public function getPaginatedRows() {
if ($this->slicedData !== null) {
return $this->slicedData;
}
return $this->slicedData = array_slice($this->data, $this->getStartOffset(), $this->getRowsPerPage());
}
}
@@ -0,0 +1,17 @@
<?php
namespace AdminAddonUserManager\Pagination;
interface Pagination {
public function paginate($page);
public function getRowsPerPage();
public function getRowsCount();
public function getCurrentPage();
public function getPagesCount();
public function getStartOffset();
public function getEndOffset();
public function getPaginatedRowsCount();
public function getPaginatedRows();
}
@@ -0,0 +1,100 @@
<?php
namespace AdminAddonUserManager\Users;
use Grav\Common\Grav;
use Grav\Plugin\AdminAddonUserManagerPlugin;
use Grav\Common\Assets;
use RocketTheme\Toolbox\Event\Event;
use AdminAddonUserManager\Manager as IManager;
use Grav\Common\User\User;
use Grav\Common\Data\Blueprints;
class ExpertManager implements IManager {
private $grav;
private $plugin;
public static $instance;
public function __construct(Grav $grav, AdminAddonUserManagerPlugin $plugin) {
$this->grav = $grav;
$this->plugin = $plugin;
self::$instance = $this;
}
/**
* Returns the required permission to access the manager
*
* @return string
*/
public function getRequiredPermission() {
return $this->plugin->name . '.users_expert';
}
/**
* Returns the location of the manager
* It will be accessible at this path
*
* @return string
*/
public function getLocation() {
return 'user-expert';
}
/**
* Returns the plugin hooked nav array
*
* @return array
*/
public function getNav() {
return false;
}
/**
* Initialiaze required assets
*
* @param \Grav\Common\Assets $assets
* @return void
*/
public function initializeAssets(Assets $assets) {
$assets->addCss('plugin://admin/themes/grav/css/codemirror/codemirror.css');
}
/**
* Handle task requests
*
* @param \RocketTheme\Toolbox\Event\Event $event
* @return boolean
*/
public function handleTask(Event $event) {}
/**
* Logic of the manager goes here
*
* @return array The array to be merged to Twig vars
*/
public function handleRequest() {
$vars = [];
$twig = $this->grav['twig'];
$uri = $this->grav['uri'];
$username = $uri->paths()[2];
$user = $this->grav['accounts']->load($username);
if (isset($_POST['raw'])) {
$user->file()->raw($_POST['raw']);
$user->file()->save();
}
$vars['raw'] = $user->file()->raw();
$vars['user'] = $user;
$blueprints = new Blueprints;
$vars['blueprint'] = $blueprints->get('user/account-raw');
return $vars;
}
}
@@ -0,0 +1,432 @@
<?php
namespace AdminAddonUserManager\Users;
use Grav\Common\Grav;
use Grav\Plugin\AdminAddonUserManagerPlugin;
use Grav\Common\Assets;
use Grav\Common\Data\Blueprints;
use RocketTheme\Toolbox\Event\Event;
use AdminAddonUserManager\Manager as IManager;
use AdminAddonUserManager\Pagination\ArrayPagination;
use Grav\Common\Utils;
use Grav\Common\User\User;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
use Symfony\Component\ExpressionLanguage\ExpressionFunction;
use AdminAddonUserManager\Group;
use AdminAddonUserManager\Dot;
class Manager implements IManager, EventSubscriberInterface {
private $grav;
private $plugin;
private $adminController;
/**
* In-memory caching for users
*
* @var Array<User>
*/
private $usersCached = null;
/**
* In-memory cache of the account directory
*
* @var String
*/
private $accountDirCached = null;
public static $instance;
public function __construct(Grav $grav, AdminAddonUserManagerPlugin $plugin) {
$this->grav = $grav;
$this->plugin = $plugin;
self::$instance = $this;
$this->grav['events']->addSubscriber($this);
}
public static function getSubscribedEvents() {
return [
'onAdminControllerInit' => ['onAdminControllerInit', 0],
'onAdminData' => ['onAdminData', 0]
];
}
public function onAdminControllerInit($e) {
$controller = $e['controller'];
$this->adminController = $controller;
}
public function onAdminData($e) {
$type = $e['type'];
if (preg_match('|user-manager/|', $type)) {
$post = $this->adminController->data;
$obj = $this->grav['accounts']->load(preg_replace('|user-manager/|', '', $type));
$obj->merge($post);
$e['data_type'] = $obj;
}
}
/**
* Returns the required permission to access the manager
*
* @return string
*/
public function getRequiredPermission() {
return $this->plugin->name . '.users';
}
/**
* Returns the location of the manager
* It will be accessible at this path
*
* @return string
*/
public function getLocation() {
return 'user-manager';
}
/**
* Returns the plugin hooked nav array
*
* @return array
*/
public function getNav() {
return [
'label' => 'PLUGIN_ADMIN_ADDON_USER_MANAGER.USER_MANAGER',
'location' => $this->getLocation(),
'icon' => 'fa-user',
'authorize' => $this->getRequiredPermission(),
'badge' => [
'count' => count($this->users())
]
];
}
/**
* Initialiaze required assets
*
* @param \Grav\Common\Assets $assets
* @return void
*/
public function initializeAssets(Assets $assets) {
$assets->addCss('plugin://' . $this->plugin->name . '/assets/users/style.css');
}
/**
* Handle task requests
*
* @param \RocketTheme\Toolbox\Event\Event $event
* @return boolean
*/
public function handleTask(Event $event) {
$method = $event['method'];
if ($method === 'taskUserDelete') {
$username = $this->grav['uri']->paths()[2];
if ($this->removeUser($username)) {
$this->adminController->setRedirect($this->getLocation());
}
} elseif ($method === 'taskUserLoginAs') {
$username = $this->grav['uri']->paths()[2];
$user = $this->grav['accounts']->load($username);
$user->authenticated = true;
$this->grav['session']->user = $user;
unset($this->grav['user']);
$this->grav['user'] = $user;
if ($user->authorize('admin.login')) {
$this->adminController->setRedirect('/');
} else {
$this->grav->redirect('/');
}
}
return false;
}
/**
* Logic of the manager goes here
*
* @return array The array to be merged to Twig vars
*/
public function handleRequest() {
$vars = [];
$twig = $this->grav['twig'];
$uri = $this->grav['uri'];
$user = $this->grav['uri']->paths();
if (count($user) == 3) {
$user = $user[2];
} else {
$user = false;
}
if ($user) {
if (isset($_POST['task']) && $_POST['task'] === 'admin-addon-user-manager-save') {
$user = $this->grav['accounts']->load($user);
$post = $_POST['data'];
try {
$user->merge($post);
$method = new \ReflectionMethod('\Grav\Plugin\Admin\AdminController', 'storeFiles');
$method->setAccessible(true);
$user = $method->invoke($this->adminController, $user);
$user->validate();
$user->filter();
$user->save();
} catch (\Exception $e) {
$this->grav['admin']->setMessage($e->getMessage(), 'error');
}
$this->grav->redirect($this->plugin->getPreviousUrl());
} else {
$blueprints = new Blueprints;
$blueprint = $blueprints->get('user/aaum-account');
$vars['blueprints'] = $blueprint;
$vars['user'] = $user = $this->grav['accounts']->load($user);
$vars['exists'] = $user->exists();
}
} else {
// Bulk actions
if (isset($_POST['selected'])) {
$usernames = $_POST['selected'];
if (isset($_POST['bulk_delete'])) {
// Bulk delete
foreach ($usernames as $username) {
$this->removeUser($username);
}
$this->grav->redirect($this->plugin->getPreviousUrl());
} else if (isset($_POST['bulk_add_to_group']) && isset($_POST['groups'])) {
// Bulk add users to groups
$groups = $_POST['groups'];
foreach ($usernames as $username) {
$user = $this->grav['accounts']->load($username);
if ($user->file()->exists()) {
if (!isset($user['groups']) || !is_array($user['groups'])) {
$user['groups'] = [];
}
$user['groups'] = array_unique(array_merge($user['groups'], $groups));
$user->save();
}
}
$this->grav->redirect($this->plugin->getPreviousUrl());
} else if (isset($_POST['bulk_remove_from_group']) && isset($_POST['groups'])) {
// Bulk remove users from groups
$groups = $_POST['groups'];
foreach ($usernames as $username) {
$user = $this->grav['accounts']->load($username);
if ($user->file()->exists()) {
if (!isset($user['groups']) || !is_array($user['groups'])) {
$user['groups'] = [];
}
$user['groups'] = array_unique(array_diff($user['groups'], $groups));
$user->save();
}
}
$this->grav->redirect($this->plugin->getPreviousUrl());
} else if (isset($_POST['bulk_add_acl']) && isset($_POST['permissions'])) {
// Bulk add permissions to users
$access = [];
foreach ($_POST['permissions'] as $p) {
Dot::set($access, $p, true);
}
foreach ($usernames as $username) {
$user = $this->grav['accounts']->load($username);
if ($user->file()->exists()) {
if (!isset($user['access']) || !is_array($user['access'])) {
$user['access'] = [];
}
$user['access'] = array_merge_recursive($user['access'], $access);
$user->save();
}
}
$this->grav->redirect($this->plugin->getPreviousUrl());
} else if (isset($_POST['bulk_remove_acl']) && isset($_POST['permissions'])) {
// Bulk remove permissions from users
foreach ($usernames as $username) {
$user = $this->grav['accounts']->load($username);
if ($user->file()->exists()) {
if (!isset($user['access']) || !is_array($user['access'])) {
$user['access'] = [];
}
$access = $user['access'];
foreach ($_POST['permissions'] as $p) {
Dot::delete($access, $p);
}
$user['access'] = $access;
$user->save();
}
}
$this->grav->redirect($this->plugin->getPreviousUrl());
}
}
$vars['fields'] = $this->plugin->getModalsConfiguration()['add_user']['fields'];
$vars['bulkFields'] = $this->plugin->getModalsConfiguration()['bulk_user']['fields'];
$vars['groupnames'] = Group::groupNames();
$permissions = array_keys($this->grav['admin']->getPermissions());
foreach ($permissions as $k=>&$v) $v = ['text' => $v, 'value' => $v];
$vars['permissions'] = $permissions;
// List style (grid or list)
$listStyle = $uri->param('listStyle');
if ($listStyle !== 'grid' && $listStyle !== 'list') {
$listStyle = $this->plugin->getPluginConfigValue('default_list_style', 'grid');
}
$vars['listStyle'] = $listStyle;
$users = $this->users();
// Filtering
$filterException = false;
$filter = (empty($_GET['filter'])) ? '' : $_GET['filter'];
$vars['filter'] = $filter;
if ($filter) {
try {
$language = new ExpressionLanguage();
$language->addFunction(ExpressionFunction::fromPhp('count'));
foreach ($users as $k => $user) {
if (!is_array($user->groups)) {
$user->groups = [];
}
if (!$language->evaluate($_GET['filter'], ['user' => $user])) {
unset($users[$k]);
}
}
} catch (\Exception $exception) {
$vars['filterException'] = $exception;
$filterException = true;
}
}
if ($filterException) {
$users = [];
}
// Pagination
$perPage = $this->plugin->getPluginConfigValue('pagination.per_page', 10);
$pagination = new ArrayPagination($users, $perPage);
$pagination->paginate($uri->param('page'));
$vars['pagination'] = [
'current' => $pagination->getCurrentPage(),
'count' => $pagination->getPagesCount(),
'total' => $pagination->getRowsCount(),
'perPage' => $pagination->getRowsPerPage(),
'startOffset' => $pagination->getStartOffset(),
'endOffset' => $pagination->getEndOffset()
];
$vars['users'] = $pagination->getPaginatedRows();
$vars['user'] = false;
}
return $vars;
}
public function users() {
if ($this->usersCached) {
return $this->usersCached;
}
$users = [];
$dir = $this->getAccountDir();
// Try cache
$cache = $this->grav['cache'];
$cacheKey = $this->plugin->name . '.users';
$modifyTime = filemtime($dir);
$usersCache = $cache->fetch($cacheKey);
if (!$usersCache || $modifyTime > $usersCache['modifyTime']) {
// Find accounts
$files = $dir ? array_diff(scandir($dir), ['.', '..']) : [];
foreach ($files as $file) {
if (Utils::endsWith($file, YAML_EXT)) {
$user = $this->grav['accounts']->load(trim(pathinfo($file, PATHINFO_FILENAME)));
$users[$user->username] = $user;
}
}
// Populate and/or refresh cache
$this->saveUsersToCache($users);
} else {
$users = $usersCache['users'];
}
$this->usersCached = $users;
return $users;
}
private function saveUsersToCache($users) {
$cache = $this->grav['cache'];
$cacheKey = $this->plugin->name . '.users';
$dir = $this->getAccountDir();
$modifyTime = filemtime($dir);
$usersCache = [
'modifyTime' => $modifyTime,
'users' => $users,
];
$cache->save($cacheKey, $usersCache);
}
private function getAccountDir() {
if ($this->accountDirCached) {
return $this->grav['locator']->findResource('account://');
}
return $this->accountDirCached = $this->grav['locator']->findResource('account://');
}
public function removeUser($username) {
$user = $this->grav['accounts']->load($username);
if ($user->file()->exists()) {
$users = $this->users();
$user->file()->delete();
// Prevent users cache refresh
unset($users[$username]);
$this->saveUsersToCache($users);
return true;
}
return false;
}
public static function userNames() {
$instance = self::$instance;
$users = $instance->users();
$userNames = [];
foreach ($users as $u) {
$userNames[$u['username']] = $u['username'];
}
return $userNames;
}
}