substates for the statesystem, many optimizations
This commit is contained in:
parent
8ff0efe6ba
commit
b3414fc398
@ -7,11 +7,11 @@ class SYS_PAGE_GROUP extends \SYSTEM\DB\QP {
|
||||
//pg
|
||||
'SELECT * FROM '.\SYSTEM\DBD\system_page::NAME_PG
|
||||
.' WHERE "'.\SYSTEM\DBD\system_page::FIELD_GROUP.'" = $1'
|
||||
.' AND "'.\SYSTEM\DBD\system_page::FIELD_ID.'" = $2'
|
||||
.' ORDER BY "'.\SYSTEM\DBD\system_page::FIELD_ID.'"',
|
||||
.' AND "'.\SYSTEM\DBD\system_page::FIELD_STATE.'" = $2'
|
||||
.' ORDER BY "'.\SYSTEM\DBD\system_page::FIELD_ID.'" ASC;',
|
||||
//mys
|
||||
'SELECT * FROM '.\SYSTEM\DBD\system_page::NAME_MYS
|
||||
.' WHERE `'.\SYSTEM\DBD\system_page::FIELD_GROUP.'` = ?'
|
||||
.' AND `'.\SYSTEM\DBD\system_page::FIELD_ID.'` = ?'
|
||||
.' ORDER BY '.\SYSTEM\DBD\system_page::FIELD_ID
|
||||
.' AND `'.\SYSTEM\DBD\system_page::FIELD_STATE.'` = ?'
|
||||
.' ORDER BY '.\SYSTEM\DBD\system_page::FIELD_ID.' ASC;'
|
||||
);}}
|
||||
@ -1,11 +1,16 @@
|
||||
CREATE TABLE `system_page` (
|
||||
`id` INT(10) UNSIGNED NOT NULL,
|
||||
`name` CHAR(50) NOT NULL COLLATE 'utf8_unicode_ci',
|
||||
`group` INT(10) UNSIGNED NOT NULL,
|
||||
`id` CHAR(50) NOT NULL,
|
||||
`div` CHAR(50) NOT NULL,
|
||||
`url` TEXT NOT NULL,
|
||||
`func` CHAR(50) NOT NULL,
|
||||
`php_class` CHAR(50) NOT NULL,
|
||||
PRIMARY KEY (`id`, `div`, `group`)
|
||||
`state` CHAR(50) NOT NULL COLLATE 'utf8_unicode_ci',
|
||||
`parent_id` INT(10) UNSIGNED NOT NULL,
|
||||
`type` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`div` CHAR(50) NOT NULL COLLATE 'utf8_unicode_ci',
|
||||
`url` TEXT NOT NULL COLLATE 'utf8_unicode_ci',
|
||||
`func` CHAR(50) NOT NULL COLLATE 'utf8_unicode_ci',
|
||||
`php_class` CHAR(50) NOT NULL COLLATE 'utf8_unicode_ci',
|
||||
PRIMARY KEY (`id`, `group`, `state`, `name`)
|
||||
)
|
||||
COLLATE='utf8_unicode_ci'
|
||||
ENGINE=InnoDB;
|
||||
ENGINE=InnoDB
|
||||
;
|
||||
|
||||
@ -5,8 +5,12 @@ class system_page {
|
||||
const NAME_PG = 'system.page';
|
||||
const NAME_MYS = 'system_page';
|
||||
|
||||
const FIELD_GROUP = 'group';
|
||||
const FIELD_ID = 'id';
|
||||
const FIELD_NAME = 'name';
|
||||
const FIELD_GROUP = 'group';
|
||||
const FIELD_STATE = 'state';
|
||||
const FIELD_PARENT_ID = 'parent_id';
|
||||
const FIELD_TYPE = 'type';
|
||||
const FIELD_DIV = 'div';
|
||||
const FIELD_URL = 'url';
|
||||
const FIELD_FUNC = 'func';
|
||||
|
||||
@ -28,6 +28,9 @@ class files {
|
||||
}else{
|
||||
\SYSTEM\HEADER::FILE($id);}
|
||||
|
||||
//Allow Caching for all files
|
||||
header('Cache-Control: public;');
|
||||
|
||||
if(!self::file_get_contents_chunked(self::$folders[$cat].$id,4096,function($chunk,&$handle,$iteration){echo $chunk;})){
|
||||
throw new \SYSTEM\LOG\ERROR("Could not transfere File.");}
|
||||
return;
|
||||
|
||||
@ -10,13 +10,13 @@ function SYSTEM(endpoint,group,start_state,hash_change){
|
||||
|
||||
this.endpoint = endpoint;
|
||||
this.group = group;
|
||||
this.pages = null;
|
||||
this.start_state = start_state;
|
||||
this.hash_change = hash_change;
|
||||
|
||||
this.state = {};
|
||||
this.state_info = {};
|
||||
this.state_js = {};
|
||||
this.state_css = {};
|
||||
this.start_state = start_state;
|
||||
this.hash_change = hash_change;
|
||||
|
||||
this.hashchange();
|
||||
$(window).bind('hashchange', this.hashchange);
|
||||
@ -25,70 +25,66 @@ SYSTEM.prototype.hashchange = function () {
|
||||
system.go_state(system.start_state);
|
||||
//user callback
|
||||
if(system.hash_change){
|
||||
system.hash_change(system.cur_state());}
|
||||
system.hash_change(system.cur_state().split('(')[0]);}
|
||||
};
|
||||
SYSTEM.prototype.handle_call_pages_data = function (entry,id,forced,cached) {
|
||||
SYSTEM.prototype.handle_call_pages_page = function (html,entry,id,forced,cached) {
|
||||
var url = entry['url']+(window.location.search.substr(1) ? '&'+window.location.search.substr(1) : '' );
|
||||
//check loaded state of div - reload only if required
|
||||
if(forced || this.state[entry['div']] !== url){
|
||||
//load pages
|
||||
$.ajax({
|
||||
async: false,
|
||||
data: {},
|
||||
dataType: 'html',
|
||||
url: url,
|
||||
success: function(data){
|
||||
if($(entry['div']).length){
|
||||
$(entry['div']).html(data);
|
||||
system.log_info('load page: '+id+entry['div']+' '+url+' - success');
|
||||
} else {
|
||||
system.log_error('load page: '+id+entry['div']+' '+url+' - div not found');
|
||||
}},
|
||||
error: function(XMLHttpRequest, textStatus, errorThrown){system.log_error(errorThrown);}
|
||||
});
|
||||
//load css
|
||||
for(var i=0; i < entry['css'].length; i++){
|
||||
this.load_css(entry['css'][i],forced);}
|
||||
//load js
|
||||
var call_func = true;
|
||||
var loaded = 0;
|
||||
for(var i=0; i < entry['js'].length; i++){
|
||||
if(forced || !this.state_js[entry['js'][i]]){
|
||||
this.log_info('load js: '+entry['js'][i]+(forced ? ' - forced' : ''));
|
||||
$.getScript(entry['js'][i])
|
||||
.done(function(response, status, jqxhr) {
|
||||
system.log_info('load js: '+status);
|
||||
if(loaded++ === entry['js'].length-1){
|
||||
var fn = window[entry['func']];
|
||||
if(call_func && typeof fn === 'function'){
|
||||
call_func = false;
|
||||
fn();
|
||||
system.log_info('call func: '+entry['func']);
|
||||
} else {
|
||||
system.log_error('call func: '+entry['func']+' - fail');
|
||||
}
|
||||
if($(entry['div']).length){
|
||||
$(entry['div']).html(html);
|
||||
this.log_info('load page: '+id+entry['div']+' '+url+' - success');
|
||||
} else {
|
||||
this.log_error('load page: '+id+entry['div']+' '+url+' - div not found');
|
||||
}
|
||||
//load css
|
||||
for(var i=0; i < entry['css'].length; i++){
|
||||
this.load_css(entry['css'][i],forced);}
|
||||
//load js
|
||||
var call_func = true;
|
||||
var loaded = 0;
|
||||
for(var i=0; i < entry['js'].length; i++){
|
||||
if(forced || !this.state_js[entry['js'][i]]){
|
||||
this.log_info('load js: '+entry['js'][i]+(forced ? ' - forced' : ''));
|
||||
$.getScript(entry['js'][i])
|
||||
.done(function(response, status, jqxhr) {
|
||||
system.log_info('load js: '+status);
|
||||
if(loaded++ === entry['js'].length-1){
|
||||
var fn = window[entry['func']];
|
||||
if(call_func && typeof fn === 'function'){
|
||||
call_func = false;
|
||||
fn();
|
||||
system.log_info('call func: '+entry['func']);
|
||||
} else {
|
||||
system.log_error('call func: '+entry['func']+' - fail');
|
||||
}
|
||||
})
|
||||
.fail(function( jqxhr, settings, exception ) {
|
||||
system.log_error( "Something went wrong"+exception );
|
||||
});
|
||||
this.state_js[entry['js'][i]] = true;
|
||||
} else {
|
||||
this.log_info('load js: '+entry['js'][i]+' - cached');
|
||||
if(loaded++ === entry['js'].length-1){
|
||||
var fn = window[entry['func']];
|
||||
if(call_func && typeof fn === 'function'){
|
||||
call_func = false;
|
||||
fn();
|
||||
this.log_info('call func: '+entry['func']);
|
||||
} else {
|
||||
this.log_error('call func: '+entry['func']+' - fail');
|
||||
}
|
||||
})
|
||||
.fail(function( jqxhr, settings, exception ) {
|
||||
system.log_error( "Something went wrong"+exception );
|
||||
});
|
||||
this.state_js[entry['js'][i]] = true;
|
||||
} else {
|
||||
this.log_info('load js: '+entry['js'][i]+' - cached');
|
||||
if(loaded++ === entry['js'].length-1){
|
||||
var fn = window[entry['func']];
|
||||
if(call_func && typeof fn === 'function'){
|
||||
call_func = false;
|
||||
fn();
|
||||
this.log_info('call func: '+entry['func']);
|
||||
} else {
|
||||
this.log_error('call func: '+entry['func']+' - fail');
|
||||
}
|
||||
}
|
||||
}
|
||||
//update state
|
||||
this.state[entry['div']] = url;
|
||||
}
|
||||
//update state
|
||||
this.state[entry['div']] = url;
|
||||
}
|
||||
SYSTEM.prototype.handle_call_pages_entry = function (entry,id,forced,cached) {
|
||||
var url = entry['url']+(window.location.search.substr(1) ? '&'+window.location.search.substr(1) : '' );
|
||||
//check loaded state of div - reload only if required
|
||||
if(forced || this.state[entry['div']] !== url){
|
||||
//load page
|
||||
this.call_url(url,function(data){system.handle_call_pages_page(data,entry,id,forced,cached);},{},'html',true);
|
||||
} else {
|
||||
this.log_info('load page: '+id+entry['div']+' '+url+' - skipped - already loaded');
|
||||
}
|
||||
@ -96,6 +92,10 @@ SYSTEM.prototype.handle_call_pages_data = function (entry,id,forced,cached) {
|
||||
//internal function to handle pagestate results
|
||||
SYSTEM.prototype.handle_call_pages = function (data,id,forced,cached) {
|
||||
if(data['status']){
|
||||
//clear old state
|
||||
this.state = {}
|
||||
this.state_info = {}
|
||||
|
||||
this.log_info('load pages: endpoint '+this.endpoint+' group:'+this.group+' state:'+id+' - '+(cached ? 'cached ' : (forced ? 'forced' : 'success')));
|
||||
//state not found?
|
||||
if(data['result'].length === 0){
|
||||
@ -108,18 +108,21 @@ SYSTEM.prototype.handle_call_pages = function (data,id,forced,cached) {
|
||||
if(id !== this.cur_state()){
|
||||
window.history.pushState(null, "", '#!'+id);}
|
||||
data['result'].forEach(
|
||||
function(entry) { system.handle_call_pages_data(entry,id,forced,cached);});
|
||||
function(entry) { system.handle_call_pages_entry(entry,id,forced,cached);});
|
||||
} else {
|
||||
this.log_info('Problem with your Pages: '+data['result']['message']);
|
||||
}
|
||||
};
|
||||
//send a call to the endpoint
|
||||
SYSTEM.prototype.call = function(call,success,data,data_type,async){
|
||||
this.call_url(this.endpoint+'?'+call,success,data,data_type,async);
|
||||
};
|
||||
SYSTEM.prototype.call_url = function(url,success,data,data_type,async){
|
||||
$.ajax({
|
||||
async: async,
|
||||
data: data,
|
||||
dataType: data_type,
|
||||
url: this.endpoint+'?'+call,
|
||||
url: url,
|
||||
success: success,
|
||||
error: function(XMLHttpRequest, textStatus, errorThrown){system.log_error(call+' '+XMLHttpRequest+' '+textStatus+' '+errorThrown);}
|
||||
});
|
||||
|
||||
114
page/State.php
114
page/State.php
@ -2,14 +2,23 @@
|
||||
namespace SYSTEM\PAGE;
|
||||
class State {
|
||||
public static function get($group,$state,$returnasjson=true){
|
||||
$state = \explode(';', $state);
|
||||
//seperate state from vars
|
||||
$state_vars = \explode(';', $state);
|
||||
//parse substates
|
||||
$state_all = \explode('(', $state_vars[0]);
|
||||
$state_name = $state_all[0];
|
||||
$substate = substr($state_vars[0], strlen($state_name));
|
||||
$substate = self::parse_substate($substate);
|
||||
//vars
|
||||
$vars = array();
|
||||
for($i=1;$i<count($state);$i++){
|
||||
$var = \explode('.',$state[$i]);
|
||||
$vars[$var[0]] = $var[1];}
|
||||
$result = array();
|
||||
$res = \SYSTEM\DBD\SYS_PAGE_GROUP::QQ(array($group,$state[0]));
|
||||
$res = \SYSTEM\DBD\SYS_PAGE_GROUP::QQ(array($group,$state_name));
|
||||
while($row = $res->next()){
|
||||
if(!self::is_loaded($row,$substate,$state_name) && $row['type'] == 1){
|
||||
continue;}
|
||||
$row['url'] = \SYSTEM\PAGE\replace::replace($row['url'], $vars);
|
||||
$row['url'] = \SYSTEM\PAGE\replace::clean($row['url']);
|
||||
//clean url of empty variables
|
||||
@ -23,5 +32,104 @@ class State {
|
||||
$row['php_class'] = '';
|
||||
$result[] = $row;
|
||||
}
|
||||
return $returnasjson ? \SYSTEM\LOG\JsonResult::toString($result) : $result;}
|
||||
return $returnasjson ? \SYSTEM\LOG\JsonResult::toString($result) : $result;
|
||||
}
|
||||
public static function parse_substate($substate){
|
||||
return (new ParensParser())->parse($substate);
|
||||
}
|
||||
private static function is_loaded($row,&$substate,$state_name,$parent_id = -1){
|
||||
for($i=0;$i<count($substate);$i++){
|
||||
if($row['name'] == $state_name){
|
||||
$substate[$i]['parent_id'] = $row['id'];}
|
||||
if($substate[$i]['name'] == $row['name'] && $substate[$i]['parent_id'] == $row['parent_id']){
|
||||
$substate[$i]['parent_id'] = $parent_id;
|
||||
return true;
|
||||
}
|
||||
if(array_key_exists('parent_id', $substate[$i])){
|
||||
if(self::is_loaded($row,$substate[$i]['sub'],$state_name,$substate[$i]['parent_id'])){
|
||||
return true;}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class ParensParser
|
||||
{
|
||||
// something to keep track of parens nesting
|
||||
protected $stack = null;
|
||||
// current level
|
||||
protected $current = null;
|
||||
|
||||
// input string to parse
|
||||
protected $string = null;
|
||||
// current character offset in string
|
||||
protected $position = null;
|
||||
// start of text-buffer
|
||||
protected $buffer_start = null;
|
||||
|
||||
public function parse($string)
|
||||
{
|
||||
if (!$string) {
|
||||
// no string, no data
|
||||
return array();
|
||||
}
|
||||
|
||||
if ($string[0] == '(') {
|
||||
// killer outer parens, as they're unnecessary
|
||||
$string = substr($string, 1, -1);
|
||||
}
|
||||
|
||||
$this->current = array();
|
||||
$this->stack = array();
|
||||
|
||||
$this->string = $string;
|
||||
$this->length = strlen($this->string);
|
||||
// look at each character
|
||||
for ($this->position=0; $this->position < $this->length; $this->position++) {
|
||||
switch ($this->string[$this->position]) {
|
||||
case '(':
|
||||
$this->push();
|
||||
// push current scope to the stack an begin a new scope
|
||||
array_push($this->stack, $this->current);
|
||||
$this->current = array();
|
||||
break;
|
||||
|
||||
case ')':
|
||||
$this->push();
|
||||
// save current scope
|
||||
$t = $this->current;
|
||||
// get the last scope from stack
|
||||
$this->current = array_pop($this->stack);
|
||||
// add just saved scope to current scope
|
||||
$this->current[count($this->current)-1]['sub'] = $t;
|
||||
break;
|
||||
case '|':
|
||||
// make each word its own token
|
||||
$this->push();
|
||||
break;
|
||||
default:
|
||||
// remember the offset to do a string capture later
|
||||
// could've also done $buffer .= $string[$position]
|
||||
// but that would just be wasting resources…
|
||||
if ($this->buffer_start === null) {
|
||||
$this->buffer_start = $this->position;
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->push();
|
||||
return $this->current;
|
||||
}
|
||||
|
||||
protected function push()
|
||||
{
|
||||
if ($this->buffer_start !== null) {
|
||||
// extract string from buffer start to current position
|
||||
$buffer = substr($this->string, $this->buffer_start, $this->position - $this->buffer_start);
|
||||
// clean buffer
|
||||
$this->buffer_start = null;
|
||||
// throw token into current scope
|
||||
$this->current[] = array('name' => $buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1 +1 @@
|
||||
<a href="javascript:system.language('${lang}');"><img src="./api.php?call=files&cat=saistart_sys_sai&id=flag_${lang}.png" alt="${lang}"></a>
|
||||
<a href="javascript:system.language('${lang}');"><img src="./api.php?call=files&cat=saistart_sys_sai&id=flag_${lang}.png" alt="${lang}" width="16" height="11"></a>
|
||||
@ -298,7 +298,8 @@ class saimod_sys_log extends \SYSTEM\SAI\SaiModule {
|
||||
//print_r($r);
|
||||
$r['class_row'] = self::tablerow_class($r['class']);
|
||||
$r['time'] = self::time_elapsed_string(strtotime($r['time']));
|
||||
$r['message'] = substr($r['message'],0,255);
|
||||
$r['message'] = htmlspecialchars(substr($r['message'],0,255));
|
||||
$r['request_uri'] = htmlspecialchars($r['request_uri']);
|
||||
$table .= \SYSTEM\PAGE\replace::replaceFile(\SYSTEM\SERVERPATH(new \SYSTEM\PSAI(),'modules/saimod_sys_log/tpl/saimod_sys_log_table_row.tpl'),$r);
|
||||
}
|
||||
$vars = array();
|
||||
|
||||
@ -47,6 +47,8 @@ class saimod_sys_todo extends \SYSTEM\SAI\SaiModule {
|
||||
//$row['report_type'] = self::reporttype($row['type']);
|
||||
$row['state_string'] = self::state($row['count']);
|
||||
$row['state_btn'] = self::statebtn($row['count']);
|
||||
$row['message'] = htmlspecialchars($row['message']);
|
||||
$row['request_uri'] = htmlspecialchars($row['request_uri']);
|
||||
if($row['type'] == \SYSTEM\DBD\system_todo::FIELD_TYPE_USER){
|
||||
$row['message'] = str_replace("\r", '<br/>', $row['message']);
|
||||
$result_user .= \SYSTEM\PAGE\replace::replaceFile(\SYSTEM\SERVERPATH(new \SYSTEM\PSAI(),'modules/saimod_sys_todo/tpl/todo_user_list_element.tpl'), $row);
|
||||
|
||||
@ -29,8 +29,6 @@ class saistart_sys_sai extends \SYSTEM\SAI\SaiModule {
|
||||
$vars = array();
|
||||
$vars['project_name'] = \SYSTEM\CONFIG\config::get(\SYSTEM\CONFIG\config_ids::SYS_SAI_CONFIG_PROJECT);
|
||||
$vars['project_url'] = \SYSTEM\CONFIG\config::get(\SYSTEM\CONFIG\config_ids::SYS_CONFIG_PATH_BASEURL);
|
||||
$vars['todo_entries'] = \SYSTEM\SAI\saimod_sys_todo::sai_mod__SYSTEM_SAI_saimod_sys_todo_action_todolist();
|
||||
$vars['log_entries'] = \SYSTEM\SAI\saimod_sys_log::sai_mod__SYSTEM_SAI_saimod_sys_log_action_filter();
|
||||
$vars['analytics'] = \SYSTEM\SAI\saimod_sys_log::analytics();
|
||||
$user = \SYSTEM\SECURITY\Security::getUser();
|
||||
$vars['username'] = $user->username;
|
||||
|
||||
@ -48,10 +48,10 @@
|
||||
<h2 class="muted"><a href="#!todo">Todo</a></h2>
|
||||
<b>Status:</b> ${project_count}/${project_all}<br/>
|
||||
<b>Progress:</b> ${project}%
|
||||
${todo_entries}
|
||||
<div id="todo_entries"></div>
|
||||
</div>
|
||||
<div class="well" id="log">
|
||||
<h2 class="muted"><a href="#!log">Log</a></h2>
|
||||
<h4 class="muted">100 Latest Log Entries</h4>
|
||||
${log_entries}
|
||||
<div id="log_entries"></div>
|
||||
</div>
|
||||
Loading…
x
Reference in New Issue
Block a user