summaryrefslogtreecommitdiffstats
path: root/inc
diff options
context:
space:
mode:
authorSimon Rettberg2016-04-28 21:31:15 +0200
committerSimon Rettberg2016-04-28 21:31:15 +0200
commit95db8e184b378534db0ac08d14ae8500ee5090c3 (patch)
treef39cee8160ef4266e49dbe04d3e8fe6400ce2133 /inc
parentMerge branch 'master' into modularization (diff)
downloadslx-admin-95db8e184b378534db0ac08d14ae8500ee5090c3.tar.gz
slx-admin-95db8e184b378534db0ac08d14ae8500ee5090c3.tar.xz
slx-admin-95db8e184b378534db0ac08d14ae8500ee5090c3.zip
Implemented new menu, added logic for defining dependencies, move translation files around
Diffstat (limited to 'inc')
-rw-r--r--inc/dashboard.inc.php71
-rw-r--r--inc/dictionary.inc.php67
-rw-r--r--inc/message.inc.php4
-rw-r--r--inc/module.inc.php173
-rw-r--r--inc/render.inc.php56
5 files changed, 289 insertions, 82 deletions
diff --git a/inc/dashboard.inc.php b/inc/dashboard.inc.php
new file mode 100644
index 00000000..ef8be110
--- /dev/null
+++ b/inc/dashboard.inc.php
@@ -0,0 +1,71 @@
+<?php
+
+class Dashboard
+{
+
+ private static $iconCache = array();
+
+ public static function createMenu()
+ {
+ $modulesAssoc = array();
+ $all = Module::getEnabled();
+ foreach ($all as $module) {
+ $cat = $module->getCategory();
+ if ($cat === false)
+ continue;
+ $modulesAssoc[$cat][] = $module;
+ }
+ $modulesArray = array();
+ foreach ($modulesAssoc as $id => $list) {
+ $momomo = array();
+ foreach ($list as $module) {
+ $momomo[] = array(
+ 'displayName' => $module->getDisplayName(),
+ 'identifier' => $module->getIdentifier(),
+ 'className' => ($module->getIdentifier() === Page::getModule()->getIdentifier()) ? 'active' : ''
+ );
+ }
+ $modulesArray[] = array(
+ 'icon' => self::getCategoryIcon($id),
+ 'displayName' => Dictionary::getCategoryName($id),
+ 'modules' => $momomo
+ );
+ }
+ Render::setDashboard(array(
+ 'categories' => $modulesArray,
+ 'url' => urlencode($_SERVER['REQUEST_URI']),
+ 'langs' => Dictionary::getLanguages(true),
+ 'dbupdate' => Database::needSchemaUpdate(),
+ 'user' => User::getName(),
+ 'warning' => User::getName() !== false && User::getLastSeenEvent() < Property::getLastWarningId(),
+ 'needsSetup' => User::getName() !== false && Property::getNeedsSetup()
+ ));
+ }
+
+ public static function getCategoryIcon($category)
+ {
+ if ($category === false) {
+ return '';
+ }
+ if (!preg_match('/^(\w+)\.(\w+)$/', $category, $out)) {
+ error_log('Requested category icon for invalid category "' . $category . '"');
+ return '';
+ }
+ $module = $out[1];
+ $icon = $out[2];
+ if (!isset(self::$iconCache[$module])) {
+ $path = 'modules/' . $module . '/category-icons.json';
+ $data = json_decode(file_get_contents($path), true);
+ if (!is_array($data)) {
+ return '';
+ }
+ self::$iconCache[$module] =& $data;
+ }
+ if (!isset(self::$iconCache[$module][$icon])) {
+ error_log('Icon "' . $icon . '" not found in module "' . $module . '"');
+ return '';
+ }
+ return 'glyphicon glyphicon-' . self::$iconCache[$module][$icon];
+ }
+
+} \ No newline at end of file
diff --git a/inc/dictionary.inc.php b/inc/dictionary.inc.php
index ec4f4195..b56106cc 100644
--- a/inc/dictionary.inc.php
+++ b/inc/dictionary.inc.php
@@ -3,11 +3,9 @@
class Dictionary
{
- private static $messageArray = false;
private static $languages = false;
private static $languagesLong = false;
private static $stringCache = array();
- private static $hardcodedMessages = false;
public static function init()
{
@@ -51,57 +49,64 @@ class Dictionary
define('LANG', $language);
}
- public static function getArrayTemplate($template, $module = false, $lang = false)
+ public static function getArrayTemplate($template, $module, $lang = false)
{
- return self::getArray($module . "/" . $template, $lang);
+ return self::getArray($module, 'templates/' . $template, $lang);
}
- public static function getArray($module, $lang = false, $isMessage = false)
+ public static function getArray($module, $path, $lang = false)
{
if ($lang === false)
$lang = LANG;
- if(!$isMessage)
- $file = Util::safePath("lang/" . $lang . "/modules/" . $module . ".json");
- else
- $file = Util::safePath("lang/" . $lang . "/" . $module . ".json");
-
+ $file = Util::safePath("modules/{$module}/lang/{$lang}/{$path}.json");
if (isset(self::$stringCache[$file]))
return self::$stringCache[$file];
$content = @file_get_contents($file);
- if ($content === false) {// File does not exist for language {
- return array();
+ if ($content === false) { // File does not exist for language
+ $content = '[]';
+ error_log("getArray called for non-existent $file");
}
$json = json_decode($content, true);
- if (!is_array($json))
- return array();
+ if (!is_array($json)) {
+ $json = array();
+ }
return self::$stringCache[$file] = $json;
}
- public static function translate($section, $string = false)
+ public static function translate($module, $path, $string)
{
- if ($string === false) {
- // Fallback: General "hardcoded" messages
- $string = $section;
- if (self::$hardcodedMessages === false)
- self::$hardcodedMessages = json_decode(file_get_contents("lang/" . LANG . "/messages-hardcoded.json"), true);
- if (!isset(self::$hardcodedMessages[$string]))
- return "(missing: $string :missing)";
- return self::$hardcodedMessages[$string];
- }
- $strings = self::getArray($section, false, true);
+ $strings = self::getArray($module, $path);
if (!isset($strings[$string])) {
- return "(missing: '$string' in '$section')";
+ return false;
}
return $strings[$string];
}
public static function getMessage($id)
{
- if (self::$messageArray === false)
- self::$messageArray = json_decode(file_get_contents("lang/" . LANG . "/messages.json"), true);
- if (!isset(self::$messageArray[$id]))
- return "(missing: $id :missing)";
- return self::$messageArray[$id];
+ if (!preg_match('/^(\w+)\.(\w+)$/', id, $out)) {
+ return 'Invalid Message ID format: ' . $id;
+ }
+ $string = self::translate($out[1], 'messages', $out[2]);
+ if ($string === false) {
+ return $id;
+ }
+ return $string;
+ }
+
+ public static function getCategoryName($category)
+ {
+ if ($category === false) {
+ return 'No Category';
+ }
+ if (!preg_match('/^(\w+)\.(\w+)$/', $category, $out)) {
+ return 'Invalid Category ID format: ' . $category;
+ }
+ $string = self::translate($out[1], 'categories', $out[2]);
+ if ($string === false) {
+ return $category;
+ }
+ return $string;
}
/**
diff --git a/inc/message.inc.php b/inc/message.inc.php
index d2fd74b9..96fb94c5 100644
--- a/inc/message.inc.php
+++ b/inc/message.inc.php
@@ -52,6 +52,8 @@ class Message
*/
public static function renderList()
{
+ if (empty(self::$list))
+ return;
// Ajax
if (AJAX) {
foreach (self::$list as $item) {
@@ -65,7 +67,6 @@ class Message
return;
}
// Non-Ajax
- if (!self::$flushed) Render::openTag('div', array('class' => 'container'));
foreach (self::$list as $item) {
$message = Dictionary::getMessage($item['id']);
foreach ($item['params'] as $index => $text) {
@@ -74,7 +75,6 @@ class Message
Render::addTemplate('messagebox-' . $item['type'], array('message' => $message),'main');
self::$alreadyDisplayed[] = $item;
}
- if (!self::$flushed) Render::closeTag('div');
self::$list = array();
self::$flushed = true;
}
diff --git a/inc/module.inc.php b/inc/module.inc.php
new file mode 100644
index 00000000..9126cb32
--- /dev/null
+++ b/inc/module.inc.php
@@ -0,0 +1,173 @@
+<?php
+
+class Module
+{
+ /*
+ * Static
+ */
+
+ /**
+ * @var \Module[]
+ */
+ private static $modules = false;
+
+ public static function get($name)
+ {
+ if (!isset(self::$modules[$name]))
+ return false;
+ if (!self::resolveDeps(self::$modules[$name]))
+ return false;
+ return self::$modules[$name];
+ }
+
+ private static function resolveDepsByName($name)
+ {
+ if (!isset(self::$modules[$name]))
+ return false;
+ return self::resolveDeps(self::$modules[$name]);
+ }
+
+ private static function resolveDeps($mod)
+ {
+ if (!$mod->depsChecked) {
+ $mod->depsChecked = true;
+ foreach ($mod->dependencies as $dep) {
+ if (!self::resolveDepsByName($dep)) {
+ if ($mod->enabled) {
+ error_log("Disabling module $name: Dependency $dep failed.");
+ }
+ $mod->enabled = false;
+ $mod->depsMissing = true;
+ return false;
+ }
+ }
+ }
+ return $mod->enabled;
+ }
+
+ /**
+ * @return \Module[] List of enabled modules
+ */
+ public static function getEnabled()
+ {
+ $ret = array();
+ foreach (self::$modules as $module) {
+ if (self::resolveDeps($module))
+ $ret[] = $module;
+ }
+ return $ret;
+ }
+
+ public static function init()
+ {
+ if (self::$modules !== false)
+ return;
+ $dh = opendir('modules');
+ if ($dh === false)
+ return;
+ self::$modules = array();
+ while (($dir = readdir($dh)) !== false) {
+ if (empty($dir) || preg_match('/[^a-zA-Z0-9]/', $dir))
+ continue;
+ if (!is_file('modules/' . $dir . '/config.json'))
+ continue;
+ $name = strtolower($dir);
+ self::$modules[$name] = new Module($dir);
+ }
+ closedir($dh);
+ }
+
+ /*
+ * Non-static
+ */
+
+ private $enabled = false;
+ private $category = false;
+ private $depsMissing = false;
+ private $depsChecked = false;
+ private $activated = false;
+ private $dependencies = array();
+ private $name;
+
+ private function __construct($name)
+ {
+ $file = 'modules/' . $name . '/config.json';
+ $json = @json_decode(@file_get_contents($file), true);
+ $this->enabled = isset($json['enabled']) && ($json['enabled'] === true || $json['enabled'] === 'true');
+ if (isset($json['dependencies']) && is_array($json['dependencies'])) {
+ $this->dependencies = $json['dependencies'];
+ }
+ if (isset($json['category']) && is_string($json['category'])) {
+ $this->category = $json['category'];
+ }
+ $this->name = $name;
+ }
+
+ public function newPage()
+ {
+ $modulePath = 'modules/' . $this->name . '/page.inc.php';
+ if (!file_exists($modulePath)) {
+ Util::traceError("Module doesn't have a page: " . $modulePath);
+ }
+ require_once $modulePath;
+ $class = 'Page_' . $this->name;
+ return new $class();
+ }
+
+ public function activate()
+ {
+ if ($this->activated || !$this->enabled)
+ return;
+ $this->activated = true;
+ 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;
+ });
+ foreach ($this->dependencies as $dep) {
+ $get = self::get($dep);
+ if ($get !== false) {
+ $get->activate();
+ }
+ }
+ }
+
+ public function getIdentifier()
+ {
+ return $this->name;
+ }
+
+ public function getDisplayName()
+ {
+ $string = Dictionary::translate($this->name, 'module', 'module_name');
+ if ($string === false) {
+ return $this->name;
+ }
+ return $string;
+ }
+
+ public function getCategory()
+ {
+ return $this->category;
+ }
+
+ public function getCategoryName()
+ {
+ return Dictionary::getCategoryName($this->category);
+ }
+
+ public function translate($tag, $section = 'module')
+ {
+ $string = Dictionary::translate($this->name, $section, $tag);
+ if ($string === false) {
+ $string = Dictionary::translate('core', $section, $tag);
+ }
+ if ($string === false) {
+ error_log('Translation not found. Module: ' . $this->name . ', section: ' . $section . ', tag: ' . $tag);
+ $string = '!!' . $tag . '!!';
+ }
+ return $string;
+ }
+
+}
diff --git a/inc/render.inc.php b/inc/render.inc.php
index 10d18514..14d5a810 100644
--- a/inc/render.inc.php
+++ b/inc/render.inc.php
@@ -41,22 +41,19 @@ class Render
if ($zip)
ob_start();
$page = strtolower($_GET['do']);
- if(User::isLoggedIn())
- self::createDashboard($page);
echo
'<!DOCTYPE html>
<html>
<head>
<title>', RENDER_DEFAULT_TITLE, self::$title, '</title>
<meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Bootstrap -->
<link href="style/bootstrap.min.css" rel="stylesheet" media="screen">
<link href="style/bootstrap-tagsinput.css" rel="stylesheet" media="screen">
<link href="style/default.css" rel="stylesheet" media="screen">
- <link href="style/bootstrap-switch.css" rel="stylesheet" media="screen">
- <script src="script/bootstrap-switch.js"></script>
<script type="text/javascript">
var TOKEN = "' . Session::get('token') . '";
</script>
@@ -65,15 +62,13 @@ class Render
,
' </head>
<body>
- <div class="container-fluid" id="mainpage">
- <div class="row">
',
- self::$dashboard
- ,
+ self::$dashboard,
+ '<div class="main" id="mainpage"><div class="container-fluid">
+ ',
self::$body
,
- ' </div>
- </div>
+ '</div></div>
<script src="script/jquery.js"></script>
<script src="script/bootstrap.min.js"></script>
<script src="script/taskmanager.js"></script>
@@ -259,46 +254,9 @@ class Render
/**
* Create the dashboard menu
*/
- private static function createDashboard($page)
+ public static function setDashboard($params)
{
- // Check all required modules
- $requiredModules = array('adduser','main','session','translation','usermanagement');
- $notFound = '';
- foreach ($requiredModules as $module) {
- if(!is_dir('modules/' . $module . '/')){
- $notFound .= '\'' . $module . '\' ';
- }
- }
- if(strlen($notFound) > 0){
- Util::traceError('At least one required module was not found: ' . $notFound);
- }else{
- $modules = array_diff(scandir('modules/'), array('..', '.'));
- $categories = array();
- foreach ($modules as $module) {
- $json = json_decode(file_get_contents("modules/" . $module . "/config.json"),true);
- $categories[$json['category']][] = $module;
- }
- unset($categories['hidden']);
- self::$dashboard = '<div class="col-sm-3 col-md-2 sidebar">';
- foreach ($categories as $cat => $modules) {
- self::$dashboard .= '<div class="dash-header"></span> <span class="glyphicon glyphicon-' . self::getGlyphicon($cat)
- . '" aria-hidden="true"></span> ' . Dictionary::translate('lang_' . $cat) . '</div>';
- self::$dashboard .= '<ul class="nav nav-sidebar">';
- foreach ($modules as $module) {
- self::$dashboard .= '<li class="' . (($page == $module) ? 'active' : '')
- . '"><a href="?do=' . ucfirst($module) . '"> ' . (Dictionary::translate('lang_' . $module)) . '</a></li>';
- }
- self::$dashboard .= '</ul>';
- }
- self::$dashboard .= '</div> <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">';
- }
- }
-
- /**
- * get categories glyph icons
- */
- private static function getGlyphicon($category){
- return json_decode(file_get_contents("style/categories.json"),true)[$category];
+ self::$dashboard = self::parse('main-menu', $params, 'main');
}
}