Internal rework pending editframe
This commit is contained in:
parent
4f79a1a997
commit
264747e2f3
@ -2,18 +2,36 @@
|
|||||||
|
|
||||||
namespace App\Classes;
|
namespace App\Classes;
|
||||||
|
|
||||||
|
use App\Classes\Control\EditFrame;
|
||||||
use App\Classes\Control\Register;
|
use App\Classes\Control\Register;
|
||||||
use App\Classes\Control\Telnet;
|
use App\Classes\Control\Telnet;
|
||||||
|
|
||||||
abstract class Control
|
abstract class Control
|
||||||
{
|
{
|
||||||
|
// Has this control class finished with input
|
||||||
protected $complete = FALSE;
|
protected $complete = FALSE;
|
||||||
|
|
||||||
|
// The server object that is running this control class
|
||||||
protected $so = NULL;
|
protected $so = NULL;
|
||||||
|
|
||||||
|
// The frame applicable for this control (not the current rendered frame, thats in $so)
|
||||||
|
protected $fo = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* What is the state of the server outside of this control.
|
||||||
|
* Should only contain
|
||||||
|
* + mode = Mode to follow outside of the control method
|
||||||
|
* + action = Action to run after leaving the control method
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
public $state = [];
|
public $state = [];
|
||||||
|
|
||||||
public function __construct(Server $so) {
|
public function __construct(Server $so,Frame $fo=NULL) {
|
||||||
$this->so = $so;
|
$this->so = $so;
|
||||||
|
$this->fo = $fo;
|
||||||
|
|
||||||
|
// Boot control, preparing anything before keyboard entry
|
||||||
$this->boot();
|
$this->boot();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,8 +49,11 @@ abstract class Control
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @todo Change to Dynamic Calls by the existence of files in App\Classes\Control
|
// @todo Change to Dynamic Calls by the existence of files in App\Classes\Control
|
||||||
public static function factory(string $name, Server $so) {
|
public static function factory(string $name,Server $so,Frame $fo=NULL) {
|
||||||
switch ($name) {
|
switch ($name) {
|
||||||
|
case 'editframe':
|
||||||
|
return new EditFrame($so,$fo);
|
||||||
|
|
||||||
case 'register':
|
case 'register':
|
||||||
return new Register($so);
|
return new Register($so);
|
||||||
|
|
||||||
@ -44,5 +65,5 @@ abstract class Control
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract public function handle(string $char);
|
abstract public function handle(string $read);
|
||||||
}
|
}
|
@ -12,7 +12,6 @@ use Illuminate\Support\Facades\Validator;
|
|||||||
* Class Register handles registration
|
* Class Register handles registration
|
||||||
*
|
*
|
||||||
* @todo REMOVE the force .WHITE at the end of each sendBaseline()
|
* @todo REMOVE the force .WHITE at the end of each sendBaseline()
|
||||||
*
|
|
||||||
* @package App\Classes\Control
|
* @package App\Classes\Control
|
||||||
*/
|
*/
|
||||||
class Register extends Control
|
class Register extends Control
|
||||||
@ -21,7 +20,7 @@ class Register extends Control
|
|||||||
|
|
||||||
protected function boot()
|
protected function boot()
|
||||||
{
|
{
|
||||||
$this->so->sendBaseline($this->so->client(),GREEN.'Select User Name'.WHITE);
|
$this->so->sendBaseline($this->so->co,GREEN.'Select User Name'.WHITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -37,124 +36,114 @@ class Register extends Control
|
|||||||
*/
|
*/
|
||||||
public function handle(string $read,array $current=[])
|
public function handle(string $read,array $current=[])
|
||||||
{
|
{
|
||||||
// Ignore CR
|
|
||||||
if ($read == CR)
|
|
||||||
return '';
|
|
||||||
|
|
||||||
// If we got a # we'll be completing field input.
|
// If we got a # we'll be completing field input.
|
||||||
if ($read == HASH OR $read == LF) {
|
if ($read == HASH OR $read == LF) {
|
||||||
|
// Does our field have data...
|
||||||
|
if (array_get($current['fielddata'],$current['fieldnum'])) {
|
||||||
|
switch ($current['fieldnum']) {
|
||||||
|
// Username
|
||||||
|
case 0:
|
||||||
|
// See if the requested username already exists
|
||||||
|
if (User::where('login', $current['fielddata'][$current['fieldnum']])->exists()) {
|
||||||
|
$this->so->sendBaseline($this->so->co,RED.'USER ALREADY EXISTS'.WHITE);
|
||||||
|
|
||||||
// Our registration page
|
return '';
|
||||||
// @todo get this from the DB
|
}
|
||||||
if ($current['page']['frame'] == '981') {
|
|
||||||
|
|
||||||
// Does our field have data...
|
$this->data['user'] = $current['fielddata'][$current['fieldnum']];
|
||||||
if (array_get($current['fielddata'],$current['fieldnum'])) {
|
$this->so->sendBaseline($this->so->co,GREEN.'Enter Real Name'.WHITE);
|
||||||
switch ($current['fieldnum']) {
|
|
||||||
// Username
|
|
||||||
case 0:
|
|
||||||
// See if the requested username already exists
|
|
||||||
if (User::where('login', $current['fielddata'][$current['fieldnum']])->exists()) {
|
|
||||||
$this->so->sendBaseline($this->so->client(), RED . 'USER ALREADY EXISTS'.WHITE);
|
|
||||||
|
|
||||||
return '';
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
$this->data['user'] = $current['fielddata'][$current['fieldnum']];
|
// Real Name
|
||||||
$this->so->sendBaseline($this->so->client(), GREEN . 'Enter Real Name'.WHITE);
|
case 1:
|
||||||
|
$this->data['name'] = $current['fielddata'][$current['fieldnum']];
|
||||||
|
$this->so->sendBaseline($this->so->co,GREEN.'Enter Email Address'.WHITE);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Real Name
|
// Email Address
|
||||||
case 1:
|
case 2:
|
||||||
$this->data['name'] = $current['fielddata'][$current['fieldnum']];
|
if (Validator::make(['email'=>$current['fielddata'][$current['fieldnum']]],[
|
||||||
$this->so->sendBaseline($this->so->client(), GREEN . 'Enter Email Address'.WHITE);
|
'email'=>'email',
|
||||||
|
])->fails()) {
|
||||||
|
$this->so->sendBaseline($this->so->co,RED.'INVALID EMAIL ADDRESS'.WHITE);
|
||||||
|
|
||||||
break;
|
return '';
|
||||||
|
};
|
||||||
|
|
||||||
// Email Address
|
// See if the requested email already exists
|
||||||
case 2:
|
if (User::where('email', $current['fielddata'][$current['fieldnum']])->exists()) {
|
||||||
if (Validator::make(['email'=>$current['fielddata'][$current['fieldnum']]],[
|
$this->so->sendBaseline($this->so->co,RED.'USER ALREADY EXISTS'.WHITE);
|
||||||
'email'=>'email',
|
|
||||||
])->fails()) {
|
|
||||||
$this->so->sendBaseline($this->so->client(), RED . 'INVALID EMAIL ADDRESS'.WHITE);
|
|
||||||
|
|
||||||
return '';
|
return '';
|
||||||
};
|
}
|
||||||
|
|
||||||
// See if the requested email already exists
|
$this->data['email'] = $current['fielddata'][$current['fieldnum']];
|
||||||
if (User::where('email', $current['fielddata'][$current['fieldnum']])->exists()) {
|
$this->data['token'] = sprintf('%06.0f',rand(0,999999));
|
||||||
$this->so->sendBaseline($this->so->client(), RED . 'USER ALREADY EXISTS'.WHITE);
|
|
||||||
|
|
||||||
return '';
|
$this->so->sendBaseline($this->so->co,YELLOW.'PROCESSING...'.WHITE);
|
||||||
}
|
Mail::to($this->data['email'])->sendNow(new SendToken($this->data['token']));
|
||||||
|
|
||||||
$this->data['email'] = $current['fielddata'][$current['fieldnum']];
|
if (Mail::failures()) {
|
||||||
$this->data['token'] = sprintf('%06.0f',rand(0,999999));
|
dump('Failure?');
|
||||||
|
|
||||||
$this->so->sendBaseline($this->so->client(), YELLOW . 'PROCESSING...'.WHITE);
|
dump(Mail::failures());
|
||||||
Mail::to($this->data['email'])->sendNow(new SendToken($this->data['token']));
|
}
|
||||||
|
|
||||||
if (Mail::failures()) {
|
$this->so->sendBaseline($this->so->co,GREEN.'Enter Password'.WHITE);
|
||||||
dump('Failure?');
|
|
||||||
|
|
||||||
dump(Mail::failures());
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
$this->so->sendBaseline($this->so->client(), GREEN . 'Enter Password'.WHITE);
|
// Enter Password
|
||||||
|
case 3:
|
||||||
|
$this->data['password'] = $current['fielddata'][$current['fieldnum']];
|
||||||
|
$this->so->sendBaseline($this->so->co,GREEN.'Confirm Password'.WHITE);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Enter Password
|
// Confirm Password
|
||||||
case 3:
|
case 4:
|
||||||
$this->data['password'] = $current['fielddata'][$current['fieldnum']];
|
if ($this->data['password'] !== $current['fielddata'][$current['fieldnum']]) {
|
||||||
$this->so->sendBaseline($this->so->client(), GREEN . 'Confirm Password'.WHITE);
|
$this->so->sendBaseline($this->so->co,RED.'PASSWORD DOESNT MATCH, *09 TO START AGAIN'.WHITE);
|
||||||
|
|
||||||
break;
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
// Confirm Password
|
$this->so->sendBaseline($this->so->co,GREEN.'Enter Location'.WHITE);
|
||||||
case 4:
|
|
||||||
if ($this->data['password'] !== $current['fielddata'][$current['fieldnum']]) {
|
|
||||||
$this->so->sendBaseline($this->so->client(), RED . 'PASSWORD DOESNT MATCH, *09 TO START AGAIN'.WHITE);
|
|
||||||
|
|
||||||
return '';
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
$this->so->sendBaseline($this->so->client(), GREEN . 'Enter Location'.WHITE);
|
// Enter Location
|
||||||
|
case 5:
|
||||||
|
$this->data['location'] = $current['fielddata'][$current['fieldnum']];
|
||||||
|
$this->so->sendBaseline($this->so->co,GREEN.'Enter TOKEN emailed to you'.WHITE);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Enter Location
|
// Enter Token
|
||||||
case 5:
|
case 6:
|
||||||
$this->data['location'] = $current['fielddata'][$current['fieldnum']];
|
if ($this->data['token'] !== $current['fielddata'][$current['fieldnum']]) {
|
||||||
$this->so->sendBaseline($this->so->client(), GREEN . 'Enter TOKEN emailed to you'.WHITE);
|
$this->so->sendBaseline($this->so->co,RED.'TOKEN DOESNT MATCH, *09 TO START AGAIN'.WHITE);
|
||||||
|
|
||||||
break;
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
// Enter Token
|
break;
|
||||||
case 6:
|
|
||||||
if ($this->data['token'] !== $current['fielddata'][$current['fieldnum']]) {
|
|
||||||
$this->so->sendBaseline($this->so->client(), RED . 'TOKEN DOESNT MATCH, *09 TO START AGAIN'.WHITE);
|
|
||||||
|
|
||||||
return '';
|
default:
|
||||||
}
|
$this->so->sendBaseline($this->so->co,RED.'HUH?');
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
} else {
|
||||||
|
// If we are MODE_BL, we need to return the HASH, otherwise nothing.
|
||||||
default:
|
if (in_array($this->state['mode'],[MODE_BL,MODE_SUBMITRF,MODE_RFNOTSENT])) {
|
||||||
$this->so->sendBaseline($this->so->client(), RED . 'HUH?');
|
return $read;
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// If we are MODE_BL, we need to return the HASH, otherwise nothing.
|
$this->so->sendBaseline($this->so->co,RED.'FIELD REQUIRED...'.WHITE);
|
||||||
if (in_array($this->state['mode'],[MODE_BL,MODE_SUBMITRF,MODE_RFNOTSENT])) {
|
|
||||||
return $read;
|
|
||||||
|
|
||||||
} else {
|
return '';
|
||||||
$this->so->sendBaseline($this->so->client(), RED . 'FIELD REQUIRED...'.WHITE);
|
|
||||||
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -174,14 +163,14 @@ class Register extends Control
|
|||||||
$o->location = $this->data['location'];
|
$o->location = $this->data['location'];
|
||||||
|
|
||||||
$o->save();
|
$o->save();
|
||||||
$this->so->sendBaseline($this->so->client(), GREEN . 'ACCOUNT CREATED, PRESS '.HASH.' TO CONTINUE...'.WHITE);
|
$this->so->sendBaseline($this->so->co,GREEN.'ACCOUNT CREATED, PRESS '.HASH.' TO CONTINUE...'.WHITE);
|
||||||
$this->state['action'] = ACTION_NEXT;
|
$this->state['action'] = ACTION_NEXT;
|
||||||
|
|
||||||
// Add to CUG 0
|
// Add to CUG 0
|
||||||
$o->cugs()->attach(0);
|
$o->cugs()->attach(0);
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$this->so->sendBaseline($this->so->client(), RED . 'SOMETHING WENT WRONG...'.WHITE);
|
$this->so->sendBaseline($this->so->co,RED.'SOMETHING WENT WRONG...'.WHITE);
|
||||||
$this->so->log('error',$e->getMessage());
|
$this->so->log('error',$e->getMessage());
|
||||||
$this->state['action'] = ACTION_RELOAD;
|
$this->state['action'] = ACTION_RELOAD;
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,12 @@
|
|||||||
|
|
||||||
namespace App\Classes;
|
namespace App\Classes;
|
||||||
|
|
||||||
use App\Models\Mode;
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
use App\User;
|
use App\User;
|
||||||
use App\Models\CUG;
|
use App\Models\{CUG,Mode};
|
||||||
|
use App\Models\Frame as FrameModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles all aspects of frame
|
* Handles all aspects of frame
|
||||||
@ -34,12 +35,14 @@ use App\Models\CUG;
|
|||||||
*/
|
*/
|
||||||
abstract class Frame
|
abstract class Frame
|
||||||
{
|
{
|
||||||
protected $frame = NULL;
|
// This holds the parser object for this frame.
|
||||||
protected $output = '';
|
protected $po = NULL;
|
||||||
protected $startline = 1;
|
|
||||||
|
// This holds the frame object as retrieved from the DB
|
||||||
|
protected $fo = NULL;
|
||||||
|
|
||||||
// All this vars should be overridden in the child class
|
|
||||||
/*
|
/*
|
||||||
|
// All this vars should be overridden in the child class
|
||||||
protected $frame_length = 22;
|
protected $frame_length = 22;
|
||||||
protected $frame_width = 40;
|
protected $frame_width = 40;
|
||||||
|
|
||||||
@ -54,9 +57,8 @@ abstract class Frame
|
|||||||
const FRAMETYPE_LOGIN = 'l';
|
const FRAMETYPE_LOGIN = 'l';
|
||||||
const FRAMETYPE_TERMINATE = 't';
|
const FRAMETYPE_TERMINATE = 't';
|
||||||
|
|
||||||
public $fields = NULL; // The fields in this frame.
|
|
||||||
|
|
||||||
// Fields that are editable
|
// Fields that are editable
|
||||||
|
// @todo This needs rework.
|
||||||
private $fieldoptions = [
|
private $fieldoptions = [
|
||||||
'p'=>['edit'=>TRUE,'mask'=>'*'], // Password
|
'p'=>['edit'=>TRUE,'mask'=>'*'], // Password
|
||||||
't'=>['edit'=>TRUE], // Text
|
't'=>['edit'=>TRUE], // Text
|
||||||
@ -65,38 +67,44 @@ abstract class Frame
|
|||||||
// @todo Move this to the database
|
// @todo Move this to the database
|
||||||
private $header = RED.'T'.BLUE.'E'.GREEN.'S'.YELLOW.'T'.MAGENTA.'!';
|
private $header = RED.'T'.BLUE.'E'.GREEN.'S'.YELLOW.'T'.MAGENTA.'!';
|
||||||
|
|
||||||
public function __construct(\App\Models\Frame $o)
|
public function __construct(FrameModel $o)
|
||||||
{
|
{
|
||||||
$this->frame = $o;
|
$this->fo = $o;
|
||||||
|
$startline = 1;
|
||||||
|
|
||||||
$this->output = $this->frame->cls ? CLS : HOME;
|
if ($this->fo->exists) {
|
||||||
|
if (! $this->hasFlag('ip') AND (! $this->isCUG(0) OR $this->type() !== self::FRAMETYPE_LOGIN)) {
|
||||||
|
$startline = 2;
|
||||||
|
|
||||||
if (! $this->hasFlag('ip') AND (! $this->isCUG(0) OR $this->type() !== self::FRAMETYPE_LOGIN)) {
|
} elseif ($this->isCUG(0) AND $this->type() === self::FRAMETYPE_LOGIN) {
|
||||||
// Set the page header: CUG/Site Name | Page # | Cost
|
$startline = 2;
|
||||||
$this->output .= $this->render_header($this->header).
|
}
|
||||||
$this->render_page($this->frame->frame,$this->frame->index).
|
|
||||||
$this->render_cost($this->frame->cost);
|
|
||||||
|
|
||||||
$this->startline = 2;
|
|
||||||
|
|
||||||
} elseif ($this->isCUG(0) AND $this->type() === self::FRAMETYPE_LOGIN) {
|
|
||||||
$this->startline = 2;
|
|
||||||
$this->output .= str_repeat(DOWN,$this->startline-1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate fields and render output.
|
// Our parser object
|
||||||
$this->fields = collect(); // Fields in this frame.
|
$this->po = $this->parser($startline);
|
||||||
$this->fields($this->startline);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render the frame
|
* Render the frame
|
||||||
*
|
*
|
||||||
* @return null|string
|
* @return null|string
|
||||||
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function __toString()
|
public function __toString()
|
||||||
{
|
{
|
||||||
return $this->output;
|
$output = $this->fo->cls ? CLS : HOME;
|
||||||
|
|
||||||
|
if (! $this->hasFlag('ip') AND (! $this->isCUG(0) OR $this->type() !== self::FRAMETYPE_LOGIN)) {
|
||||||
|
$output .= $this->render_header($this->header).
|
||||||
|
$this->render_page($this->fo->frame,$this->fo->index).
|
||||||
|
$this->render_cost($this->fo->cost);
|
||||||
|
|
||||||
|
} elseif ($this->isCUG(0) AND $this->type() === self::FRAMETYPE_LOGIN) {
|
||||||
|
$output .= str_repeat(DOWN,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $output.(string)$this->po;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -106,9 +114,9 @@ abstract class Frame
|
|||||||
*/
|
*/
|
||||||
public function alts(Mode $o)
|
public function alts(Mode $o)
|
||||||
{
|
{
|
||||||
return \App\Models\Frame::where('frame',$this->frame())
|
return FrameModel::where('frame',$this->fo->frame)
|
||||||
->where('index',$this->index())
|
->where('index',$this->index())
|
||||||
->where('id','<>',$this->frame->id)
|
->where('id','<>',$this->fo->id)
|
||||||
->where('mode_id',$o->id)
|
->where('mode_id',$o->id)
|
||||||
->where('access',1)
|
->where('access',1)
|
||||||
->limit(9);
|
->limit(9);
|
||||||
@ -119,23 +127,33 @@ abstract class Frame
|
|||||||
*/
|
*/
|
||||||
public function created()
|
public function created()
|
||||||
{
|
{
|
||||||
return $this->frame->created_at;
|
return $this->fo->created_at;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the frame from Binary to Output
|
* Return fields within the frame.
|
||||||
* Look for fields within the frame.
|
|
||||||
*
|
|
||||||
* @param int $startline
|
|
||||||
*/
|
*/
|
||||||
abstract public function fields($startline=0);
|
public function fields()
|
||||||
|
{
|
||||||
|
return $this->po->fields;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current frame.
|
* Returns the current frame.
|
||||||
*/
|
*/
|
||||||
public function frame()
|
public function frame()
|
||||||
{
|
{
|
||||||
return $this->frame->frame;
|
return $this->fo->frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function frame_length()
|
||||||
|
{
|
||||||
|
return static::$frame_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function frame_width()
|
||||||
|
{
|
||||||
|
return static::$frame_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -149,7 +167,7 @@ abstract class Frame
|
|||||||
public function getCUG()
|
public function getCUG()
|
||||||
{
|
{
|
||||||
$co = NULL;
|
$co = NULL;
|
||||||
$frame = $this->frame->frame;
|
$frame = $this->fo->frame;
|
||||||
|
|
||||||
while (! $co)
|
while (! $co)
|
||||||
{
|
{
|
||||||
@ -171,7 +189,7 @@ abstract class Frame
|
|||||||
*/
|
*/
|
||||||
public function getField(int $id)
|
public function getField(int $id)
|
||||||
{
|
{
|
||||||
return $this->fields->get($id);
|
return $this->fields()->get($id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -183,7 +201,7 @@ abstract class Frame
|
|||||||
*/
|
*/
|
||||||
public function getFieldId($type='edit',$after=0)
|
public function getFieldId($type='edit',$after=0)
|
||||||
{
|
{
|
||||||
return $this->fields
|
return $this->fields()
|
||||||
->search(function($item,$key) use ($type,$after) {
|
->search(function($item,$key) use ($type,$after) {
|
||||||
return $key >= $after AND $this->isFieldEditable($item->type);
|
return $key >= $after AND $this->isFieldEditable($item->type);
|
||||||
});
|
});
|
||||||
@ -204,7 +222,7 @@ abstract class Frame
|
|||||||
*/
|
*/
|
||||||
public function hasFlag($flag)
|
public function hasFlag($flag)
|
||||||
{
|
{
|
||||||
return $this->frame->hasFlag($flag);
|
return $this->fo->hasFlag($flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -214,7 +232,7 @@ abstract class Frame
|
|||||||
*/
|
*/
|
||||||
public function id()
|
public function id()
|
||||||
{
|
{
|
||||||
return $this->frame->id;
|
return $this->fo->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -224,7 +242,7 @@ abstract class Frame
|
|||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
return $this->frame->index;
|
return $this->fo->index;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -232,16 +250,25 @@ abstract class Frame
|
|||||||
*/
|
*/
|
||||||
public function index_next()
|
public function index_next()
|
||||||
{
|
{
|
||||||
return chr(ord($this->frame->index)+1);
|
return chr(ord($this->fo->index)+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the previous index
|
||||||
|
*/
|
||||||
|
public function index_prev()
|
||||||
|
{
|
||||||
|
return $this->fo->index == 'a' ? 'a' : chr(ord($this->fo->index)-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isAccessible():bool
|
public function isAccessible():bool
|
||||||
{
|
{
|
||||||
return $this->frame->access ? TRUE : FALSE;
|
return $this->fo->access ? TRUE : FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if the frame is a particular CUG
|
* Determine if the frame is a particular CUG
|
||||||
|
*
|
||||||
* @param int $cug
|
* @param int $cug
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
@ -273,10 +300,10 @@ abstract class Frame
|
|||||||
*/
|
*/
|
||||||
public function isFramePublic(): bool
|
public function isFramePublic(): bool
|
||||||
{
|
{
|
||||||
return $this->frame->public ? TRUE : FALSE;
|
return $this->fo->public ? TRUE : FALSE;
|
||||||
}
|
}
|
||||||
// @todo To implement
|
|
||||||
|
|
||||||
|
// @todo To implement
|
||||||
public function isOwner(User $o):bool
|
public function isOwner(User $o):bool
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -287,7 +314,7 @@ abstract class Frame
|
|||||||
*/
|
*/
|
||||||
public function page(bool $as_array=FALSE)
|
public function page(bool $as_array=FALSE)
|
||||||
{
|
{
|
||||||
return $as_array ? ['frame'=>$this->frame->frame,'index'=>$this->frame->index] : $this->frame->page;
|
return $as_array ? ['frame'=>$this->fo->frame,'index'=>$this->fo->index] : $this->fo->page;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -296,11 +323,19 @@ abstract class Frame
|
|||||||
* @param bool $as_array
|
* @param bool $as_array
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function pagenext(bool $as_array=FALSE)
|
public function page_next(bool $as_array=FALSE)
|
||||||
{
|
{
|
||||||
return $as_array ? ['frame'=>$this->frame->frame,'index'=>$this->index_next()] : $this->frame->frame.$this->index_next();
|
return $as_array ? ['frame'=>$this->fo->frame,'index'=>$this->index_next()] : $this->fo->frame.$this->index_next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the parser
|
||||||
|
*
|
||||||
|
* @param int $startline
|
||||||
|
* @return Parser
|
||||||
|
*/
|
||||||
|
abstract protected function parser(int $startline): Parser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render the cost of the frame
|
* Render the cost of the frame
|
||||||
*
|
*
|
||||||
@ -359,6 +394,8 @@ abstract class Frame
|
|||||||
* Get the route for the key press
|
* Get the route for the key press
|
||||||
*
|
*
|
||||||
* @param string $read
|
* @param string $read
|
||||||
|
* @return string
|
||||||
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function route(string $read)
|
public function route(string $read)
|
||||||
{
|
{
|
||||||
@ -366,11 +403,11 @@ abstract class Frame
|
|||||||
throw new \Exception('Routes are single digit');
|
throw new \Exception('Routes are single digit');
|
||||||
|
|
||||||
// If we dont have a route record...
|
// If we dont have a route record...
|
||||||
if (! $this->frame->route)
|
if (! $this->fo->route)
|
||||||
return '*';
|
return '*';
|
||||||
|
|
||||||
$key = 'r'.$read;
|
$key = 'r'.$read;
|
||||||
return $this->frame->route->{$key};
|
return $this->fo->route->{$key};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -381,12 +418,12 @@ abstract class Frame
|
|||||||
* @param $text
|
* @param $text
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
abstract function strlenv($text):int;
|
abstract public static function strlenv($text):int;
|
||||||
|
|
||||||
public static function testFrame(Server $so)
|
public static function testFrame()
|
||||||
{
|
{
|
||||||
// Simulate a DB load
|
// Simulate a DB load
|
||||||
$o = new \App\Models\Frame;
|
$o = new FrameModel;
|
||||||
|
|
||||||
$content = '';
|
$content = '';
|
||||||
$o->flags = ['ip'];
|
$o->flags = ['ip'];
|
||||||
@ -399,7 +436,7 @@ abstract class Frame
|
|||||||
|
|
||||||
// Header
|
// Header
|
||||||
$sid = R_RED.'T'.R_BLUE.'E'.R_GREEN.'S'.R_YELLOW.'T';
|
$sid = R_RED.'T'.R_BLUE.'E'.R_GREEN.'S'.R_YELLOW.'T';
|
||||||
$content .= substr($sid.'-'.str_repeat('12345678901234567890',4),0,static::$header_length+(strlen($sid)-$so->strlenv($sid))).
|
$content .= substr($sid.'-'.str_repeat('12345678901234567890',4),0,static::$header_length+(strlen($sid)-static::strlenv($sid))).
|
||||||
R_WHITE.str_repeat('9',static::$pagenum_length).'a'.R_RED.sprintf('%07.0f',999).'u';
|
R_WHITE.str_repeat('9',static::$pagenum_length).'a'.R_RED.sprintf('%07.0f',999).'u';
|
||||||
|
|
||||||
$content .= R_WHITE.str_repeat('+-',static::$frame_width/2-3).' '.R_RED.'01';
|
$content .= R_WHITE.str_repeat('+-',static::$frame_width/2-3).' '.R_RED.'01';
|
||||||
@ -410,7 +447,7 @@ abstract class Frame
|
|||||||
|
|
||||||
$o->content = $content;
|
$o->content = $content;
|
||||||
|
|
||||||
return $o;
|
return new static($o);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -418,6 +455,6 @@ abstract class Frame
|
|||||||
*/
|
*/
|
||||||
public function type()
|
public function type()
|
||||||
{
|
{
|
||||||
return $this->frame->type();
|
return $this->fo->type();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -24,7 +24,7 @@ class Login extends Action
|
|||||||
$this->mode = 2; // MODE_FIELD
|
$this->mode = 2; // MODE_FIELD
|
||||||
// $this->action = 2; // ACTION_GOTO
|
// $this->action = 2; // ACTION_GOTO
|
||||||
|
|
||||||
$this->so->sendBaseline($this->so->client(),RED.'INVALID DETAILS, TRY AGAIN *00');
|
$this->so->sendBaseline($this->so->co,RED.'INVALID DETAILS, TRY AGAIN *00');
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -33,7 +33,7 @@ class Login extends Action
|
|||||||
$this->uo = User::where('login',array_get($fielddata,0))->firstOrFail();
|
$this->uo = User::where('login',array_get($fielddata,0))->firstOrFail();
|
||||||
|
|
||||||
} catch (ModelNotFoundException $e) {
|
} catch (ModelNotFoundException $e) {
|
||||||
$this->so->sendBaseline($this->so->client(),RED.'USER NOT FOUND, TRY AGAIN *00');
|
$this->so->sendBaseline($this->so->co,RED.'USER NOT FOUND, TRY AGAIN *00');
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -41,7 +41,7 @@ class Login extends Action
|
|||||||
if ($this->uo->password != array_get($fielddata,1))
|
if ($this->uo->password != array_get($fielddata,1))
|
||||||
{
|
{
|
||||||
$this->uo = new User;
|
$this->uo = new User;
|
||||||
$this->so->sendBaseline($this->so->client(),RED.'INVALID PASSWORD, TRY AGAIN *00');
|
$this->so->sendBaseline($this->so->co,RED.'INVALID PASSWORD, TRY AGAIN *00');
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,14 @@
|
|||||||
|
|
||||||
namespace App\Classes\Frame;
|
namespace App\Classes\Frame;
|
||||||
|
|
||||||
|
use App\Classes\Parser;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
use App\Classes\Frame as AbstractFrame;
|
use App\Classes\Frame;
|
||||||
use App\Classes\Parser\Ansi as AnsiParser;
|
use App\Classes\Parser\Ansi as AnsiParser;
|
||||||
|
use App\Models\Frame as FrameModel;
|
||||||
|
|
||||||
class Ansi extends AbstractFrame
|
class Ansi extends Frame
|
||||||
{
|
{
|
||||||
public static $frame_length = 22;
|
public static $frame_length = 22;
|
||||||
public static $frame_width = 80;
|
public static $frame_width = 80;
|
||||||
@ -19,7 +21,7 @@ class Ansi extends AbstractFrame
|
|||||||
|
|
||||||
public static $if_filler = '.';
|
public static $if_filler = '.';
|
||||||
|
|
||||||
public function __construct(\App\Models\Frame $o,string $msg='')
|
public function __construct(FrameModel $o,string $msg='')
|
||||||
{
|
{
|
||||||
parent::__construct($o);
|
parent::__construct($o);
|
||||||
|
|
||||||
@ -28,15 +30,12 @@ class Ansi extends AbstractFrame
|
|||||||
$this->output .= ESC.'[24;0f'.$msg.HOME;
|
$this->output .= ESC.'[24;0f'.$msg.HOME;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function fields($startline=1)
|
protected function parser(int $startline): Parser
|
||||||
{
|
{
|
||||||
$o = new AnsiParser($this->frame->content,$startline);
|
return new AnsiParser($this->fo->content,self::$frame_width,$startline);
|
||||||
$this->output .= (string)$o;
|
|
||||||
|
|
||||||
$this->fields = $o->fields;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function strlenv($text):int {
|
public static function strlenv($text):int {
|
||||||
return strlen($text ? preg_replace('/'.ESC.'\[[0-9;?]+[a-zA-Z]/','',$text) : $text);
|
return strlen($text ? preg_replace('/'.ESC.'\[[0-9;?]+[a-zA-Z]/','',$text) : $text);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,10 +4,12 @@ namespace App\Classes\Frame;
|
|||||||
|
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
use App\Classes\Frame as AbstractFrame;
|
use App\Classes\Frame;
|
||||||
|
use App\Classes\Parser;
|
||||||
use App\Classes\Parser\Videotex as VideotexParser;
|
use App\Classes\Parser\Videotex as VideotexParser;
|
||||||
|
use App\Models\Frame as FrameModel;
|
||||||
|
|
||||||
class Videotex extends AbstractFrame
|
class Videotex extends Frame
|
||||||
{
|
{
|
||||||
public static $frame_length = 22;
|
public static $frame_length = 22;
|
||||||
public static $frame_width = 40;
|
public static $frame_width = 40;
|
||||||
@ -19,7 +21,7 @@ class Videotex extends AbstractFrame
|
|||||||
|
|
||||||
public static $if_filler = '.';
|
public static $if_filler = '.';
|
||||||
|
|
||||||
public function __construct(\App\Models\Frame $o,string $msg='')
|
public function __construct(FrameModel $o,string $msg='')
|
||||||
{
|
{
|
||||||
parent::__construct($o);
|
parent::__construct($o);
|
||||||
|
|
||||||
@ -28,17 +30,12 @@ class Videotex extends AbstractFrame
|
|||||||
$this->output .= HOME.UP.$msg.HOME;
|
$this->output .= HOME.UP.$msg.HOME;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @todo Change to use a Parser, like we do for ANSI
|
protected function parser(int $startline): Parser
|
||||||
public function fields($startline=1)
|
|
||||||
{
|
{
|
||||||
|
return new VideotexParser($this->fo->content,self::$frame_width,$startline);
|
||||||
$o = new VideotexParser($this->frame->content,$startline);
|
|
||||||
$this->output .= (string)$o;
|
|
||||||
|
|
||||||
$this->fields = $o->fields;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function strlenv($text):int {
|
public static function strlenv($text):int {
|
||||||
return strlen($text)-substr_count($text,ESC);
|
return strlen($text)-substr_count($text,ESC);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,11 +2,22 @@
|
|||||||
|
|
||||||
namespace App\Classes;
|
namespace App\Classes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Frame Parser looks into frames for ESC codes that renders dynamic information
|
||||||
|
*/
|
||||||
abstract class Parser
|
abstract class Parser
|
||||||
{
|
{
|
||||||
protected $content = '';
|
// Fields in the frame
|
||||||
protected $startline = 0;
|
public $fields = [];
|
||||||
public $fields = NULL;
|
|
||||||
|
// Parsed frame, ready to send to client
|
||||||
|
public $output = '';
|
||||||
|
|
||||||
|
// Position array of frame control chars
|
||||||
|
protected $frame_data = [];
|
||||||
|
|
||||||
|
// Position array of frame chars
|
||||||
|
protected $frame_content = [];
|
||||||
|
|
||||||
// Magic Fields that are pre-filled
|
// Magic Fields that are pre-filled
|
||||||
protected $fieldmap = [
|
protected $fieldmap = [
|
||||||
@ -14,17 +25,16 @@ abstract class Parser
|
|||||||
'd'=>'%date',
|
'd'=>'%date',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function __construct(string $content,int $startline=1)
|
public function __construct(string $content,int $width,int $startline=1)
|
||||||
{
|
{
|
||||||
$this->content = $content;
|
|
||||||
$this->startline = $startline;
|
|
||||||
$this->fields = collect();
|
$this->fields = collect();
|
||||||
|
$this->output = $this->parse($startline,$content,$width);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __toString(): string
|
public function __toString(): string
|
||||||
{
|
{
|
||||||
return $this->parse($this->startline);
|
return $this->output;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract protected function parse($startline): string;
|
abstract protected function parse(int $startline,string $content,int $width): string;
|
||||||
}
|
}
|
@ -16,11 +16,11 @@ class Ansi extends AbstractParser {
|
|||||||
* @param int $start
|
* @param int $start
|
||||||
* @return bool|int
|
* @return bool|int
|
||||||
*/
|
*/
|
||||||
private function findEOF(string $char,int $start)
|
private function findEOF(string $char,int $start,string $content)
|
||||||
{
|
{
|
||||||
for ($c=$start;$c <= strlen($this->content);$c++)
|
for ($c=$start;$c <= strlen($content);$c++)
|
||||||
{
|
{
|
||||||
if ($this->content{$c} != $char)
|
if ($content{$c} != $char)
|
||||||
return $c-$start;
|
return $c-$start;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ class Ansi extends AbstractParser {
|
|||||||
* @param int $offset
|
* @param int $offset
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function parse($startline): string
|
protected function parse(int $startline,string $content,int $width): string
|
||||||
{
|
{
|
||||||
// Our starting coordinates
|
// Our starting coordinates
|
||||||
$x = 1;
|
$x = 1;
|
||||||
@ -40,10 +40,10 @@ class Ansi extends AbstractParser {
|
|||||||
$output = '';
|
$output = '';
|
||||||
|
|
||||||
// Scan the frame for a field start
|
// Scan the frame for a field start
|
||||||
for ($c=0; $c<=strlen($this->content); $c++)
|
for ($c=0; $c<=strlen($content); $c++)
|
||||||
{
|
{
|
||||||
// If the frame is not big enough, fill it with spaces.
|
// If the frame is not big enough, fill it with spaces.
|
||||||
$byte = isset($this->content{$c}) ? $this->content{$c} : ' ';
|
$byte = isset($content{$c}) ? $content{$c} : ' ';
|
||||||
$advance = 0;
|
$advance = 0;
|
||||||
|
|
||||||
switch ($byte) {
|
switch ($byte) {
|
||||||
@ -58,7 +58,7 @@ class Ansi extends AbstractParser {
|
|||||||
case ESC:
|
case ESC:
|
||||||
$advance = 1;
|
$advance = 1;
|
||||||
// Is the next byte something we know about
|
// Is the next byte something we know about
|
||||||
$nextbyte = isset($this->content{$c+$advance}) ? $this->content{$c+$advance} : ' ';
|
$nextbyte = isset($content{$c+$advance}) ? $content{$c+$advance} : ' ';
|
||||||
|
|
||||||
switch ($nextbyte) {
|
switch ($nextbyte) {
|
||||||
case '[':
|
case '[':
|
||||||
@ -68,7 +68,7 @@ class Ansi extends AbstractParser {
|
|||||||
// Find our end CSI param
|
// Find our end CSI param
|
||||||
$matches = [];
|
$matches = [];
|
||||||
|
|
||||||
$a = preg_match('/([0-9]+[;]?)+([a-zA-Z])/',$this->content,$matches,NULL,$c+$advance);
|
$a = preg_match('/([0-9]+[;]?)+([a-zA-Z])/',$content,$matches,NULL,$c+$advance);
|
||||||
|
|
||||||
if (! $a)
|
if (! $a)
|
||||||
break;
|
break;
|
||||||
@ -76,6 +76,13 @@ class Ansi extends AbstractParser {
|
|||||||
$advance += strlen($matches[0])-1;
|
$advance += strlen($matches[0])-1;
|
||||||
$chars .= $matches[0];
|
$chars .= $matches[0];
|
||||||
|
|
||||||
|
if (! isset($this->frame_data[$y][$x]))
|
||||||
|
$this->frame_data[$y][$x] = '';
|
||||||
|
else
|
||||||
|
$this->frame_data[$y][$x] .= '|';
|
||||||
|
|
||||||
|
$this->frame_data[$y][$x] .= $matches[0];
|
||||||
|
|
||||||
switch ($matches[2]) {
|
switch ($matches[2]) {
|
||||||
// We ignore 'm' they are color CSIs
|
// We ignore 'm' they are color CSIs
|
||||||
case 'm': break;
|
case 'm': break;
|
||||||
@ -96,10 +103,11 @@ class Ansi extends AbstractParser {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
$c--; // Allow for the original ESC
|
// Allow for the original ESC
|
||||||
|
$c--;
|
||||||
$advance++;
|
$advance++;
|
||||||
$fieldtype = ord($nextbyte)%128; // @todo Do we need the %128 for ANSI?
|
$fieldtype = ord($nextbyte);
|
||||||
$fieldlength = $this->findEOF(chr($fieldtype),$c+2)+1;
|
$fieldlength = $this->findEOF(chr($fieldtype),$c+2,$content)+1;
|
||||||
|
|
||||||
$byte = '';
|
$byte = '';
|
||||||
|
|
||||||
@ -122,6 +130,7 @@ class Ansi extends AbstractParser {
|
|||||||
$x++;
|
$x++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->frame_content[$y][$x] = $byte;
|
||||||
$output .= $byte;
|
$output .= $byte;
|
||||||
|
|
||||||
if ($advance) {
|
if ($advance) {
|
||||||
@ -129,7 +138,7 @@ class Ansi extends AbstractParser {
|
|||||||
$c += $advance;
|
$c += $advance;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($x > 80) {
|
if ($x > $width) {
|
||||||
$x = 1;
|
$x = 1;
|
||||||
$y++;
|
$y++;
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ use App\Classes\Frame\Videotex as VideotexFrame;
|
|||||||
|
|
||||||
class Videotex extends AbstractParser
|
class Videotex extends AbstractParser
|
||||||
{
|
{
|
||||||
protected function parse($startline): string
|
protected function parse(int $startline,string $content,int $width): string
|
||||||
{
|
{
|
||||||
// Our starting coordinates
|
// Our starting coordinates
|
||||||
$output = '';
|
$output = '';
|
||||||
@ -32,13 +32,13 @@ class Videotex extends AbstractParser
|
|||||||
$posn = $y*VideotexFrame::$frame_width+$x;
|
$posn = $y*VideotexFrame::$frame_width+$x;
|
||||||
|
|
||||||
// If the frame is not big enough, fill it with spaces.
|
// If the frame is not big enough, fill it with spaces.
|
||||||
$byte = ord(isset($this->content{$posn}) ? $this->content{$posn} : ' ')%128;
|
$byte = ord(isset($content{$posn}) ? $content{$posn} : ' ')%128;
|
||||||
|
|
||||||
// Check for start-of-field
|
// Check for start-of-field
|
||||||
if ($byte == ord(ESC)) { // Esc designates start of field (Esc-K is end of edit)
|
if ($byte == ord(ESC)) { // Esc designates start of field (Esc-K is end of edit)
|
||||||
$infield = TRUE;
|
$infield = TRUE;
|
||||||
$fieldlength = 1;
|
$fieldlength = 1;
|
||||||
$fieldtype = ord(substr($this->content,$posn+1,1))%128;
|
$fieldtype = ord(substr($content,$posn+1,1))%128;
|
||||||
$output .= VideotexFrame::$if_filler;
|
$output .= VideotexFrame::$if_filler;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -107,8 +107,8 @@ class Videotex extends AbstractParser
|
|||||||
}
|
}
|
||||||
|
|
||||||
// truncate end of lines @todo havent validated this code or used it?
|
// truncate end of lines @todo havent validated this code or used it?
|
||||||
if (isset($pageflags['tru']) && substr($this->content,$posn,40-$x) === str_repeat(' ',40-$x)) {
|
if (isset($pageflags['tru']) && substr($content,$posn,$width-$x) === str_repeat(' ',$width-$x)) {
|
||||||
$output .= CR . LF;
|
$output .= CR.LF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,11 +13,23 @@ use App\Models\Frame as FrameModel;
|
|||||||
use App\Models\Mode;
|
use App\Models\Mode;
|
||||||
|
|
||||||
abstract class Server {
|
abstract class Server {
|
||||||
private $mo = NULL; // Our Mode object
|
// Our Mode object, this determines if we are an ANSI or VIDEOTEX server
|
||||||
private $co = NULL;
|
private $mo = NULL;
|
||||||
protected $blp = 0; // Size of Bottom Line Pollution
|
|
||||||
protected $baseline = ''; // Whats on the baseline currently
|
// The client connection object of the currently connected client.
|
||||||
protected $pid = NULL; // Client PID
|
public $co = NULL;
|
||||||
|
|
||||||
|
// The currently rendered Frame to the client of Frame/*
|
||||||
|
public $fo = NULL;
|
||||||
|
|
||||||
|
// Size of Bottom Line Pollution
|
||||||
|
protected $blp = 0;
|
||||||
|
|
||||||
|
// Whats on the baseline currently
|
||||||
|
protected $baseline = '';
|
||||||
|
|
||||||
|
// Client PID
|
||||||
|
protected $pid = NULL;
|
||||||
|
|
||||||
public function __construct(Mode $o)
|
public function __construct(Mode $o)
|
||||||
{
|
{
|
||||||
@ -31,6 +43,7 @@ abstract class Server {
|
|||||||
define('MODE_RFSENT', 6);
|
define('MODE_RFSENT', 6);
|
||||||
define('MODE_RFERROR', 7);
|
define('MODE_RFERROR', 7);
|
||||||
define('MODE_RFNOTSENT', 8);
|
define('MODE_RFNOTSENT', 8);
|
||||||
|
define('MODE_CONTROL', 9); // Do nothing, a method is controlling input
|
||||||
|
|
||||||
define('ACTION_RELOAD', 1);
|
define('ACTION_RELOAD', 1);
|
||||||
define('ACTION_GOTO', 2);
|
define('ACTION_GOTO', 2);
|
||||||
@ -40,16 +53,11 @@ abstract class Server {
|
|||||||
define('ACTION_TERMINATE', 6);
|
define('ACTION_TERMINATE', 6);
|
||||||
define('ACTION_SUBMITRF', 7); // Offer to submit a response frame
|
define('ACTION_SUBMITRF', 7); // Offer to submit a response frame
|
||||||
define('ACTION_STAR', 8);
|
define('ACTION_STAR', 8);
|
||||||
|
define('ACTION_EDIT', 9); // Edit current frame
|
||||||
|
|
||||||
define('CONTROL_TELNET', 1); // Telnet session control
|
define('CONTROL_TELNET', 1); // Telnet session control
|
||||||
define('CONTROL_METHOD', 2); // Send input to an external method
|
define('CONTROL_METHOD', 2); // Send input to an external method
|
||||||
|
define('CONTROL_EDIT', 3); // Controller to edit frame
|
||||||
// Keyboard presses
|
|
||||||
define('KEY_DELETE', chr(8));
|
|
||||||
define('KEY_LEFT', chr(136));
|
|
||||||
define('KEY_RIGHT', chr(137));
|
|
||||||
define('KEY_DOWN', chr(138));
|
|
||||||
define('KEY_UP', chr(139));
|
|
||||||
|
|
||||||
define('TCP_IAC', chr(255));
|
define('TCP_IAC', chr(255));
|
||||||
define('TCP_DONT', chr(254));
|
define('TCP_DONT', chr(254));
|
||||||
@ -67,11 +75,12 @@ abstract class Server {
|
|||||||
define('TCP_OPT_WINDOWSIZE', chr(31));
|
define('TCP_OPT_WINDOWSIZE', chr(31));
|
||||||
define('TCP_OPT_LINEMODE', chr(34));
|
define('TCP_OPT_LINEMODE', chr(34));
|
||||||
|
|
||||||
|
// Status messages
|
||||||
define('MSG_SENDORNOT', GREEN.'KEY 1 TO SEND, 2 NOT TO SEND');
|
define('MSG_SENDORNOT', GREEN.'KEY 1 TO SEND, 2 NOT TO SEND');
|
||||||
define('MSG_SENT', GREEN.'MESSAGE SENT - KEY '.HASH.' TO CONTINUE');
|
define('MSG_SENT', GREEN.'MESSAGE SENT - KEY '.HASH.' TO CONTINUE');
|
||||||
define('MSG_NOTSENT', GREEN.'MESSAGE NOT SENT - KEY '.HASH.' TO CONTINUE');
|
define('MSG_NOTSENT', GREEN.'MESSAGE NOT SENT - KEY '.HASH.' TO CONTINUE');
|
||||||
|
|
||||||
define('ERR_DATABASE', RED.'UNAVAILABLE AT PRESENT - PLSE TRY LATER');
|
define('ERR_DATABASE', RED.'UNAVAILABLE AT PRESENT - PLS TRY LATER');
|
||||||
define('ERR_NOTSENT', WHITE.'MESSAGE NOT SENT DUE TO AN ERROR');
|
define('ERR_NOTSENT', WHITE.'MESSAGE NOT SENT DUE TO AN ERROR');
|
||||||
define('ERR_PRIVATE', WHITE.'PRIVATE PAGE'.GREEN.'- FOR EXPLANATION *37'.HASH.'..');
|
define('ERR_PRIVATE', WHITE.'PRIVATE PAGE'.GREEN.'- FOR EXPLANATION *37'.HASH.'..');
|
||||||
define('ERR_ROUTE', WHITE.'MISTAKE?'.GREEN.'TRY AGAIN OR TELL US ON *08');
|
define('ERR_ROUTE', WHITE.'MISTAKE?'.GREEN.'TRY AGAIN OR TELL US ON *08');
|
||||||
@ -84,11 +93,13 @@ abstract class Server {
|
|||||||
define('MSG_TIMEWARP', WHITE.'OTHER VERSIONS EXIST'.GREEN.'KEY *02 TO VIEW');
|
define('MSG_TIMEWARP', WHITE.'OTHER VERSIONS EXIST'.GREEN.'KEY *02 TO VIEW');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function client()
|
/**
|
||||||
{
|
* Write something to the system log.
|
||||||
return $this->co;
|
*
|
||||||
}
|
* @param string $mode
|
||||||
|
* @param string $message
|
||||||
|
* @param array $data
|
||||||
|
*/
|
||||||
public function log(string $mode,string $message,array $data=[])
|
public function log(string $mode,string $message,array $data=[])
|
||||||
{
|
{
|
||||||
Log::$mode(sprintf('%s: %s',$this->pid,$message),$data);
|
Log::$mode(sprintf('%s: %s',$this->pid,$message),$data);
|
||||||
@ -111,7 +122,9 @@ abstract class Server {
|
|||||||
elseif ($pid)
|
elseif ($pid)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
$fo = NULL;
|
// The next page we will load - this should have frame=,index=
|
||||||
|
$next_page = NULL;
|
||||||
|
|
||||||
$this->co = $client;
|
$this->co = $client;
|
||||||
$this->pid = getmypid();
|
$this->pid = getmypid();
|
||||||
$this->log('info','Connection from: ',['client'=>$client->getAddress(),'server'=>$this->mo->name]);
|
$this->log('info','Connection from: ',['client'=>$client->getAddress(),'server'=>$this->mo->name]);
|
||||||
@ -136,7 +149,6 @@ abstract class Server {
|
|||||||
$action = ACTION_GOTO; // Initial action.
|
$action = ACTION_GOTO; // Initial action.
|
||||||
$control = FALSE; // Logic in control
|
$control = FALSE; // Logic in control
|
||||||
$mode = FALSE; // Current mode.
|
$mode = FALSE; // Current mode.
|
||||||
$save = FALSE; //
|
|
||||||
$cmd = ''; // Current *command being typed in
|
$cmd = ''; // Current *command being typed in
|
||||||
$user = new User; // The logged in user
|
$user = new User; // The logged in user
|
||||||
$method = collect(); // Method in control for CONTROL_METHOD
|
$method = collect(); // Method in control for CONTROL_METHOD
|
||||||
@ -147,19 +159,28 @@ abstract class Server {
|
|||||||
$current['fieldpos'] = 0; // For current field, position within.
|
$current['fieldpos'] = 0; // For current field, position within.
|
||||||
$current['prevmode'] = FALSE; // Previous mode - in case we need to go back to MODE_FIELD
|
$current['prevmode'] = FALSE; // Previous mode - in case we need to go back to MODE_FIELD
|
||||||
|
|
||||||
|
$fielddata = [];
|
||||||
|
|
||||||
// @todo Get the login/start page, and if it is not available, throw the ERR_DATEBASE error.
|
// @todo Get the login/start page, and if it is not available, throw the ERR_DATEBASE error.
|
||||||
if (isset($config['loginpage'])) {
|
if (isset($config['loginpage'])) {
|
||||||
$page = ['frame'=>$config['loginpage']];
|
$next_page = ['frame'=>$config['loginpage']];
|
||||||
} else if (!empty($service['start_page'])) {
|
} else if (!empty($service['start_page'])) {
|
||||||
$page = ['frame'=>$service['start_page']];
|
$next_page = ['frame'=>$service['start_page']];
|
||||||
} else {
|
} else {
|
||||||
$page = ['frame'=>'980']; // next page
|
$next_page = ['frame'=>'980']; // Default Login Page
|
||||||
}
|
}
|
||||||
|
|
||||||
while ($action != ACTION_TERMINATE) {
|
while ($action != ACTION_TERMINATE) {
|
||||||
// Read a character from the client session
|
// Read a character from the client session
|
||||||
|
// @todo Add a timeout to read, and log user off if timeout exceeded.
|
||||||
$read = $client->read(1);
|
$read = $client->read(1);
|
||||||
printf(". Got: %s (%s): Mode: [%s], Action: [%s], Control: [%s]\n",$read,ord($read),$mode,$action,$control);
|
echo "\n";
|
||||||
|
printf(". Got: %s (%s): Mode: [%s], Action: [%s], Control: [%s]\n",
|
||||||
|
(ord($read) < 32 ? '.' : $read),
|
||||||
|
ord($read),
|
||||||
|
serialize($mode),
|
||||||
|
serialize($action),
|
||||||
|
$control);
|
||||||
|
|
||||||
// It appears that read will return '' instead of false when a disconnect has occurred.
|
// It appears that read will return '' instead of false when a disconnect has occurred.
|
||||||
// We'll set it to NULL so its caught later
|
// We'll set it to NULL so its caught later
|
||||||
@ -174,17 +195,15 @@ abstract class Server {
|
|||||||
$control = CONTROL_TELNET;
|
$control = CONTROL_TELNET;
|
||||||
|
|
||||||
// Remember our Telnet Session Object
|
// Remember our Telnet Session Object
|
||||||
// @todo We might need to clear out the old mode/action states
|
if (! $session)
|
||||||
if (! $session) {
|
|
||||||
$session = Control::factory('telnet',$this);
|
$session = Control::factory('telnet',$this);
|
||||||
}
|
|
||||||
|
|
||||||
$method->push($session);
|
$method->push($session);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($control AND $method->count()) {
|
if ($control AND $method->count()) {
|
||||||
printf("= Control going to method: %s\n", get_class($method->last()));
|
printf("= Start CONTROL: Going to method: %s\n",get_class($method->last()));
|
||||||
|
|
||||||
// Capture our state when we enter this method.
|
// Capture our state when we enter this method.
|
||||||
if (! array_key_exists('control',$method->last()->state)) {
|
if (! array_key_exists('control',$method->last()->state)) {
|
||||||
@ -200,7 +219,7 @@ abstract class Server {
|
|||||||
$mode = $method->last()->state['mode'];
|
$mode = $method->last()->state['mode'];
|
||||||
|
|
||||||
if ($method->last()->complete()) {
|
if ($method->last()->complete()) {
|
||||||
printf("- Control complete: %s\n",get_class($method->last()));
|
printf("- Complete CONTROL: %s\n",get_class($method->last()));
|
||||||
$save = $method->pop();
|
$save = $method->pop();
|
||||||
|
|
||||||
if ($method->count()) {
|
if ($method->count()) {
|
||||||
@ -214,28 +233,34 @@ abstract class Server {
|
|||||||
|
|
||||||
dump(sprintf('End: Control is now: %s: Method Count: %s',is_object($control) ? get_class($control) : serialize($control),$method->count()));
|
dump(sprintf('End: Control is now: %s: Method Count: %s',is_object($control) ? get_class($control) : serialize($control),$method->count()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("- End CONTROL: Read %s (%s): Mode: [%s], Action: [%s], Control: [%s]\n",
|
||||||
|
(ord($read) < 32 ? '.' : $read),
|
||||||
|
ord($read),
|
||||||
|
serialize($mode),
|
||||||
|
serialize($action),
|
||||||
|
$control);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("- End Control: Read %s (%s): Mode: [%s], Action: [%s], Control: [%s]\n",$read,ord($read),$mode,$action,$control);
|
printf("= Start MODE: %s\n",serialize($mode));
|
||||||
|
|
||||||
switch ($mode) {
|
switch ($mode) {
|
||||||
// Key presses during field input.
|
// Key presses during field input.
|
||||||
case MODE_FIELD:
|
case MODE_FIELD:
|
||||||
$cmd = '';
|
$cmd = '';
|
||||||
$action = FALSE;
|
$action = FALSE;
|
||||||
|
|
||||||
switch ($fo->type()) {
|
switch ($this->fo->type()) {
|
||||||
// Login frame.
|
// Login frame.
|
||||||
case Frame::FRAMETYPE_LOGIN:
|
case Frame::FRAMETYPE_LOGIN:
|
||||||
switch ($read) {
|
switch ($read) {
|
||||||
case HASH:
|
case HASH:
|
||||||
// If we are the main login screen, see if it is a new user
|
// If we are the main login screen, see if it is a new user
|
||||||
if ($fo->isCUG(0))
|
if ($this->fo->isCUG(0))
|
||||||
{
|
{
|
||||||
if ($current['field']->type == 't' AND array_get($fielddata,$current['fieldnum']) == 'NEW')
|
if ($current['field']->type == 't' AND array_get($fielddata,$current['fieldnum']) == 'NEW')
|
||||||
{
|
{
|
||||||
$action = ACTION_GOTO;
|
$action = ACTION_GOTO;
|
||||||
$page = ['frame'=>'981']; // @todo This should be in the DB.
|
$next_page = ['frame'=>'981']; // @todo This should be in the DB.
|
||||||
|
|
||||||
break 2;
|
break 2;
|
||||||
}
|
}
|
||||||
@ -254,13 +279,13 @@ abstract class Server {
|
|||||||
$current['fieldnum']++;
|
$current['fieldnum']++;
|
||||||
$current['fieldpos'] = 0;
|
$current['fieldpos'] = 0;
|
||||||
|
|
||||||
if ($current['fieldnum'] < $fo->fields->count()) {
|
if ($current['fieldnum'] < $this->fo->fields()->count()) {
|
||||||
$current['fieldnum'] = $fo->getFieldId('edit',$current['fieldnum']);
|
$current['fieldnum'] = $this->fo->getFieldId('edit',$current['fieldnum']);
|
||||||
|
|
||||||
if ($current['fieldnum'] !== FALSE) {
|
if ($current['fieldnum'] !== FALSE) {
|
||||||
$current['field'] = $fo->getField($current['fieldnum']);
|
$current['field'] = $this->fo->getField($current['fieldnum']);
|
||||||
|
|
||||||
$client->send($this->outputPosition($current['field']->x,$current['field']->y).CON);
|
$client->send($this->moveCursor($current['field']->x,$current['field']->y).CON);
|
||||||
$mode = MODE_FIELD;
|
$mode = MODE_FIELD;
|
||||||
|
|
||||||
// There were no (more) editable fields.
|
// There were no (more) editable fields.
|
||||||
@ -288,7 +313,7 @@ abstract class Server {
|
|||||||
if ($current['fieldpos'])
|
if ($current['fieldpos'])
|
||||||
{
|
{
|
||||||
$current['fieldpos']--;
|
$current['fieldpos']--;
|
||||||
$client->send(LEFT.$fo::$if_filler.LEFT);
|
$client->send(LEFT.$this->fo::$if_filler.LEFT);
|
||||||
$fielddata[$current['fieldnum']] = substr($fielddata[$current['fieldnum']],0,-1);
|
$fielddata[$current['fieldnum']] = substr($fielddata[$current['fieldnum']],0,-1);
|
||||||
$current['fielddata'][$current['fieldnum']] = substr($current['fielddata'][$current['fieldnum']],0,-1);
|
$current['fielddata'][$current['fieldnum']] = substr($current['fielddata'][$current['fieldnum']],0,-1);
|
||||||
}
|
}
|
||||||
@ -332,7 +357,7 @@ abstract class Server {
|
|||||||
$current['fieldpos'] = (($current['fieldpos'] + $current['field']->x) % 40) * 40;
|
$current['fieldpos'] = (($current['fieldpos'] + $current['field']->x) % 40) * 40;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
$client->send($this->outputPosition($current['field']->x,$current['field']->y).CON);
|
$client->send($this->moveCursor($current['field']->x,$current['field']->y).CON);
|
||||||
$current['fieldpos'] = 0;
|
$current['fieldpos'] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -354,7 +379,7 @@ abstract class Server {
|
|||||||
|
|
||||||
$current['fieldpos']++;
|
$current['fieldpos']++;
|
||||||
|
|
||||||
$client->send($fo->isFieldMasked($current['field']->type) ?: $read);
|
$client->send($this->fo->isFieldMasked($current['field']->type) ?: $read);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,7 +389,7 @@ abstract class Server {
|
|||||||
default:
|
default:
|
||||||
$client->close();
|
$client->close();
|
||||||
|
|
||||||
throw new \Exception('Shouldnt get here', 500);
|
throw new \Exception('Shouldnt get here',500);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -372,29 +397,32 @@ abstract class Server {
|
|||||||
// Form submission: 1 to send, 2 not to send.
|
// Form submission: 1 to send, 2 not to send.
|
||||||
case MODE_SUBMITRF:
|
case MODE_SUBMITRF:
|
||||||
switch ($read) {
|
switch ($read) {
|
||||||
// @todo Input received, process it.
|
|
||||||
case '1':
|
case '1':
|
||||||
$route = $fo->route(1);
|
|
||||||
|
|
||||||
// If we are in a control method, complete it
|
// If we are in a control method, complete it
|
||||||
if ($control AND $method->count()) {
|
if ($control AND $method->count()) {
|
||||||
$method->last()->process();
|
$method->last()->process();
|
||||||
|
|
||||||
} elseif ($route == '*' OR is_numeric($route)) {
|
} elseif ($this->fo->route(1) == '*' OR is_numeric($this->fo->route(1))) {
|
||||||
$this->sendBaseline($client,RED.'NO ACTION PERFORMED');
|
$this->sendBaseline($client,RED.'NO ACTION PERFORMED');
|
||||||
$mode = MODE_RFSENT;
|
$mode = MODE_RFSENT;
|
||||||
|
|
||||||
} elseif ($ao = FrameClass\Action::factory($fo->route(1),$this,$user,$action,$mode)) {
|
} elseif ($ao = FrameClass\Action::factory($this->fo->route(1),$this,$user,$action,$mode)) {
|
||||||
$ao->handle($fielddata);
|
$ao->handle($fielddata);
|
||||||
$mode = $ao->mode;
|
$mode = $ao->mode;
|
||||||
$action = $ao->action;
|
$action = $ao->action;
|
||||||
$user = $ao->uo;
|
|
||||||
|
// Is this a user logging in?
|
||||||
|
if ($ao->uo->exists AND $ao instanceof FrameClass\Action\Login)
|
||||||
|
{
|
||||||
|
$user = $ao->uo;
|
||||||
|
$history = collect();
|
||||||
|
}
|
||||||
|
|
||||||
if ($ao->page)
|
if ($ao->page)
|
||||||
$page = $ao->page;
|
$next_page = $ao->page;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
$this->sendBaseline($client, RED.'NO method exists...');
|
$this->sendBaseline($client,RED.'NO method exists...');
|
||||||
|
|
||||||
$mode = MODE_RFSENT;
|
$mode = MODE_RFSENT;
|
||||||
}
|
}
|
||||||
@ -434,18 +462,18 @@ abstract class Server {
|
|||||||
$client->send(COFF);
|
$client->send(COFF);
|
||||||
|
|
||||||
if ($read == HASH) {
|
if ($read == HASH) {
|
||||||
if ($route = $fo->route(2) AND $route !== '*' AND is_numeric($route)) {
|
if ($x = $this->fo->route(2) AND $x !== '*' AND is_numeric($x)) {
|
||||||
$page = ['frame'=>$route];
|
$next_page = ['frame'=>$x];
|
||||||
|
|
||||||
} elseif (FrameModel::where('frame',$fo->frame())->where('index',$fo->index_next())->exists()) {
|
} elseif (FrameModel::where('frame',$this->fo->frame())->where('index',$this->fo->index_next())->exists()) {
|
||||||
$page = ['frame'=>$fo->frame(),'index'=>$fo->index_next()];
|
$next_page = ['frame'=>$this->fo->frame(),'index'=>$this->fo->index_next()];
|
||||||
|
|
||||||
} elseif ($route = $fo->route(0) AND $route !== '*' AND is_numeric($route)) {
|
} elseif ($x = $this->fo->route(0) AND $x !== '*' AND is_numeric($x)) {
|
||||||
$page = ['frame'=>$route];
|
$next_page = ['frame'=>$x];
|
||||||
|
|
||||||
// No further routes defined, go home.
|
// No further routes defined, go home.
|
||||||
} else {
|
} else {
|
||||||
$page = ['frame'=>0];
|
$next_page = ['frame'=>0];
|
||||||
}
|
}
|
||||||
|
|
||||||
$action = ACTION_GOTO;
|
$action = ACTION_GOTO;
|
||||||
@ -461,23 +489,23 @@ abstract class Server {
|
|||||||
// Response form after NOT sending
|
// Response form after NOT sending
|
||||||
case MODE_RFNOTSENT:
|
case MODE_RFNOTSENT:
|
||||||
|
|
||||||
// Response form ERROR
|
// Response form ERROR
|
||||||
case MODE_RFERROR:
|
case MODE_RFERROR:
|
||||||
$client->send(COFF);
|
$client->send(COFF);
|
||||||
|
|
||||||
if ($read == HASH) {
|
if ($read == HASH) {
|
||||||
if ($route = $fo->route(2) AND $route !== '*' AND is_numeric($route)) {
|
if ($x = $this->fo->route(2) AND $x !== '*' AND is_numeric($x)) {
|
||||||
$page = ['frame'=>$route];
|
$next_page = ['frame'=>$x];
|
||||||
|
|
||||||
} elseif (FrameModel::where('frame',$fo->frame())->where('index',$fo->index_next())->exists()) {
|
} elseif (FrameModel::where('frame',$this->fo->frame())->where('index',$this->fo->index_next())->exists()) {
|
||||||
$page = ['frame'=>$fo->frame(),'index'=>$fo->index_next()];
|
$next_page = ['frame'=>$this->fo->frame(),'index'=>$this->fo->index_next()];
|
||||||
|
|
||||||
} elseif ($route = $fo->route(0) AND $route !== '*' AND is_numeric($route)) {
|
} elseif ($x = $this->fo->route(0) AND $x !== '*' AND is_numeric($x)) {
|
||||||
$page = ['frame'=>$route];
|
$next_page = ['frame'=>$x];
|
||||||
|
|
||||||
// No further routes defined, go home.
|
// No further routes defined, go home.
|
||||||
} else {
|
} else {
|
||||||
$page = ['frame'=>0];
|
$next_page = ['frame'=>0];
|
||||||
}
|
}
|
||||||
|
|
||||||
$action = ACTION_GOTO;
|
$action = ACTION_GOTO;
|
||||||
@ -528,8 +556,8 @@ abstract class Server {
|
|||||||
case '7':
|
case '7':
|
||||||
case '8':
|
case '8':
|
||||||
case '9':
|
case '9':
|
||||||
if (is_numeric($fo->route($read))) {
|
if (is_numeric($this->fo->route($read))) {
|
||||||
$page = ['frame'=>$fo->route($read),'index'=>'a'];
|
$next_page = ['frame'=>$this->fo->route($read)];
|
||||||
|
|
||||||
$action = ACTION_GOTO;
|
$action = ACTION_GOTO;
|
||||||
|
|
||||||
@ -548,10 +576,18 @@ abstract class Server {
|
|||||||
echo "- Waiting for Page Number\n";
|
echo "- Waiting for Page Number\n";
|
||||||
|
|
||||||
// if it's a number, continue entry
|
// if it's a number, continue entry
|
||||||
if (strpos('0123456789', $read) !== FALSE) {
|
if (strpos('0123456789',$read) !== FALSE) {
|
||||||
$cmd .= $read;
|
|
||||||
$client->send($read);
|
$client->send($read);
|
||||||
$this->blp++;
|
$this->blp++;
|
||||||
|
$cmd .= $read;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If its a backspace, delete last input
|
||||||
|
if ($read === KEY_DELETE AND strlen($cmd))
|
||||||
|
{
|
||||||
|
$client->send(BS.' '.BS);
|
||||||
|
$this->blp--;
|
||||||
|
$cmd = substr($cmd,0,-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we hit a special numeric command, deal with it.
|
// if we hit a special numeric command, deal with it.
|
||||||
@ -569,7 +605,7 @@ abstract class Server {
|
|||||||
if ($cmd === '01') {
|
if ($cmd === '01') {
|
||||||
$client->send(COFF);
|
$client->send(COFF);
|
||||||
$timewarp = !$timewarp;
|
$timewarp = !$timewarp;
|
||||||
$this->sendBaseline($client, ($timewarp ? MSG_TIMEWARP_ON : MSG_TIMEWARP_OFF));
|
$this->sendBaseline($client,($timewarp ? MSG_TIMEWARP_ON : MSG_TIMEWARP_OFF));
|
||||||
$cmd = '';
|
$cmd = '';
|
||||||
$action = $mode = FALSE;
|
$action = $mode = FALSE;
|
||||||
|
|
||||||
@ -586,9 +622,22 @@ abstract class Server {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Edit frame
|
||||||
|
// Catch if we are going to edit a child frame
|
||||||
|
if (preg_match('/^04/',$cmd) AND preg_match('/^[a-z]$/',$read))
|
||||||
|
{
|
||||||
|
$client->send(COFF);
|
||||||
|
$next_page = ['frame'=>substr($cmd,2),'index'=>$read];
|
||||||
|
$cmd = '';
|
||||||
|
|
||||||
|
$action = ACTION_EDIT;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Bookmark page
|
// Bookmark page
|
||||||
if ($cmd === '05') {
|
if ($cmd === '05') {
|
||||||
$this->sendBaseline($client, RED.'NOT IMPLEMENTED YET?');
|
$this->sendBaseline($client,RED.'NOT IMPLEMENTED YET?');
|
||||||
$mode = FALSE;
|
$mode = FALSE;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -596,7 +645,7 @@ abstract class Server {
|
|||||||
|
|
||||||
// Report a problem
|
// Report a problem
|
||||||
if ($cmd === '08') {
|
if ($cmd === '08') {
|
||||||
$this->sendBaseline($client, RED.'NOT IMPLEMENTED YET?');
|
$this->sendBaseline($client,RED.'NOT IMPLEMENTED YET?');
|
||||||
$mode = FALSE;
|
$mode = FALSE;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -607,6 +656,7 @@ abstract class Server {
|
|||||||
$client->send(COFF);
|
$client->send(COFF);
|
||||||
$action = ACTION_GOTO;
|
$action = ACTION_GOTO;
|
||||||
$cmd = '';
|
$cmd = '';
|
||||||
|
$next_page = $this->fo->page(TRUE);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -622,8 +672,8 @@ abstract class Server {
|
|||||||
$current['prevmode'] = FALSE;
|
$current['prevmode'] = FALSE;
|
||||||
|
|
||||||
// @todo The cursor color could be wrong
|
// @todo The cursor color could be wrong
|
||||||
$client->send($this->outputPosition($current['field']->x,$current['field']->y).CON);
|
$client->send($this->moveCursor($current['field']->x,$current['field']->y).CON);
|
||||||
$client->send(str_repeat($fo::$if_filler, $current['field']->length));
|
$client->send(str_repeat($this->fo::$if_filler,$current['field']->length));
|
||||||
$current['fieldreset'] = TRUE;
|
$current['fieldreset'] = TRUE;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -638,18 +688,36 @@ abstract class Server {
|
|||||||
$client->send(COFF);
|
$client->send(COFF);
|
||||||
$timewarpalt = FALSE;
|
$timewarpalt = FALSE;
|
||||||
|
|
||||||
|
// If input is in a control, terminate it
|
||||||
|
if ($control)
|
||||||
|
{
|
||||||
|
$method->pop();
|
||||||
|
$control = FALSE;
|
||||||
|
|
||||||
|
// Our method count should be zero
|
||||||
|
if ($method->count())
|
||||||
|
dd($method);
|
||||||
|
}
|
||||||
|
|
||||||
// Nothing typed between * and #
|
// Nothing typed between * and #
|
||||||
// *# means go back
|
// *# means go back
|
||||||
if ($cmd === '') {
|
if ($cmd === '') {
|
||||||
$action = ACTION_BACKUP;
|
$action = ACTION_BACKUP;
|
||||||
|
|
||||||
} elseif ($cmd === '0') {
|
} elseif ($cmd === '0') {
|
||||||
$page = $user->exists ? ['frame'=>1,'index'=>'a'] : ['frame'=>980,'index'=>'a']; // @todo Get from DB.
|
$next_page = ['frame'=>$user->exists ? 1 : 980]; // @todo Get from DB.
|
||||||
$action = ACTION_GOTO;
|
$action = ACTION_GOTO;
|
||||||
|
|
||||||
|
// Edit Frame
|
||||||
|
} elseif (preg_match('/^04/',$cmd)) {
|
||||||
|
$client->send(COFF);
|
||||||
|
$action = ACTION_EDIT;
|
||||||
|
$next_page = [
|
||||||
|
'frame' => substr($cmd,2) ?: $this->fo->frame(),
|
||||||
|
];
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
$page['frame'] = $cmd;
|
$next_page = ['frame'=>$cmd];
|
||||||
$page['index'] = 'a';
|
|
||||||
$action = ACTION_GOTO;
|
$action = ACTION_GOTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -661,17 +729,24 @@ abstract class Server {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Control is taking input
|
||||||
|
case MODE_CONTROL:
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
$this->log('debug','Not sure what we were doing?');
|
$this->log('debug','Not sure what we were doing?');
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
printf("- End Mode: Read %s (%s): Mode: [%s], Action: [%s], Control: [%s]\n",$read,ord($read),$mode,$action,$control);
|
printf("- End MODE: Read %s (%s): Mode: [%s], Action: [%s], Control: [%s]\n",
|
||||||
|
(ord($read) < 32 ? '.' : $read),
|
||||||
|
ord($read),
|
||||||
|
serialize($mode),
|
||||||
|
serialize($action),
|
||||||
|
$control);
|
||||||
|
}
|
||||||
|
|
||||||
// This section performs some action if it is deemed necessary
|
// This section performs some action if it is deemed necessary
|
||||||
if ($action) {
|
printf("= Start ACTION: %s\n",serialize($action));
|
||||||
printf("+ Performing action: %s\n",$action);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ($action) {
|
switch ($action) {
|
||||||
case ACTION_STAR:
|
case ACTION_STAR:
|
||||||
@ -679,7 +754,10 @@ abstract class Server {
|
|||||||
|
|
||||||
// If there is something on the baseline, lets preserve it
|
// If there is something on the baseline, lets preserve it
|
||||||
if ($this->blp)
|
if ($this->blp)
|
||||||
|
{
|
||||||
|
printf(". Preserving Baseline: %s\n",$this->baseline);
|
||||||
$current['baseline'] = $this->baseline;
|
$current['baseline'] = $this->baseline;
|
||||||
|
}
|
||||||
|
|
||||||
$this->sendBaseline($client,GREEN.STAR,TRUE);
|
$this->sendBaseline($client,GREEN.STAR,TRUE);
|
||||||
$client->send(CON);
|
$client->send(CON);
|
||||||
@ -696,6 +774,30 @@ abstract class Server {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Edit Frame
|
||||||
|
case ACTION_EDIT:
|
||||||
|
$this->log('debug','Editing frame:',[$next_page]);
|
||||||
|
|
||||||
|
$next_fo = NULL;
|
||||||
|
// If we are editing a different frame, load it
|
||||||
|
try {
|
||||||
|
$next_fo = $this->mo->framePage($next_page['frame'],array_get($next_page,'index','a'),$this);
|
||||||
|
|
||||||
|
} catch (ModelNotFoundException $e) {
|
||||||
|
$next_fo = $this->mo->frameNew($this,$next_page['frame'],$next_page['index']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$control = CONTROL_EDIT;
|
||||||
|
$method->push(Control::factory('editframe',$this,$next_fo));
|
||||||
|
$next_fo = NULL;
|
||||||
|
$method->last()->state['control'] = $control;
|
||||||
|
$method->last()->state['action'] = FALSE;
|
||||||
|
$method->last()->state['mode'] = MODE_FIELD;
|
||||||
|
$mode = MODE_CONTROL;
|
||||||
|
$action = FALSE;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
// GO Backwards
|
// GO Backwards
|
||||||
case ACTION_BACKUP:
|
case ACTION_BACKUP:
|
||||||
// Do we have anywhere to go, drop the current page from the history.
|
// Do we have anywhere to go, drop the current page from the history.
|
||||||
@ -716,116 +818,126 @@ abstract class Server {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$page = $history->last();
|
$next_page = $history->last();
|
||||||
|
|
||||||
$this->log('debug','Backing up to:',$page);
|
// If there is no next page, we'll refresh the current page.
|
||||||
|
if ($next_page)
|
||||||
|
$this->log('debug','Backing up to:',$next_page);
|
||||||
|
|
||||||
// Go to next index frame.
|
// Go to next index frame.
|
||||||
case ACTION_NEXT:
|
case ACTION_NEXT:
|
||||||
// We need this extra test in case we come from ACTION_BACKUP
|
// We need this extra test in case we come from ACTION_BACKUP
|
||||||
if ($action == ACTION_NEXT)
|
if ($action == ACTION_NEXT)
|
||||||
{
|
{
|
||||||
$current['page']['index'] = $fo->index();
|
$current['page']['index'] = $this->fo->index();
|
||||||
$page['index'] = $fo->index_next();
|
$next_page = ['frame'=>$this->fo->frame(),'index'=>$this->fo->index_next()];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look for requested page
|
// Look for requested page - charge for it to be loaded.
|
||||||
case ACTION_GOTO:
|
case ACTION_GOTO:
|
||||||
$current['frame'] = $fo;
|
if ($next_page OR $timewarpalt)
|
||||||
|
|
||||||
// If we wanted a "Searching..." message, this is where to put it.
|
|
||||||
try {
|
|
||||||
$fo = $timewarpalt
|
|
||||||
? $this->mo->frame(FrameModel::findOrFail($timewarpalt))
|
|
||||||
: $this->mo->frameLoad($page['frame'],array_get($page,'index','a'),$this);
|
|
||||||
|
|
||||||
$this->log('debug',sprintf('Fetched frame: %s (%s)',$fo->id(),$fo->page()));
|
|
||||||
|
|
||||||
} catch (ModelNotFoundException $e) {
|
|
||||||
$this->sendBaseline($client,ERR_PAGE);
|
|
||||||
$mode = $action = FALSE;
|
|
||||||
|
|
||||||
$fo = $current['frame'] ?: $this->mo->frame($this->testFrame());
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is there a user logged in
|
|
||||||
if ($user)
|
|
||||||
{
|
{
|
||||||
if ($fo->isFramePublic() AND $fo->isAccessible())
|
// If we wanted a "Searching..." message, this is where to put it.
|
||||||
{
|
try {
|
||||||
if ($fo->type() == Frame::FRAMETYPE_LOGIN AND $user->isMemberCUG($fo->getCUG()))
|
// Store our next frame in a temporary var while we determine if it can be displayed
|
||||||
{
|
$fo = $timewarpalt
|
||||||
$this->sendBaseline($client,ERR_USER_ALREADYMEMBER);
|
? $this->mo->frameID($timewarpalt)
|
||||||
$fo = $current['frame'];
|
: $this->mo->framePage($next_page['frame'],array_get($next_page,'index','a'),$this);
|
||||||
$page = $history->last();
|
|
||||||
$mode = $action = FALSE;
|
|
||||||
$this->log('debug',sprintf('Frame Denied - Already Member: %s (%s)',$fo->id(),$fo->page()));
|
|
||||||
|
|
||||||
break;
|
$this->log('debug',sprintf('Fetched frame: %s (%s)',$fo->id(),$fo->page()));
|
||||||
}
|
|
||||||
|
|
||||||
// If this is a login frame and the user is already a member.
|
} catch (ModelNotFoundException $e) {
|
||||||
} else {
|
// @todo Make sure parent frame exists, or display error
|
||||||
|
|
||||||
if (! $fo->isOwner($user))
|
|
||||||
{
|
|
||||||
if (! $fo->isAccessible())
|
|
||||||
{
|
|
||||||
$this->sendBaseline($client,ERR_PAGE);
|
|
||||||
$fo = $current['frame'];
|
|
||||||
$page = $history->last();
|
|
||||||
$mode = $action = FALSE;
|
|
||||||
$this->log('debug',sprintf('Frame Denied - In Accessible: %s (%s)',$fo->id(),$fo->page()));
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! $user->isMemberCUG($fo->getCUG()))
|
|
||||||
{
|
|
||||||
$this->sendBaseline($client, ERR_PRIVATE);
|
|
||||||
$fo = $current['frame'];
|
|
||||||
$page = $history->last();
|
|
||||||
$mode = $action = FALSE;
|
|
||||||
$this->log('debug',sprintf('Frame Denied - Not in CUG [%s]: %s (%s)',$fo->getCUG()->id,$fo->id(),$fo->page()));
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// Is this a public frame in CUG 0?
|
|
||||||
if (! $fo->isCUG(0) OR ! $fo->isFramePublic())
|
|
||||||
{
|
|
||||||
$this->sendBaseline($client,ERR_PAGE);
|
$this->sendBaseline($client,ERR_PAGE);
|
||||||
$mode = $action = FALSE;
|
$mode = $action = FALSE;
|
||||||
|
|
||||||
|
if (! $fo)
|
||||||
|
$fo = $this->mo->frameTest($this);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Is there a user logged in
|
||||||
|
if ($user)
|
||||||
|
{
|
||||||
|
if ($fo->isFramePublic() AND $fo->isAccessible())
|
||||||
|
{
|
||||||
|
if ($fo->type() == Frame::FRAMETYPE_LOGIN AND $user->isMemberCUG($fo->getCUG()))
|
||||||
|
{
|
||||||
|
$this->sendBaseline($client,ERR_USER_ALREADYMEMBER);
|
||||||
|
$next_page = $history->last();
|
||||||
|
$mode = $action = FALSE;
|
||||||
|
$this->log('debug',sprintf('Frame Denied - Already Member: %s (%s)',$fo->id(),$fo->page()));
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// If this is a login frame and the user is already a member.
|
||||||
|
} else {
|
||||||
|
if (! $fo->isOwner($user))
|
||||||
|
{
|
||||||
|
if (! $fo->isAccessible())
|
||||||
|
{
|
||||||
|
$this->sendBaseline($client,ERR_PAGE);
|
||||||
|
$next_page = $history->last();
|
||||||
|
$mode = $action = FALSE;
|
||||||
|
$this->log('debug',sprintf('Frame Denied - In Accessible: %s (%s)',$fo->id(),$fo->page()));
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! $user->isMemberCUG($fo->getCUG()))
|
||||||
|
{
|
||||||
|
$this->sendBaseline($client,ERR_PRIVATE);
|
||||||
|
$next_page = $history->last();
|
||||||
|
$mode = $action = FALSE;
|
||||||
|
$this->log('debug',sprintf('Frame Denied - Not in CUG [%s]: %s (%s)',$fo->getCUG()->id,$fo->id(),$fo->page()));
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Is this a public frame in CUG 0?
|
||||||
|
if (! $fo->isCUG(0) OR ! $fo->isFramePublic())
|
||||||
|
{
|
||||||
|
$this->sendBaseline($client,ERR_PAGE);
|
||||||
|
$next_page = $history->last();
|
||||||
|
$mode = $action = FALSE;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$current['page'] = $fo->page(TRUE);
|
|
||||||
$current['fieldpos'] = 0;
|
|
||||||
|
|
||||||
// Only if new location, not going backwards
|
// Only if new location, not going backwards
|
||||||
if (($history->last() != $page) AND ($action == ACTION_GOTO || $action == ACTION_NEXT)) {
|
if (($history->last() != $next_page) AND ($action == ACTION_GOTO || $action == ACTION_NEXT)) {
|
||||||
$history->push($page);
|
$history->push($next_page);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$current['fieldpos'] = 0;
|
||||||
|
$this->fo = $fo;
|
||||||
|
$fo = NULL;
|
||||||
|
$next_page = NULL;
|
||||||
|
$timewarpalt = NULL;
|
||||||
|
|
||||||
printf("+ Mode is: %s\n",$mode);
|
printf("+ Mode is: %s\n",$mode);
|
||||||
|
|
||||||
// drop into
|
// drop into
|
||||||
case ACTION_RELOAD:
|
case ACTION_RELOAD:
|
||||||
|
// Clear the baseline history
|
||||||
$this->sendBaseline($client,'');
|
$this->sendBaseline($client,'');
|
||||||
$output = (string)$fo;
|
$current['baseline'] = '';
|
||||||
|
|
||||||
|
$output = (string)$this->fo;
|
||||||
|
|
||||||
if ($timewarpalt) {
|
if ($timewarpalt) {
|
||||||
$this->sendBaseline($client,sprintf(MSG_TIMEWARP_TO,$fo->created() ? $fo->created()->format('Y-m-d H:i:s') : 'UNKNOWN'));
|
$this->sendBaseline($client,sprintf(MSG_TIMEWARP_TO,$this->fo->created() ? $this->fo->created()->format('Y-m-d H:i:s') : 'UNKNOWN'));
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ($fo->type()) {
|
switch ($this->fo->type()) {
|
||||||
default:
|
default:
|
||||||
// Standard Frame
|
// Standard Frame
|
||||||
case Frame::FRAMETYPE_INFO:
|
case Frame::FRAMETYPE_INFO:
|
||||||
@ -842,7 +954,7 @@ abstract class Server {
|
|||||||
|
|
||||||
// If this is the registration page
|
// If this is the registration page
|
||||||
// @todo Should be evaluated out of the DB
|
// @todo Should be evaluated out of the DB
|
||||||
if ($fo->page() == '981a') {
|
if ($this->fo->page() == '981a') {
|
||||||
$control = CONTROL_METHOD;
|
$control = CONTROL_METHOD;
|
||||||
$method->push(Control::factory('register',$this));
|
$method->push(Control::factory('register',$this));
|
||||||
$method->last()->state['control'] = $control;
|
$method->last()->state['control'] = $control;
|
||||||
@ -857,10 +969,10 @@ abstract class Server {
|
|||||||
$fielddata = [];
|
$fielddata = [];
|
||||||
$current['fielddata'] = [];
|
$current['fielddata'] = [];
|
||||||
|
|
||||||
if (count($fo->fields)) {
|
if ($this->fo->fields()->count()) {
|
||||||
// Get our first editable field.
|
// Get our first editable field.
|
||||||
$current['fieldnum'] = $fo->getFieldId('edit',0);
|
$current['fieldnum'] = $this->fo->getFieldId('edit',0);
|
||||||
$current['field'] = $fo->getField($current['fieldnum']);
|
$current['field'] = $this->fo->getField($current['fieldnum']);
|
||||||
$current['fieldreset'] = TRUE;
|
$current['fieldreset'] = TRUE;
|
||||||
|
|
||||||
if ($current['fieldnum'] !== FALSE) {
|
if ($current['fieldnum'] !== FALSE) {
|
||||||
@ -896,17 +1008,17 @@ abstract class Server {
|
|||||||
$cmd = '';
|
$cmd = '';
|
||||||
$y = 0;
|
$y = 0;
|
||||||
|
|
||||||
$output = $this->outputPosition(0, $y++) . WHITE . NEWBG . RED . 'TIMEWARP INFO FOR Pg.' . BLUE . $fo->page(). WHITE;
|
$output = $this->moveCursor(0,$y++).WHITE.NEWBG.RED.'TIMEWARP INFO FOR Pg.'.BLUE.$this->fo->page().WHITE;
|
||||||
//$output .= $this->outputPosition(0, $y++) . WHITE . NEWBG . BLUE . 'Service : ' . substr($service['service_name'] . str_repeat(' ', 27), 0, 27);
|
//$output .= $this->moveCursor(0,$y++).WHITE.NEWBG.BLUE.'Service : '.substr($service['service_name'].str_repeat(' ',27),0,27);
|
||||||
//$output .= $this->outputPosition(0, $y++) . WHITE . NEWBG . BLUE . 'Varient : ' . substr($varient['varient_name'] . str_repeat(' ', 27), 0, 27);
|
//$output .= $this->moveCursor(0,$y++).WHITE.NEWBG.BLUE.'Varient : '.substr($varient['varient_name'].str_repeat(' ',27),0,27);
|
||||||
$output .= $this->outputPosition(0, $y++) . WHITE . NEWBG . BLUE . 'Dated : ' .substr(($fo->created() ? $fo->created()->format('j F Y') : 'Unknown').str_repeat(' ', 27), 0, 27);
|
$output .= $this->moveCursor(0,$y++).WHITE.NEWBG.BLUE.'Dated : ' .substr(($this->fo->created() ? $this->fo->created()->format('j F Y') : 'Unknown').str_repeat(' ',27),0,27);
|
||||||
|
|
||||||
$alts = $fo->alts($this->mo)->get();
|
$alts = $this->fo->alts($this->mo)->get();
|
||||||
|
|
||||||
if (count($alts)) {
|
if (count($alts)) {
|
||||||
$n = 1;
|
$n = 1;
|
||||||
|
|
||||||
$output .= $this->outputPosition(0, $y++) . WHITE . NEWBG . RED . 'ALTERNATIVE VERSIONS:' . str_repeat(' ', 16);
|
$output .= $this->moveCursor(0,$y++).WHITE.NEWBG.RED.'ALTERNATIVE VERSIONS:'.str_repeat(' ',16);
|
||||||
|
|
||||||
foreach ($alts as $o) {
|
foreach ($alts as $o) {
|
||||||
$date = $o->created_at->format('d M Y');
|
$date = $o->created_at->format('d M Y');
|
||||||
@ -919,7 +1031,7 @@ abstract class Server {
|
|||||||
|
|
||||||
$line .= BLUE.$date.' '.$o->note;
|
$line .= BLUE.$date.' '.$o->note;
|
||||||
|
|
||||||
$output .= $this->outputPosition(0,$y++).$line.str_repeat(' ',40-$this->strlenv($line)); // @todo should use frame::page_length
|
$output .= $this->moveCursor(0,$y++).$line.str_repeat(' ',40-$this->fo->strlenv($line)); // @todo should use frame::page_length
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($timewarp) {
|
if ($timewarp) {
|
||||||
@ -933,11 +1045,16 @@ abstract class Server {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("- End Action: Read %s (%s): Mode: [%s], Action: [%s], Control: [%s]\n",$read,ord($read),$mode,$action,$control);
|
printf("- End ACTION: Read %s (%s): Mode: [%s], Action: [%s], Control: [%s]\n",
|
||||||
|
(ord($read) < 32 ? '.' : $read),
|
||||||
|
ord($read),
|
||||||
|
serialize($mode),
|
||||||
|
serialize($action),
|
||||||
|
$control);
|
||||||
|
|
||||||
// We need to reposition the cursor to the current field.
|
// We need to reposition the cursor to the current field.
|
||||||
if ($current['fieldreset'] !== FALSE) {
|
if ($current['fieldreset'] !== FALSE) {
|
||||||
$client->send($this->outputPosition($current['field']->x,$current['field']->y).CON);
|
$client->send($this->moveCursor($current['field']->x,$current['field']->y).CON);
|
||||||
$current['fieldreset'] = FALSE;
|
$current['fieldreset'] = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -962,7 +1079,7 @@ abstract class Server {
|
|||||||
/**
|
/**
|
||||||
* Move the cursor via the shortest path.
|
* Move the cursor via the shortest path.
|
||||||
*/
|
*/
|
||||||
abstract function outputPosition($x,$y);
|
abstract function moveCursor($x,$y);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a message to the base line
|
* Send a message to the base line
|
||||||
@ -973,20 +1090,4 @@ abstract class Server {
|
|||||||
* @param bool $reposition
|
* @param bool $reposition
|
||||||
*/
|
*/
|
||||||
abstract function sendBaseline($client,$text,$reposition=FALSE);
|
abstract function sendBaseline($client,$text,$reposition=FALSE);
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculate the length of text
|
|
||||||
*
|
|
||||||
* ESC characters are two chars, and need to be counted as one.
|
|
||||||
*
|
|
||||||
* @param $text
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
abstract function strlenv($text):int;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a test frame appropriate for this server.
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
abstract public function testFrame();
|
|
||||||
}
|
}
|
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
namespace App\Classes\Server;
|
namespace App\Classes\Server;
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Log;
|
|
||||||
|
|
||||||
use App\Classes\Server as AbstractServer;
|
use App\Classes\Server as AbstractServer;
|
||||||
use App\Models\Mode;
|
use App\Models\Mode;
|
||||||
|
|
||||||
@ -22,6 +20,7 @@ class Ansi extends AbstractServer {
|
|||||||
define('UP', ESC.'[A'); // Move Cursor
|
define('UP', ESC.'[A'); // Move Cursor
|
||||||
define('CR', chr(13));
|
define('CR', chr(13));
|
||||||
define('LF', chr(10));
|
define('LF', chr(10));
|
||||||
|
define('BS', chr(8));
|
||||||
define('CLS', ESC.'[2J');
|
define('CLS', ESC.'[2J');
|
||||||
define('HASH', '#'); // Enter
|
define('HASH', '#'); // Enter
|
||||||
define('STAR', '*'); // Star Entry
|
define('STAR', '*'); // Star Entry
|
||||||
@ -47,34 +46,32 @@ class Ansi extends AbstractServer {
|
|||||||
define('R_WHITE', WHITE);
|
define('R_WHITE', WHITE);
|
||||||
//define('FLASH',chr(8));
|
//define('FLASH',chr(8));
|
||||||
|
|
||||||
|
// Keyboard presses
|
||||||
|
// @todo Check where these are used vs the keys defined above?
|
||||||
|
define('KEY_DELETE', chr(8));
|
||||||
|
define('KEY_LEFT', chr(136));
|
||||||
|
define('KEY_RIGHT', chr(137));
|
||||||
|
define('KEY_DOWN', chr(138));
|
||||||
|
define('KEY_UP', chr(139));
|
||||||
|
|
||||||
parent::__construct($o);
|
parent::__construct($o);
|
||||||
}
|
}
|
||||||
|
|
||||||
function outputPosition($x,$y) {
|
function moveCursor($x,$y) {
|
||||||
|
printf(". Move cursor %s,%s\n",$x,$y);
|
||||||
return ESC.'['.$y.';'.$x.'f';
|
return ESC.'['.$y.';'.$x.'f';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Abstract function
|
// Abstract function
|
||||||
public function sendBaseline($client,$text,$reposition=FALSE) {
|
public function sendBaseline($client,$text,$reposition=FALSE) {
|
||||||
$client->send(CSAVE.ESC.'[24;0f'.$text.
|
$client->send(CSAVE.ESC.'[24;0f'.$text.
|
||||||
($this->blp > $this->strlenv($text)
|
($this->blp > $this->fo->strlenv($text)
|
||||||
? str_repeat(' ',$this->blp-$this->strlenv($text)).
|
? str_repeat(' ',$this->blp-$this->fo->strlenv($text)).
|
||||||
($reposition ? ESC.'[24;0f'.str_repeat(RIGHT,$this->strlenv($text)) : CRESTORE)
|
($reposition ? ESC.'[24;0f'.str_repeat(RIGHT,$this->fo->strlenv($text)) : CRESTORE)
|
||||||
: ($reposition ? '' : CRESTORE))
|
: ($reposition ? '' : CRESTORE))
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->blp = $this->strlenv($text);
|
$this->blp = $this->fo->strlenv($text);
|
||||||
$this->baseline = $text;
|
$this->baseline = $text;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Abstract function
|
|
||||||
public function strlenv($text):int {
|
|
||||||
return strlen($text ? preg_replace('/'.ESC.'\[[0-9;?]+[a-zA-Z]/','',$text) : $text);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Abstract function
|
|
||||||
public function testFrame()
|
|
||||||
{
|
|
||||||
return \App\Classes\Frame\Ansi::testFrame($this);
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -48,7 +48,7 @@ class Videotex extends AbstractServer {
|
|||||||
parent::__construct($o);
|
parent::__construct($o);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function outputPosition($x,$y) {
|
public function moveCursor($x,$y) {
|
||||||
// Take the shortest path.
|
// Take the shortest path.
|
||||||
if ($y < 12) {
|
if ($y < 12) {
|
||||||
return HOME.
|
return HOME.
|
||||||
@ -74,15 +74,4 @@ class Videotex extends AbstractServer {
|
|||||||
|
|
||||||
$this->blp = $this->strlenv($text);
|
$this->blp = $this->strlenv($text);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Abstract function
|
|
||||||
public function strlenv($text):int {
|
|
||||||
return strlen($text)-substr_count($text,ESC);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Abstract function
|
|
||||||
public function testFrame()
|
|
||||||
{
|
|
||||||
return \App\Classes\Frame\Videotex::testFrame($this);
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -20,6 +20,11 @@ class Mode extends Model
|
|||||||
return $this->hasMany(Frame::class);
|
return $this->hasMany(Frame::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function frameId(int $id)
|
||||||
|
{
|
||||||
|
return $this->frameLoad(Frame::findOrFail($id));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a frame class for the Model
|
* Return a frame class for the Model
|
||||||
*
|
*
|
||||||
@ -27,7 +32,7 @@ class Mode extends Model
|
|||||||
* @return FrameClass
|
* @return FrameClass
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function frame(Model $o): FrameClass
|
private function frameLoad(Model $o): FrameClass
|
||||||
{
|
{
|
||||||
switch (strtolower($this->name)) {
|
switch (strtolower($this->name)) {
|
||||||
case 'ansi':
|
case 'ansi':
|
||||||
@ -35,10 +40,28 @@ class Mode extends Model
|
|||||||
case 'videotex':
|
case 'videotex':
|
||||||
return new VideotexFrame($o);
|
return new VideotexFrame($o);
|
||||||
default:
|
default:
|
||||||
throw new \Exception('Unknown Frame type: '.$mo->name);
|
throw new \Exception('Unknown Frame type: '.$this->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function frameNew(Server $so,int $frame,string $index='a'): FrameClass
|
||||||
|
{
|
||||||
|
$o = new Frame;
|
||||||
|
$o->frame = $frame;
|
||||||
|
$o->index = $index;
|
||||||
|
$o->mode_id = $this->id;
|
||||||
|
|
||||||
|
// Make sure parent frame exists
|
||||||
|
// @todo make sure not trying to edit test frames
|
||||||
|
if ($o->index != 'a' AND ! FrameModel::where('frame',$fo->frame())->where('index',$fo->index_prev())->exists())
|
||||||
|
{
|
||||||
|
$so->sendBaseline($so->co,ERR_ROUTE);
|
||||||
|
return new Frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->frameLoad($o);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch a specific frame from the DB
|
* Fetch a specific frame from the DB
|
||||||
*
|
*
|
||||||
@ -48,17 +71,28 @@ class Mode extends Model
|
|||||||
* @return FrameClass
|
* @return FrameClass
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function frameLoad(int $frame,string $index,Server $so): FrameClass
|
public function framePage(int $frame,string $index='a',Server $so): FrameClass
|
||||||
{
|
{
|
||||||
return $this->frame(
|
return ($frame == '999' and $index == 'a')
|
||||||
// Return our internal test frame.
|
// Return our internal test frame.
|
||||||
($frame == '999' and $index == 'a')
|
? $this->frameTest($so)
|
||||||
? $so->testFrame()
|
: $this->frameLoad($this->frames()
|
||||||
: $this->frames()
|
->where('frame','=',$frame)
|
||||||
->where('frame','=',$frame)
|
->where('index','=',$index)
|
||||||
->where('index','=',$index)
|
->firstOrFail()
|
||||||
->firstOrFail()
|
);
|
||||||
);
|
}
|
||||||
|
|
||||||
|
public function frameTest(Server $so): FrameClass
|
||||||
|
{
|
||||||
|
switch (strtolower($this->name)) {
|
||||||
|
case 'ansi':
|
||||||
|
return AnsiFrame::testFrame($so);
|
||||||
|
case 'videotex':
|
||||||
|
return VideotexFrame::testFrame($so);
|
||||||
|
default:
|
||||||
|
throw new \Exception('Unknown Frame type: '.$this->name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -98,7 +98,7 @@ return [
|
|||||||
// otherwise you can them out of the configuration array
|
// otherwise you can them out of the configuration array
|
||||||
#'sslcert' => env('DB_SSLCERT', 'client.crt'),
|
#'sslcert' => env('DB_SSLCERT', 'client.crt'),
|
||||||
#'sslkey' => env('DB_SSLKEY', 'client.key'),
|
#'sslkey' => env('DB_SSLKEY', 'client.key'),
|
||||||
#'sslrootcert' => env('DB_SSLROOTCERT', 'ca.crt'),
|
'sslrootcert' => env('DB_SSLROOTCERT', 'ca.crt'),
|
||||||
],
|
],
|
||||||
|
|
||||||
],
|
],
|
||||||
|
Reference in New Issue
Block a user