diff --git a/app/main/controller/admin.php b/app/main/controller/admin.php index 3e911609..3a89188f 100644 --- a/app/main/controller/admin.php +++ b/app/main/controller/admin.php @@ -12,6 +12,7 @@ namespace Controller; use Controller\Ccp\Sso; use Model\CharacterModel; use Model\CorporationModel; +use lib\Config; class Admin extends Controller{ @@ -45,16 +46,13 @@ class Admin extends Controller{ $f3->set('tplAuthType', $f3->alias( 'sso', ['action' => 'requestAdminAuthorization'])); // page title - $f3->set('pageTitle', 'Admin'); + $f3->set('tplPageTitle', 'Admin | ' . Config::getPathfinderData('name')); // main page content - $f3->set('pageContent', $f3->get('PATHFINDER.VIEW.ADMIN')); + $f3->set('tplPageContent', Config::getPathfinderData('view.admin')); // body element class - $f3->set('bodyClass', 'pf-body pf-landing'); - - // js path (build/minified or raw uncompressed files) - $f3->set('pathJs', 'public/js/' . $f3->get('PATHFINDER.VERSION') ); + $f3->set('tplBodyClass', 'pf-landing'); } /** @@ -63,10 +61,10 @@ class Admin extends Controller{ */ public function afterroute(\Base $f3) { // js view (file) - $f3->set('jsView', 'login'); + $f3->set('tplJsView', 'admin'); // render view - echo \Template::instance()->render( $f3->get('PATHFINDER.VIEW.INDEX') ); + echo \Template::instance()->render( Config::getPathfinderData('view.index') ); // clear all SSO related temp data if( $f3->exists(Sso::SESSION_KEY_SSO) ){ @@ -236,14 +234,20 @@ class Admin extends Controller{ * -> must be in same corporation * @param CharacterModel $character * @param int $characterId - * @return array|CharacterModel[] + * @return array|\DB\CortexCollection */ protected function filterValidCharacters(CharacterModel $character, $characterId){ $characters = []; // check if kickCharacters belong to same Corp as admin character // -> remove admin char from valid characters... if( !empty($characterIds = array_diff( [$characterId], [$character->_id])) ){ - $characters = $character->getCorporation()->getCharacters($characterIds); + if($character->role === 'SUPERADMIN'){ + if($filterCharacters = CharacterModel::getAll($characterIds)){ + $characters = $filterCharacters; + } + }else{ + $characters = $character->getCorporation()->getCharacters($characterIds); + } } return $characters; } diff --git a/app/main/controller/appcontroller.php b/app/main/controller/appcontroller.php index c354a9a5..85777142 100644 --- a/app/main/controller/appcontroller.php +++ b/app/main/controller/appcontroller.php @@ -7,8 +7,9 @@ */ namespace Controller; + use Controller\Ccp as Ccp; -use Model; +use lib\Config; class AppController extends Controller { @@ -31,16 +32,16 @@ class AppController extends Controller { */ public function init(\Base $f3) { // page title - $f3->set('pageTitle', 'Pathfinder'); + $f3->set('tplPageTitle', Config::getPathfinderData('name')); // main page content - $f3->set('pageContent', $f3->get('PATHFINDER.VIEW.LOGIN')); + $f3->set('tplPageContent', Config::getPathfinderData('view.login')); // body element class - $f3->set('bodyClass', 'pf-body pf-landing'); + $f3->set('tplBodyClass', 'pf-landing'); // JS main file - $f3->set('jsView', 'login'); + $f3->set('tplJsView', 'login'); // href for SSO Auth $f3->set('tplAuthType', $f3->alias( 'sso', ['action' => 'requestAuthorization'] )); diff --git a/app/main/controller/controller.php b/app/main/controller/controller.php index 95e02293..3f9d4674 100644 --- a/app/main/controller/controller.php +++ b/app/main/controller/controller.php @@ -82,11 +82,10 @@ class Controller { $this->initSession(); if( !$f3->get('AJAX') ){ - // js path (build/minified or raw uncompressed files) - $f3->set('pathJs', 'public/js/' . $f3->get('PATHFINDER.VERSION') ); + $f3->set('tplPathJs', 'public/js/' . Config::getPathfinderData('version') ); - $this->setTemplate( $f3->get('PATHFINDER.VIEW.INDEX') ); + $this->setTemplate( Config::getPathfinderData('view.index') ); } } @@ -568,9 +567,9 @@ class Controller { */ protected function getUserAgent(){ $userAgent = ''; - $userAgent .= $this->getF3()->get('PATHFINDER.NAME'); - $userAgent .= ' - ' . $this->getF3()->get('PATHFINDER.VERSION'); - $userAgent .= ' | ' . $this->getF3()->get('PATHFINDER.CONTACT'); + $userAgent .= Config::getPathfinderData('name'); + $userAgent .= ' - ' . Config::getPathfinderData('version'); + $userAgent .= ' | ' . Config::getPathfinderData('contact'); $userAgent .= ' (' . $_SERVER['SERVER_NAME'] . ')'; return $userAgent; @@ -619,19 +618,19 @@ class Controller { echo json_encode($return); die(); }else{ - $f3->set('pageTitle', 'ERROR - ' . $error->code); + $f3->set('tplPageTitle', 'ERROR - ' . $error->code . ' | Pathfinder'); // set error data for template rendering $error->redirectUrl = $this->getRouteUrl(); $f3->set('errorData', $error); if( preg_match('/^4[0-9]{2}$/', $error->code) ){ // 4xx error -> render error page - $f3->set('pageContent', $f3->get('PATHFINDER.STATUS.4XX')); + $f3->set('tplPageContent', Config::getPathfinderData('STATUS.4XX') ); }elseif( preg_match('/^5[0-9]{2}$/', $error->code) ){ - $f3->set('pageContent', $f3->get('PATHFINDER.STATUS.5XX')); + $f3->set('tplPageContent', Config::getPathfinderData('STATUS.5XX')); } - echo \Template::instance()->render( $f3->get('PATHFINDER.VIEW.INDEX') ); + echo \Template::instance()->render( Config::getPathfinderData('view.index') ); die(); } } diff --git a/app/main/controller/mapcontroller.php b/app/main/controller/mapcontroller.php index c5a103f2..947a866e 100644 --- a/app/main/controller/mapcontroller.php +++ b/app/main/controller/mapcontroller.php @@ -8,6 +8,9 @@ namespace Controller; +use lib\Config; + + class MapController extends AccessController { /** @@ -17,17 +20,13 @@ class MapController extends AccessController { $character = $this->getCharacter(); // page title - $pageTitle = $character ? $character->name : 'Map'; - $f3->set('pageTitle', $pageTitle); + $f3->set('tplPageTitle', $character->name . ' | ' . Config::getPathfinderData('name')); // main page content - $f3->set('pageContent', false); - - // body element class - $f3->set('bodyClass', 'pf-body'); + $f3->set('tplPageContent', false); // JS main file - $f3->set('jsView', 'mappage'); + $f3->set('tplJsView', 'mappage'); } } \ No newline at end of file diff --git a/app/main/controller/setup.php b/app/main/controller/setup.php index 4eee0fdf..1170dfb2 100644 --- a/app/main/controller/setup.php +++ b/app/main/controller/setup.php @@ -125,21 +125,21 @@ class Setup extends Controller { */ function beforeroute(\Base $f3, $params) { // page title - $f3->set('pageTitle', 'Setup'); + $f3->set('tplPageTitle', 'Setup | ' . Config::getPathfinderData('name')); // main page content - $f3->set('pageContent', $f3->get('PATHFINDER.VIEW.SETUP')); + $f3->set('tplPageContent', Config::getPathfinderData('view.setup')); // body element class - $f3->set('bodyClass', 'pf-body pf-landing'); + $f3->set('tplBodyClass', 'pf-landing'); // js path (build/minified or raw uncompressed files) - $f3->set('pathJs', 'public/js/' . $f3->get('PATHFINDER.VERSION') ); + $f3->set('tplPathJs', 'public/js/' . Config::getPathfinderData('version') ); } public function afterroute(\Base $f3) { // js view (file) - $f3->set('jsView', 'setup'); + $f3->set('tplJsView', 'setup'); // set render functions (called within template) $f3->set('cacheType', function(){ @@ -151,7 +151,7 @@ class Setup extends Controller { }); // render view - echo \Template::instance()->render( $f3->get('PATHFINDER.VIEW.INDEX') ); + echo \Template::instance()->render( Config::getPathfinderData('view.index') ); } /** diff --git a/app/main/exception/baseexception.php b/app/main/exception/baseexception.php index 5d590dc6..9262e4c4 100644 --- a/app/main/exception/baseexception.php +++ b/app/main/exception/baseexception.php @@ -13,6 +13,7 @@ class BaseException extends \Exception { const VALIDATION_FAILED = 403; const REGISTRATION_FAILED = 403; + const CONFIGURATION_FAILED = 500; public function __construct($message, $code = 0){ parent::__construct($message, $code); diff --git a/app/main/exception/pathfinderexception.php b/app/main/exception/pathfinderexception.php new file mode 100644 index 00000000..7edfc358 --- /dev/null +++ b/app/main/exception/pathfinderexception.php @@ -0,0 +1,17 @@ +setUrl( Config::getEnvironmentData('CCP_ESI_URL') ); $client->setDatasource( Config::getEnvironmentData('CCP_ESI_DATASOURCE') ); - $client->setUserAgent($this->getUserAgent($f3)); + $client->setUserAgent($this->getUserAgent()); } return $client; } /** - * @param \Base $f3 * @return string */ - protected function getUserAgent($f3){ + protected function getUserAgent(){ $userAgent = ''; - $userAgent .= $f3->get('PATHFINDER.NAME'); - $userAgent .= ' - ' . $f3->get('PATHFINDER.VERSION'); - $userAgent .= ' | ' . $f3->get('PATHFINDER.CONTACT'); + $userAgent .= Config::getPathfinderData('name'); + $userAgent .= ' - ' . Config::getPathfinderData('version'); + $userAgent .= ' | ' . Config::getPathfinderData('contact'); $userAgent .= ' (' . $_SERVER['SERVER_NAME'] . ')'; return $userAgent; diff --git a/app/main/lib/config.php b/app/main/lib/config.php index 00b84e9e..7d037e68 100644 --- a/app/main/lib/config.php +++ b/app/main/lib/config.php @@ -9,6 +9,8 @@ namespace lib; +use Exception; + class Config extends \Prefab { const PREFIX_KEY = 'PF'; @@ -16,6 +18,9 @@ class Config extends \Prefab { const HIVE_KEY_PATHFINDER = 'PATHFINDER'; const HIVE_KEY_ENVIRONMENT = 'ENVIRONMENT'; + const ERROR_CONF_PATHFINDER = 'Config value missing in pathfinder.ini file [%s]'; + + /** * environment config keys that should be parsed as array * -> use "," as delimiter in config files/data @@ -163,17 +168,10 @@ class Config extends \Prefab { /** * get email for notifications by hive key * @param $key - * @return bool|mixed + * @return mixed */ static function getNotificationMail($key){ - $f3 = \Base::instance(); - $hiveKey = self::HIVE_KEY_PATHFINDER . '.NOTIFICATION.' . $key; - $mail = false; - if( $f3->exists($hiveKey, $cachedMail) ){ - $mail = $cachedMail; - } - - return $mail; + return self::getPathfinderData('notification' . ($key ? '.' . $key : '')); } /** @@ -183,12 +181,11 @@ class Config extends \Prefab { * @return array */ static function getMapsDefaultConfig($mapType = ''){ - $f3 = \Base::instance(); - $hiveKey = 'PATHFINDER.MAP'; - if( !empty($mapType) ){ - $hiveKey .= '.' . strtoupper($mapType); + if( $mapConfig = self::getPathfinderData('map' . ($mapType ? '.' . $mapType : '')) ){ + $mapConfig = Util::arrayChangeKeyCaseRecursive( $mapConfig ); } - return Util::arrayChangeKeyCaseRecursive( $f3->get($hiveKey) ); + + return $mapConfig; } /** @@ -208,5 +205,20 @@ class Config extends \Prefab { return $uri; } + /** + * get PATHFINDER config data + * @param string $key + * @return mixed + * @throws Exception\PathfinderException + */ + static function getPathfinderData($key = ''){ + $hiveKey = self::HIVE_KEY_PATHFINDER . ($key ? '.' . strtoupper($key) : ''); + + if( !\Base::instance()->exists($hiveKey, $data) ){ + throw new Exception\PathfinderException(sprintf(self::ERROR_CONF_PATHFINDER, $hiveKey)); + } + + return $data; + } } \ No newline at end of file diff --git a/app/main/model/charactermodel.php b/app/main/model/charactermodel.php index 71c98788..a72e8950 100644 --- a/app/main/model/charactermodel.php +++ b/app/main/model/charactermodel.php @@ -924,7 +924,7 @@ class CharacterModel extends BasicModel { * @param array $characterDataBase * @return array */ - static function mergeSessionCharacterData(array $characterDataBase = []){ + public static function mergeSessionCharacterData(array $characterDataBase = []){ $addData = []; // get current session characters to be merged with $characterData = (array)self::getF3()->get(User::SESSION_KEY_CHARACTERS); @@ -944,4 +944,13 @@ class CharacterModel extends BasicModel { return array_merge($characterDataBase, $addData); } + public static function getAll($characterIds = []){ + $query = [ + 'active = :active AND id IN :characterIds', + ':active' => 1, + ':characterIds' => $characterIds + ]; + + return (new self())->find($query); + } } \ No newline at end of file diff --git a/build.js b/build.js index 60083194..1b9a9dca 100644 --- a/build.js +++ b/build.js @@ -6,13 +6,13 @@ //then all the files from the app directory will be copied to the dir: //output area, and baseUrl will assume to be a relative path under //this directory. - appDir: "./js", + appDir: './js', //By default, all modules are located relative to this path. If baseUrl //is not explicitly set, then all modules are loaded relative to //the directory that holds the build file. If appDir is set, then //baseUrl should be specified as relative to the appDir. - baseUrl: "./", + baseUrl: './', //By default all the configuration for optimization happens from the command //line or by properties in the config file, and configuration that was @@ -92,6 +92,11 @@ excludeShallow: [ 'app' ] + },{ + name: 'admin', + excludeShallow: [ + 'app' + ] },{ name: 'app/notification', excludeShallow: [ @@ -196,13 +201,13 @@ }, paths: { - app: "./../js/app" // the main config file will not be build + app: './../js/app' // the main config file will not be build }, //The directory path to save the output. If not specified, then //the path will default to be a directory called "build" as a sibling //to the build file. All relative paths are relative to the build file. - dir: "./build_js" + dir: './build_js' diff --git a/js/app.js b/js/app.js index 16a8e40c..3bd05f73 100644 --- a/js/app.js +++ b/js/app.js @@ -20,6 +20,7 @@ requirejs.config({ login: './app/login', // initial start "login page" view mappage: './app/mappage', // initial start "map page" view setup: './app/setup', // initial start "setup page" view + admin: './app/admin', // initial start "admin page" view jquery: 'lib/jquery-3.1.1.min', // v3.1.1 jQuery bootstrap: 'lib/bootstrap.min', // v3.3.0 Bootstrap js code - http://getbootstrap.com/javascript diff --git a/js/app/admin.js b/js/app/admin.js new file mode 100644 index 00000000..aecb732a --- /dev/null +++ b/js/app/admin.js @@ -0,0 +1,49 @@ +/** + * Main "admin" page + */ + +define([ + 'jquery', + 'app/init', + 'app/util', + 'datatables.net', + 'datatables.net-buttons', + 'datatables.net-buttons-html', + 'datatables.net-responsive', + 'datatables.net-select' +], function($, Init, Util) { + + 'use strict'; + + let config = { + splashOverlayClass: 'pf-splash' // class for "splash" overlay + }; + + /** + * main init "admin" page + */ + $(function(){ + // set Dialog default config + Util.initDefaultBootboxConfig(); + + // hide splash loading animation + $('.' + config.splashOverlayClass).hideSplashOverlay(); + + + let systemsDataTable = $('.dataTable').dataTable( { + pageLength: 100, + paging: true, + ordering: true, + autoWidth: false, + hover: false, + language: { + emptyTable: 'No members', + zeroRecords: 'No members found', + lengthMenu: 'Show _MENU_ members', + info: 'Showing _START_ to _END_ of _TOTAL_ members' + } + }); + + + }); +}); \ No newline at end of file diff --git a/js/app/page.js b/js/app/page.js index c8d461e8..5da37739 100644 --- a/js/app/page.js +++ b/js/app/page.js @@ -23,6 +23,7 @@ define([ 'dialog/jump_info', 'dialog/delete_account', 'dialog/credit', + 'xEditable', 'slidebars', 'app/module_map' ], function($, Init, Util, Logging, Mustache, MapUtil, TplLogo, TplHead, TplFooter) { @@ -1166,6 +1167,50 @@ define([ return body; }; + /** + * get all form Values as object + * this includes all xEditable fields + * @returns {{}} + */ + $.fn.getFormValues = function(){ + let form = $(this); + let formData = {}; + let values = form.serializeArray(); + + // add "unchecked" checkboxes as well + values = values.concat( + form.find('input[type=checkbox]:not(:checked)').map( + function() { + return {name: this.name, value: 0}; + }).get() + ); + + for(let field of values){ + // check for numeric values -> convert to Int + let value = ( /^\d+$/.test(field.value) ) ? parseInt(field.value) : field.value; + + if(field.name.indexOf('[]') !== -1){ + // array field + let key = field.name.replace('[]', ''); + if( !$.isArray(formData[key]) ){ + formData[key] = []; + } + + formData[key].push( value); + }else{ + formData[field.name] = value; + } + } + + // get xEditable values + let editableValues = form.find('.' + Util.config.formEditableFieldClass).editable('getValue'); + + // merge values + formData = $.extend(formData, editableValues); + + return formData; + }; + return { initTabChangeObserver: initTabChangeObserver }; diff --git a/js/app/util.js b/js/app/util.js index 15b3e754..7d45e67d 100644 --- a/js/app/util.js +++ b/js/app/util.js @@ -12,7 +12,6 @@ define([ 'velocityUI', 'customScrollbar', 'validator', - 'xEditable', 'easyPieChart', 'hoverIntent', 'bootstrapConfirmation', @@ -397,50 +396,6 @@ define([ return valid; }; - /** - * get all form Values as object - * this includes all xEditable fields - * @returns {{}} - */ - $.fn.getFormValues = function(){ - let form = $(this); - let formData = {}; - let values = form.serializeArray(); - - // add "unchecked" checkboxes as well - values = values.concat( - form.find('input[type=checkbox]:not(:checked)').map( - function() { - return {name: this.name, value: 0}; - }).get() - ); - - for(let field of values){ - // check for numeric values -> convert to Int - let value = ( /^\d+$/.test(field.value) ) ? parseInt(field.value) : field.value; - - if(field.name.indexOf('[]') !== -1){ - // array field - let key = field.name.replace('[]', ''); - if( !$.isArray(formData[key]) ){ - formData[key] = []; - } - - formData[key].push( value); - }else{ - formData[field.name] = value; - } - } - - // get xEditable values - let editableValues = form.find('.' + config.formEditableFieldClass).editable('getValue'); - - // merge values - formData = $.extend(formData, editableValues); - - return formData; - }; - /** * check multiple element if they arecurrently visible in viewport * @returns {Array} diff --git a/public/js/v1.2.3/app.js b/public/js/v1.2.3/app.js index 16a8e40c..3bd05f73 100644 --- a/public/js/v1.2.3/app.js +++ b/public/js/v1.2.3/app.js @@ -20,6 +20,7 @@ requirejs.config({ login: './app/login', // initial start "login page" view mappage: './app/mappage', // initial start "map page" view setup: './app/setup', // initial start "setup page" view + admin: './app/admin', // initial start "admin page" view jquery: 'lib/jquery-3.1.1.min', // v3.1.1 jQuery bootstrap: 'lib/bootstrap.min', // v3.3.0 Bootstrap js code - http://getbootstrap.com/javascript diff --git a/public/js/v1.2.3/app/admin.js b/public/js/v1.2.3/app/admin.js new file mode 100644 index 00000000..aecb732a --- /dev/null +++ b/public/js/v1.2.3/app/admin.js @@ -0,0 +1,49 @@ +/** + * Main "admin" page + */ + +define([ + 'jquery', + 'app/init', + 'app/util', + 'datatables.net', + 'datatables.net-buttons', + 'datatables.net-buttons-html', + 'datatables.net-responsive', + 'datatables.net-select' +], function($, Init, Util) { + + 'use strict'; + + let config = { + splashOverlayClass: 'pf-splash' // class for "splash" overlay + }; + + /** + * main init "admin" page + */ + $(function(){ + // set Dialog default config + Util.initDefaultBootboxConfig(); + + // hide splash loading animation + $('.' + config.splashOverlayClass).hideSplashOverlay(); + + + let systemsDataTable = $('.dataTable').dataTable( { + pageLength: 100, + paging: true, + ordering: true, + autoWidth: false, + hover: false, + language: { + emptyTable: 'No members', + zeroRecords: 'No members found', + lengthMenu: 'Show _MENU_ members', + info: 'Showing _START_ to _END_ of _TOTAL_ members' + } + }); + + + }); +}); \ No newline at end of file diff --git a/public/js/v1.2.3/app/page.js b/public/js/v1.2.3/app/page.js index c8d461e8..5da37739 100644 --- a/public/js/v1.2.3/app/page.js +++ b/public/js/v1.2.3/app/page.js @@ -23,6 +23,7 @@ define([ 'dialog/jump_info', 'dialog/delete_account', 'dialog/credit', + 'xEditable', 'slidebars', 'app/module_map' ], function($, Init, Util, Logging, Mustache, MapUtil, TplLogo, TplHead, TplFooter) { @@ -1166,6 +1167,50 @@ define([ return body; }; + /** + * get all form Values as object + * this includes all xEditable fields + * @returns {{}} + */ + $.fn.getFormValues = function(){ + let form = $(this); + let formData = {}; + let values = form.serializeArray(); + + // add "unchecked" checkboxes as well + values = values.concat( + form.find('input[type=checkbox]:not(:checked)').map( + function() { + return {name: this.name, value: 0}; + }).get() + ); + + for(let field of values){ + // check for numeric values -> convert to Int + let value = ( /^\d+$/.test(field.value) ) ? parseInt(field.value) : field.value; + + if(field.name.indexOf('[]') !== -1){ + // array field + let key = field.name.replace('[]', ''); + if( !$.isArray(formData[key]) ){ + formData[key] = []; + } + + formData[key].push( value); + }else{ + formData[field.name] = value; + } + } + + // get xEditable values + let editableValues = form.find('.' + Util.config.formEditableFieldClass).editable('getValue'); + + // merge values + formData = $.extend(formData, editableValues); + + return formData; + }; + return { initTabChangeObserver: initTabChangeObserver }; diff --git a/public/js/v1.2.3/app/util.js b/public/js/v1.2.3/app/util.js index 15b3e754..7d45e67d 100644 --- a/public/js/v1.2.3/app/util.js +++ b/public/js/v1.2.3/app/util.js @@ -12,7 +12,6 @@ define([ 'velocityUI', 'customScrollbar', 'validator', - 'xEditable', 'easyPieChart', 'hoverIntent', 'bootstrapConfirmation', @@ -397,50 +396,6 @@ define([ return valid; }; - /** - * get all form Values as object - * this includes all xEditable fields - * @returns {{}} - */ - $.fn.getFormValues = function(){ - let form = $(this); - let formData = {}; - let values = form.serializeArray(); - - // add "unchecked" checkboxes as well - values = values.concat( - form.find('input[type=checkbox]:not(:checked)').map( - function() { - return {name: this.name, value: 0}; - }).get() - ); - - for(let field of values){ - // check for numeric values -> convert to Int - let value = ( /^\d+$/.test(field.value) ) ? parseInt(field.value) : field.value; - - if(field.name.indexOf('[]') !== -1){ - // array field - let key = field.name.replace('[]', ''); - if( !$.isArray(formData[key]) ){ - formData[key] = []; - } - - formData[key].push( value); - }else{ - formData[field.name] = value; - } - } - - // get xEditable values - let editableValues = form.find('.' + config.formEditableFieldClass).editable('getValue'); - - // merge values - formData = $.extend(formData, editableValues); - - return formData; - }; - /** * check multiple element if they arecurrently visible in viewport * @returns {Array} diff --git a/public/templates/view/index.html b/public/templates/view/index.html index 84f4233d..3378ec78 100644 --- a/public/templates/view/index.html +++ b/public/templates/view/index.html @@ -31,7 +31,7 @@ - {{ @pageTitle}} + {{ @tplPageTitle}} @@ -55,8 +55,8 @@ {* Resources *} - - + + @@ -64,18 +64,18 @@ - + - + - - + +