diff options
author | Simon Rettberg | 2016-04-28 21:31:15 +0200 |
---|---|---|
committer | Simon Rettberg | 2016-04-28 21:31:15 +0200 |
commit | 95db8e184b378534db0ac08d14ae8500ee5090c3 (patch) | |
tree | f39cee8160ef4266e49dbe04d3e8fe6400ce2133 /inc | |
parent | Merge branch 'master' into modularization (diff) | |
download | slx-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.php | 71 | ||||
-rw-r--r-- | inc/dictionary.inc.php | 67 | ||||
-rw-r--r-- | inc/message.inc.php | 4 | ||||
-rw-r--r-- | inc/module.inc.php | 173 | ||||
-rw-r--r-- | inc/render.inc.php | 56 |
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'); } } |