summaryrefslogtreecommitdiffstats
path: root/inc
diff options
context:
space:
mode:
authorroot2019-02-19 18:53:50 +0100
committerroot2019-02-19 18:53:50 +0100
commit0ad4c0f8196b61699754762aacbaab0223478ab9 (patch)
treede434c4aea8d07ecd01cd3badd48d057d62c2d1b /inc
parent[usb-lock-off] Edit rule cleanup and fix of the dropdown boxes. (diff)
parent[statistics] Fix RAM change warning to handle increase too (diff)
downloadslx-admin-0ad4c0f8196b61699754762aacbaab0223478ab9.tar.gz
slx-admin-0ad4c0f8196b61699754762aacbaab0223478ab9.tar.xz
slx-admin-0ad4c0f8196b61699754762aacbaab0223478ab9.zip
Merge branch 'master' into usb-lock-offusb-lock-off
Diffstat (limited to 'inc')
-rw-r--r--inc/dashboard.inc.php7
-rw-r--r--inc/database.inc.php15
-rw-r--r--inc/dictionary.inc.php15
-rw-r--r--inc/event.inc.php16
-rw-r--r--inc/module.inc.php63
-rw-r--r--inc/paginate.inc.php2
-rw-r--r--inc/permission.inc.php36
-rw-r--r--inc/property.inc.php2
-rw-r--r--inc/render.inc.php8
-rw-r--r--inc/taskmanager.inc.php40
-rw-r--r--inc/taskmanagercallback.inc.php9
-rw-r--r--inc/trigger.inc.php33
-rw-r--r--inc/user.inc.php69
-rw-r--r--inc/util.inc.php30
14 files changed, 268 insertions, 77 deletions
diff --git a/inc/dashboard.inc.php b/inc/dashboard.inc.php
index 3db42efb..d576a8f1 100644
--- a/inc/dashboard.inc.php
+++ b/inc/dashboard.inc.php
@@ -68,7 +68,7 @@ class Dashboard
'url' => urlencode($_SERVER['REQUEST_URI']),
'langs' => Dictionary::getLanguages(true),
'user' => User::getName(),
- 'warning' => User::getName() !== false && User::getLastSeenEvent() < Property::getLastWarningId(),
+ 'warning' => User::getName() !== false && User::hasPermission('.eventlog.*') && User::getLastSeenEvent() < Property::getLastWarningId(),
'needsSetup' => User::getName() !== false && Property::getNeedsSetup()
));
}
@@ -103,5 +103,10 @@ class Dashboard
{
self::$subMenu[] = array('url' => $url, 'name' => $name);
}
+
+ public static function getSubmenus()
+ {
+ return self::$subMenu;
+ }
} \ No newline at end of file
diff --git a/inc/database.inc.php b/inc/database.inc.php
index 082b13b6..3b2414b5 100644
--- a/inc/database.inc.php
+++ b/inc/database.inc.php
@@ -77,6 +77,19 @@ class Database
}
/**
+ * Fetch the first column of the query as a plain list-of-values array.
+ *
+ * @return array|bool List of values representing first column of query
+ */
+ public static function queryColumnArray($query, $args = array(), $ignoreError = null)
+ {
+ $res = self::simpleQuery($query, $args, $ignoreError);
+ if ($res === false)
+ return false;
+ return $res->fetchAll(PDO::FETCH_COLUMN, 0);
+ }
+
+ /**
* Execute the given query and return the number of rows affected.
* Mostly useful for UPDATEs or INSERTs
*
@@ -132,7 +145,7 @@ class Database
if (!isset(self::$statements[$query])) {
self::$statements[$query] = self::$dbh->prepare($query);
} else {
- self::$statements[$query]->closeCursor();
+ //self::$statements[$query]->closeCursor();
}
$start = microtime(true);
if (self::$statements[$query]->execute($args) === false) {
diff --git a/inc/dictionary.inc.php b/inc/dictionary.inc.php
index ee196f59..935d1f4e 100644
--- a/inc/dictionary.inc.php
+++ b/inc/dictionary.inc.php
@@ -17,6 +17,8 @@ class Dictionary
{
self::$languages = array();
foreach (glob('lang/??', GLOB_ONLYDIR) as $lang) {
+ if (!file_exists($lang . '/name.txt') && !file_exists($lang . '/flag.png'))
+ continue;
$lang = basename($lang);
if ($lang === '..')
continue;
@@ -28,10 +30,15 @@ class Dictionary
if ($lang !== false && in_array($lang, self::$languages)) {
setcookie('lang', $lang, time() + 60 * 60 * 24 * 30 * 12);
$url = Request::get('url');
- if ($url === false && isset($_SERVER['HTTP_REFERER']))
+ if ($url === false && isset($_SERVER['HTTP_REFERER'])) {
$url = $_SERVER['HTTP_REFERER'];
- if ($url === false)
- $url = '?do=Main';
+ }
+ $parts = parse_url($url);
+ if ($url === false || $parts === false || empty($parts['query'])) {
+ $url = '?do=main';
+ } else {
+ $url = '?' . $parts['query'];
+ }
Util::redirect($url);
}
@@ -191,6 +198,8 @@ class Dictionary
foreach (self::$languages as $lang) {
if (file_exists("lang/$lang/name.txt")) {
$name = file_get_contents("lang/$lang/name.txt");
+ } else {
+ $name = false;
}
if (!isset($name) || $name === false) {
$name = $lang;
diff --git a/inc/event.inc.php b/inc/event.inc.php
index 66601607..4e68ab6d 100644
--- a/inc/event.inc.php
+++ b/inc/event.inc.php
@@ -24,6 +24,17 @@ class Event
Property::clearList('cron.key.status');
Property::clearList('cron.key.blocked');
+ // Hooks
+ foreach (Hook::load('bootup') as $hook) {
+ // Isolate for local vars
+ $fun = function() use ($hook) {
+ include_once($hook->file);
+ };
+ $fun();
+ }
+
+ // TODO: Modularize (hooks)
+
// Tasks: fire away
$mountStatus = false;
$mountId = Trigger::mount();
@@ -98,8 +109,7 @@ class Event
public static function serverIpChanged()
{
error_log('Server ip changed');
- global $tidIpxe;
- $tidIpxe = Trigger::ipxe();
+ Trigger::ipxe();
if (Module::isAvailable('sysconfig')) { // TODO: Modularize events
ConfigModule::serverIpChanged();
}
@@ -111,6 +121,8 @@ class Event
public static function activeConfigChanged()
{
$task = Trigger::ldadp();
+ if ($task === false)
+ return;
TaskmanagerCallback::addCallback($task, 'ldadpStartup');
}
diff --git a/inc/module.inc.php b/inc/module.inc.php
index 7610c720..6d160787 100644
--- a/inc/module.inc.php
+++ b/inc/module.inc.php
@@ -35,7 +35,7 @@ class Module
if ($module === false)
return false;
if ($activate) {
- $module->activate();
+ $module->activate(1, true);
}
return !$module->hasMissingDependencies();
}
@@ -139,9 +139,11 @@ class Module
*/
private $category = false;
+ private $clientPlugin = false;
private $depsMissing = false;
private $depsChecked = false;
private $activated = false;
+ private $directActivation = false;
private $dependencies = array();
private $name;
/**
@@ -165,6 +167,9 @@ class Module
if (isset($json['category']) && is_string($json['category'])) {
$this->category = $json['category'];
}
+ if (isset($json['client-plugin'])) {
+ $this->clientPlugin = (bool)$json['client-plugin'];
+ }
$this->name = $name;
}
@@ -184,21 +189,33 @@ class Module
return new $class();
}
- public function activate($depth = 1)
+ public function activate($depth, $direct)
{
- if ($this->activated !== false || $this->depsMissing)
- return $this->activated !== false;
+ if ($this->depsMissing)
+ return false;
+ if ($this->activated !== false && ($this->directActivation || !$direct))
+ return true;
+ if ($depth === null && $direct === null) {
+ // This is the current page, always load its scripts
+ $this->clientPlugin = true;
+ $direct = true;
+ }
+ if ($this->activated === false) {
+ spl_autoload_register(function ($class) {
+ $file = 'modules/' . $this->name . '/inc/' . preg_replace('/[^a-z0-9]/', '', strtolower($class)) . '.inc.php';
+ if (!file_exists($file))
+ return;
+ require_once $file;
+ });
+ }
$this->activated = $depth;
- spl_autoload_register(function($class) {
- $file = 'modules/' . $this->name . '/inc/' . preg_replace('/[^a-z0-9]/', '', strtolower($class)) . '.inc.php';
- if (!file_exists($file))
- return;
- require_once $file;
- });
+ if ($direct) {
+ $this->directActivation = true;
+ }
foreach ($this->dependencies as $dep) {
$get = self::get($dep);
if ($get !== false) {
- $get->activate($depth + 1);
+ $get->activate($depth + 1, $direct && $this->clientPlugin);
}
}
return true;
@@ -263,26 +280,26 @@ class Module
return 'modules/' . $this->name;
}
- public function getScripts($externalOnly)
+ public function getScripts()
{
- if (!$externalOnly) {
- if (!isset($this->scripts['clientscript.js']) && file_exists($this->getDir() . '/clientscript.js')) {
- $this->scripts['clientscript.js'] = false;
+ if ($this->directActivation && $this->clientPlugin) {
+ if (!in_array('clientscript.js', $this->scripts) && file_exists($this->getDir() . '/clientscript.js')) {
+ $this->scripts[] = 'clientscript.js';
}
- return array_keys($this->scripts);
+ return $this->scripts;
}
- return array_keys(array_filter($this->scripts));
+ return [];
}
- public function getCss($externalOnly)
+ public function getCss()
{
- if (!$externalOnly) {
- if (!isset($this->css['style.css']) && file_exists($this->getDir() . '/style.css')) {
- $this->css['style.css'] = false;
+ if ($this->directActivation && $this->clientPlugin) {
+ if (!in_array('style.css', $this->css) && file_exists($this->getDir() . '/style.css')) {
+ $this->css[] = 'style.css';
}
- return array_keys($this->css);
+ return $this->css;
}
- return array_keys(array_filter($this->css));
+ return [];
}
}
diff --git a/inc/paginate.inc.php b/inc/paginate.inc.php
index cdb4adf1..b212e252 100644
--- a/inc/paginate.inc.php
+++ b/inc/paginate.inc.php
@@ -65,8 +65,6 @@ class Paginate
$countQuery = preg_replace('/ORDER\s+BY\s.*?(\sASC|\sDESC|$)/is', '', $this->query);
$countQuery = preg_replace('/SELECT\s.*?\sFROM\s/is', 'SELECT Count(*) AS rowcount FROM ', $countQuery);
$countRes = Database::queryFirst($countQuery, $args);
- $args['limit_start'] = $this->currentPage;
- $args['limit_count'] = $this->perPage;
$query = $this->query . ' LIMIT ' . ($this->currentPage * $this->perPage) . ', ' . $this->perPage;
$retval = Database::simpleQuery($query, $args);
$this->totalRows = (int)$countRes['rowcount'];
diff --git a/inc/permission.inc.php b/inc/permission.inc.php
index d04e3c3b..aaef6ba6 100644
--- a/inc/permission.inc.php
+++ b/inc/permission.inc.php
@@ -15,5 +15,41 @@ class Permission
return self::$permissions[$permission];
}
+
+ // TODO: Doc/Refactor
+ public static function addGlobalTags(&$array, $locationid, $disabled, $noneAvailDisabled = null)
+ {
+ if (Module::get('permissionmanager') === false)
+ return;
+ $one = false;
+ foreach ($disabled as $perm) {
+ if (User::hasPermission($perm, $locationid)) {
+ $one = true;
+ continue;
+ }
+ if (strpos($perm, '.') === false) {
+ $array[$perm] = ['disabled' => 'disabled', 'readonly' => 'readonly'];
+ continue;
+ }
+ $temp =& $array;
+ foreach (explode('.', $perm) as $sub) {
+ if (empty($sub) || $sub === '*')
+ continue;
+ $temp =& $temp[$sub];
+ }
+ $temp = ['disabled' => 'disabled', 'readonly' => 'readonly'];
+ }
+ if (!$one && !is_null($noneAvailDisabled)) {
+ $array[$noneAvailDisabled]['disabled'] = true;
+ }
+ }
+
+ public static function moduleHasPermissions($moduleId)
+ {
+ if (Module::get('permissionmanager') === false)
+ return true;
+ return file_exists('modules/' . $moduleId . '/permissions/permissions.json');
+ }
+
}
diff --git a/inc/property.inc.php b/inc/property.inc.php
index 56adb823..b69be1f8 100644
--- a/inc/property.inc.php
+++ b/inc/property.inc.php
@@ -168,7 +168,7 @@ class Property
if (!Taskmanager::isFinished($task)) {
$task = Taskmanager::waitComplete($task['id'], 5000);
}
- if ($task['statusCode'] !== TASK_FINISHED || !isset($task['data']['content'])) {
+ if ($task['statusCode'] !== Taskmanager::TASK_FINISHED || !isset($task['data']['content'])) {
return isset($task['data']['error']) ? $task['data']['error'] : 'Timeout';
}
$data = json_decode($task['data']['content'], true);
diff --git a/inc/render.inc.php b/inc/render.inc.php
index 0ce39dbe..4da0567e 100644
--- a/inc/render.inc.php
+++ b/inc/render.inc.php
@@ -84,7 +84,7 @@ class Render
';
// Include any module specific styles
foreach ($modules as $module) {
- $files = $module->getCss($module !== $pageModule);
+ $files = $module->getCss();
foreach ($files as $file) {
echo '<link href="', $module->getDir(), '/', $file, '" rel="stylesheet" media="screen">';
}
@@ -113,7 +113,7 @@ class Render
<script src="script/slx-fixes.js"></script>
';
foreach ($modules as $module) {
- $files = $module->getScripts($module !== $pageModule);
+ $files = $module->getScripts();
foreach ($files as $file) {
echo '<script src="', $module->getDir(), '/', $file, '"></script>';
}
@@ -213,7 +213,7 @@ class Render
* @param string $module name of module to load template from; defaults to currently active module
* @return string Rendered template
*/
- public static function parse($template, $params = false, $module = false)
+ public static function parse($template, $params = false, $module = false, $lang = false)
{
if ($module === false && class_exists('Page')) {
$module = Page::getModule()->getIdentifier();
@@ -228,7 +228,7 @@ class Render
}
// Now find all language tags in this array
if (preg_match_all('/{{\s*(lang_.+?)\s*}}/', $html, $out) > 0) {
- $dictionary = Dictionary::getArray($module, 'template-tags');
+ $dictionary = Dictionary::getArray($module, 'template-tags', $lang);
$fallback = false;
foreach ($out[1] as $tag) {
if ($fallback === false && empty($dictionary[$tag])) {
diff --git a/inc/taskmanager.inc.php b/inc/taskmanager.inc.php
index cdc90f55..dab950ed 100644
--- a/inc/taskmanager.inc.php
+++ b/inc/taskmanager.inc.php
@@ -6,6 +6,13 @@
class Taskmanager
{
+ const NO_SUCH_TASK = 'NO_SUCH_TASK';
+ const TASK_FINISHED = 'TASK_FINISHED';
+ const TASK_ERROR = 'TASK_ERROR';
+ const TASK_WAITING = 'TASK_WAITING';
+ const NO_SUCH_INSTANCE = 'NO_SUCH_INSTANCE';
+ const TASK_PROCESSING = 'TASK_PROCESSING';
+
/**
* UDP socket used for communication with the task manager
* @var resource
@@ -49,7 +56,7 @@ class Taskmanager
if ($async)
return true;
$reply = self::readReply($seq);
- if ($reply === false || !is_array($reply) || !isset($reply['id']) || (isset($reply['statusCode']) && $reply['statusCode'] === NO_SUCH_TASK)) {
+ if ($reply === false || !is_array($reply) || !isset($reply['id']) || (isset($reply['statusCode']) && $reply['statusCode'] === Taskmanager::NO_SUCH_TASK)) {
self::addErrorMessage($reply);
return false;
}
@@ -82,15 +89,22 @@ class Taskmanager
/**
* Checks whether the given task id corresponds to a known task in the taskmanager.
* Returns true iff the taskmanager is reachable and the status of the task
- * is different from NO_SUCH_TASK.
+ * is different from Taskmanager::NO_SUCH_INSTANCE/_TASK.
+ * If you pass an array it is assumed that it was already queried and is evaluated
+ * directly.
*
- * @param string $taskid a task id
+ * @param string|array $taskid a task id or a task array returned by ::status or ::submit
* @return boolean true if taskid exists in taskmanager
*/
- public static function isTask($taskid)
+ public static function isTask($task)
{
- $task = self::status($taskid);
- return isset($task['statusCode']) && $task['statusCode'] !== NO_SUCH_TASK;
+ if ($task === false)
+ return false;
+ if (is_string($task)) {
+ $task = self::status($task);
+ }
+ return isset($task['statusCode']) && $task['statusCode'] !== Taskmanager::NO_SUCH_INSTANCE
+ && $task['statusCode'] !== Taskmanager::NO_SUCH_TASK;
}
/**
@@ -103,7 +117,7 @@ class Taskmanager
public static function waitComplete($task, $timeout = 2500)
{
if (is_array($task) && isset($task['id'])) {
- if ($task['statusCode'] !== TASK_PROCESSING && $task['statusCode'] !== TASK_WAITING) {
+ if ($task['statusCode'] !== Taskmanager::TASK_PROCESSING && $task['statusCode'] !== Taskmanager::TASK_WAITING) {
self::release($task['id']);
return $task;
}
@@ -117,7 +131,7 @@ class Taskmanager
$status = self::status($task);
if (!isset($status['statusCode']))
break;
- if ($status['statusCode'] !== TASK_PROCESSING && $status['statusCode'] !== TASK_WAITING) {
+ if ($status['statusCode'] !== Taskmanager::TASK_PROCESSING && $status['statusCode'] !== Taskmanager::TASK_WAITING) {
$done = true;
break;
}
@@ -140,7 +154,7 @@ class Taskmanager
{
if (!is_array($task) || !isset($task['statusCode']) || !isset($task['id']))
return true;
- if ($task['statusCode'] !== TASK_WAITING && $task['statusCode'] !== TASK_PROCESSING && $task['statusCode'] !== TASK_FINISHED)
+ if ($task['statusCode'] !== Taskmanager::TASK_WAITING && $task['statusCode'] !== Taskmanager::TASK_PROCESSING && $task['statusCode'] !== Taskmanager::TASK_FINISHED)
return true;
return false;
}
@@ -156,7 +170,7 @@ class Taskmanager
{
if (!is_array($task) || !isset($task['statusCode']) || !isset($task['id']))
return false;
- if ($task['statusCode'] !== TASK_WAITING && $task['statusCode'] !== TASK_PROCESSING)
+ if ($task['statusCode'] !== Taskmanager::TASK_WAITING && $task['statusCode'] !== Taskmanager::TASK_PROCESSING)
return true;
return false;
}
@@ -210,7 +224,7 @@ class Taskmanager
private static function readReply($seq)
{
$tries = 0;
- while (($bytes = socket_recvfrom(self::$sock, $buf, 90000, 0, $bla1, $bla2)) !== false || socket_last_error() === 11) {
+ while (($bytes = @socket_recvfrom(self::$sock, $buf, 90000, 0, $bla1, $bla2)) !== false || socket_last_error() === 11) {
$parts = explode(',', $buf, 2);
// Do we have compressed data?
if (substr($parts[0], 0, 3) === '+z:') {
@@ -237,7 +251,3 @@ class Taskmanager
}
}
-
-foreach (array('TASK_FINISHED', 'TASK_ERROR', 'TASK_WAITING', 'NO_SUCH_TASK', 'TASK_PROCESSING') as $i) {
- define($i, $i);
-}
diff --git a/inc/taskmanagercallback.inc.php b/inc/taskmanagercallback.inc.php
index ab8affac..8e253962 100644
--- a/inc/taskmanagercallback.inc.php
+++ b/inc/taskmanagercallback.inc.php
@@ -22,7 +22,7 @@ class TaskmanagerCallback
if (is_array($task) && isset($task['id']))
$task = $task['id'];
if (!is_string($task)) {
- EventLog::warning("addCallback: Not a valid task id: $task");
+ EventLog::warning("addCallback: Not a valid task id: $task", print_r(debug_backtrace(), true));
return;
}
$data = array(
@@ -136,7 +136,7 @@ class TaskmanagerCallback
$mod = Module::get('sysconfig');
if ($mod === false)
return;
- $mod->activate();
+ $mod->activate(1, false);
if (Taskmanager::isFailed($task)) {
ConfigModule::generateFailed($task, $args);
} else {
@@ -155,7 +155,7 @@ class TaskmanagerCallback
$mod = Module::get('sysconfig');
if ($mod === false)
return;
- $mod->activate();
+ $mod->activate(1, false);
if (Taskmanager::isFailed($task)) {
ConfigTgz::generateFailed($task, $args);
} else {
@@ -172,7 +172,8 @@ class TaskmanagerCallback
Property::setVmStoreConfig($args);
return;
}
- if ($task['data']['exitCode'] > 0) {
+ // If code is 99 then the script failed to even unmount -- don't change anything
+ if ($task['data']['exitCode'] != 99) {
// Manual mount failed with non-taskmanager related error - reset storage type to reflect situation
$data = Property::getVmStoreConfig();
if (isset($data['storetype'])) {
diff --git a/inc/trigger.inc.php b/inc/trigger.inc.php
index 2af73872..e89a9a17 100644
--- a/inc/trigger.inc.php
+++ b/inc/trigger.inc.php
@@ -20,12 +20,24 @@ class Trigger
*/
public static function ipxe()
{
- $data = Property::getBootMenu();
- $data['ipaddress'] = Property::getServerIp();
- $task = Taskmanager::submit('CompileIPxe', $data);
- if (!isset($task['id']))
- return false;
- return $task['id'];
+ $hooks = Hook::load('ipxe-update');
+ $taskId = false;
+ foreach ($hooks as $hook) {
+ $ret = function($taskId) use ($hook) {
+ $ret = include_once($hook->file);
+ if (is_string($ret))
+ return $ret;
+ return isset($taskId) ? $taskId : false;
+ };
+ $ret = $ret($taskId);
+ if (is_string($ret)) {
+ $taskId = $ret;
+ } elseif (is_array($ret) && isset($ret['id'])) {
+ $taskId = $ret['id'];
+ }
+ }
+ Property::set('ipxe-task-id', $taskId, 15);
+ return $taskId;
}
/**
@@ -127,14 +139,23 @@ class Trigger
}
if ($storetype === 'nfs') {
$addr = $vmstore['nfsaddr'];
+ $opts = 'nfsopts';
} elseif ($storetype === 'cifs') {
$addr = $vmstore['cifsaddr'];
+ $opts = 'cifsopts';
} else {
+ $opts = null;
$addr = 'null';
}
+ if (isset($vmstore[$opts])) {
+ $opts = $vmstore[$opts];
+ }else {
+ $opts = null;
+ }
return Taskmanager::submit('MountVmStore', array(
'address' => $addr,
'type' => 'images',
+ 'opts' => $opts,
'username' => $vmstore['cifsuser'],
'password' => $vmstore['cifspasswd']
));
diff --git a/inc/user.inc.php b/inc/user.inc.php
index 81091e1b..20e8cd3d 100644
--- a/inc/user.inc.php
+++ b/inc/user.inc.php
@@ -31,8 +31,19 @@ class User
if (!self::isLoggedIn())
return false;
if (Module::isAvailable("permissionmanager")) {
- $module = Page::getModule();
- $permission = $module ? $module->getIdentifier().".".$permission : $permission;
+ if ($permission{0} === '.') {
+ $permission = substr($permission, 1);
+ } else {
+ if (class_exists('Page')) {
+ $module = Page::getModule();
+ if ($module !== false) {
+ $module = $module->getIdentifier();
+ }
+ } else {
+ $module = strtolower(Request::any('do'));
+ }
+ $permission = $module ? $module . "." . $permission : $permission;
+ }
return PermissionUtil::userHasPermission(self::$user['userid'], $permission, $locationid);
}
if (self::$user['permissions'] & Permission::get('superadmin'))
@@ -40,15 +51,60 @@ class User
return (self::$user['permissions'] & Permission::get($permission)) != 0;
}
+ /**
+ * Confirm current user has the given permission, stop execution and show error message
+ * otherwise.
+ * @param string $permission Permission to check for
+ * @param null|int $locationid location this permission has to apply to, NULL if any location is sufficient
+ * @param null|string $redirect page to redirect to if permission is not given, NULL defaults to main page
+ */
+ public static function assertPermission($permission, $locationid = NULL, $redirect = NULL)
+ {
+ if (User::hasPermission($permission, $locationid))
+ return;
+ if (AJAX) {
+ Message::renderList();
+ exit;
+ }
+ if (!is_null($redirect)) {
+ Message::addError('main.no-permission');
+ Util::redirect($redirect);
+ } elseif (Module::isAvailable('permissionmanager')) {
+ if ($permission{0} !== '.') {
+ $module = Page::getModule();
+ if ($module !== false) {
+ $permission = '.' . $module->getIdentifier() . '.' . $permission;
+ }
+ }
+ Util::redirect('?do=permissionmanager&show=denied&permission=' . urlencode($permission));
+ } else {
+ Message::addError('main.no-permission');
+ Util::redirect('?do=main');
+ }
+ }
+
public static function getAllowedLocations($permission)
{
+ if (!self::isLoggedIn())
+ return [];
if (Module::isAvailable("permissionmanager")) {
- $module = Page::getModule();
- $permission = $module ? $module->getIdentifier().".".$permission : $permission;
+ if ($permission{0} === '.') {
+ $permission = substr($permission, 1);
+ } else {
+ $module = Page::getModule();
+ $permission = $module ? $module->getIdentifier() . "." . $permission : $permission;
+ }
return PermissionUtil::getAllowedLocations(self::$user['userid'], $permission);
}
- if (self::$user['permissions'] & Permission::get('superadmin'))
- return array_keys(Location::getLocationsAssoc());
+ if (self::$user['permissions'] & Permission::get('superadmin')) {
+ if (Module::isAvailable('locations')) {
+ $a = array_keys(Location::getLocationsAssoc());
+ $a[] = 0;
+ } else {
+ $a = [0];
+ }
+ return $a;
+ }
return array();
}
@@ -63,6 +119,7 @@ class User
self::$user = Database::queryFirst('SELECT * FROM user WHERE userid = :uid LIMIT 1', array(':uid' => $uid));
if (self::$user === false)
self::logout();
+ settype(self::$user['userid'], 'int');
return true;
}
return false;
diff --git a/inc/util.inc.php b/inc/util.inc.php
index 69eaf941..e459cc46 100644
--- a/inc/util.inc.php
+++ b/inc/util.inc.php
@@ -179,6 +179,13 @@ SADFACE;
$location .= '&' . implode('&', self::$redirectParams);
}
}
+ if (CONFIG_DEBUG) {
+ global $global_start;
+ $duration = microtime(true) - $global_start;
+ error_log('Redirect: ' . round($duration, 3) . 's, '
+ . Database::getQueryCount() . ' queries, '
+ . round(Database::getQueryTime(), 3) . 's query time total');
+ }
Header('Location: ' . $location);
exit(0);
}
@@ -227,18 +234,23 @@ SADFACE;
*
* @param float|int $bytes numeric value of the filesize to make readable
* @param int $decimals number of decimals to show, -1 for automatic
- * @return string human readable string representing the given filesize
+ * @param int $shift how many units to skip, i.e. if you pass in KiB or MiB
+ * @return string human readable string representing the given file size
*/
- public static function readableFileSize($bytes, $decimals = -1)
+ public static function readableFileSize($bytes, $decimals = -1, $shift = 0)
{
+ $bytes = round($bytes);
static $sz = array('Byte', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB');
$factor = (int)floor((strlen($bytes) - 1) / 3);
- if ($factor == 0) {
+ if ($factor === 0) {
$decimals = 0;
- } elseif ($decimals === -1) {
- $decimals = 2 - floor((strlen($bytes) - 1) % 3);
+ } else {
+ $bytes = $bytes / pow(1024, $factor);
+ if ($decimals === -1) {
+ $decimals = 2 - floor(strlen((int)$bytes) - 1);
+ }
}
- return sprintf("%.{$decimals}f ", $bytes / pow(1024, $factor)) . $sz[$factor];
+ return sprintf("%.{$decimals}f", $bytes) . "\xe2\x80\x89" . $sz[$factor + $shift];
}
public static function sanitizeFilename($name)
@@ -484,7 +496,7 @@ SADFACE;
settype($ts, 'int');
if ($ts === 0)
return '???';
- static $TODAY = false, $ETODAY = false, $YESTERDAY = false, $YEAR = false;
+ static $TODAY = false, $ETODAY = false, $YESTERDAY = false, $YEARCUTOFF = false;
if (!$ETODAY) $ETODAY = strtotime('today 23:59:59');
if ($ts > $ETODAY) // TODO: Do we need strings for future too?
return date('d.m.Y H:i', $ts);
@@ -494,8 +506,8 @@ SADFACE;
if (!$YESTERDAY) $YESTERDAY = strtotime('yesterday 0:00');
if ($ts >= $YESTERDAY)
return Dictionary::translate('lang_yesterday') . ' ' . date('H:i', $ts);
- if (!$YEAR) $YEAR = strtotime('this year 1/1');
- if ($ts >= $YEAR)
+ if (!$YEARCUTOFF) $YEARCUTOFF = min(strtotime('-3 month'), strtotime('this year 1/1'));
+ if ($ts >= $YEARCUTOFF)
return date('d.m. H:i', $ts);
return date('d.m.Y', $ts);
}