- Refactoring

This commit is contained in:
Exodus4D
2017-06-05 20:55:58 +02:00
parent 77e0131efe
commit a3d89b9d77
20 changed files with 306 additions and 160 deletions

View File

@@ -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;
}

View File

@@ -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'] ));

View File

@@ -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();
}
}

View File

@@ -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');
}
}

View File

@@ -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') );
}
/**

View File

@@ -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);

View File

@@ -0,0 +1,17 @@
<?php
/**
* Created by PhpStorm.
* User: exodu
* Date: 05.06.2017
* Time: 19:19
*/
namespace Exception;
class PathfinderException extends BaseException{
public function __construct($message){
parent::__construct($message, self::CONFIGURATION_FAILED);
}
}

View File

@@ -33,21 +33,20 @@ class CcpClient extends \Prefab {
$client = new ApiClient($f3);
$client->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;

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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'

View File

@@ -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

49
js/app/admin.js Normal file
View File

@@ -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'
}
});
});
});

View File

@@ -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
};

View File

@@ -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}

View File

@@ -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

View File

@@ -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'
}
});
});
});

View File

@@ -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
};

View File

@@ -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}

View File

@@ -31,7 +31,7 @@
<meta name="keywords" content="eve,wormhole,mapping,tool,mmo,space,game">
<meta name="author" content="Exodus 4D">
<title>{{ @pageTitle}}</title>
<title>{{ @tplPageTitle}}</title>
<meta property="og:type" content="website" />
<meta property="og:title" content="{{ @PATHFINDER.NAME }}">
@@ -55,8 +55,8 @@
{* Resources *}
<set pathCSS="{{ @BASE . '/public/css/pathfinder.css?' . @PATHFINDER.VERSION }}" />
<set pathJSApp="{{ @BASE . '/' . @pathJs . '/app' }}" />
<set pathJSRequire="{{ @BASE . '/' . @pathJs . '/lib/require.js' }}" />
<set pathJSApp="{{ @BASE . '/' . @tplPathJs . '/app' }}" />
<set pathJSRequire="{{ @BASE . '/' . @tplPathJs . '/lib/require.js' }}" />
<link rel="stylesheet" type="text/css" media="screen" href="{{@pathCSS}}">
@@ -64,18 +64,18 @@
<link rel="preload" href="{{@pathCSS}}" as="style">
<link rel="preload" href="{{@pathJSRequire}}" as="script">
<link rel="preload" href="{{@pathJSApp}}.js" as="script">
<link rel="preload" href="{{@pathJSApp}}/{{@jsView}}.js" as="script">
<link rel="preload" href="{{@pathJSApp}}/{{@tplJsView}}.js" as="script">
<link rel="dns-prefetch" href="https://login.eveonline.com">
<link rel="dns-prefetch" href="https://image.eveonline.com">
<link rel="dns-prefetch" href="https://i.ytimg.com">
<check if="{{ @jsView != 'mappage' }}">
<check if="{{ @tplJsView != 'mappage' }}">
<link rel="prefetch" href="{{@pathJSApp}}/mappage.js" as="script">
</check>
</head>
<body class="{{ @bodyClass }}" data-js-path="{{ @BASE }}/{{ @pathJs }}" data-script="{{ @jsView }}" data-version="{{ @PATHFINDER.VERSION }}">
<include if="{{ @pageContent }}" href="{{ @pageContent }}"/>
<body class="pf-body {{ @tplBodyClass }}" data-js-path="{{ @BASE }}/{{ @tplPathJs }}" data-script="{{ @tplJsView }}" data-version="{{ @PATHFINDER.VERSION }}">
<include if="{{ @tplPageContent }}" href="{{ @tplPageContent }}"/>
<!-- Hey dude! Where is all the magic? -->