2023-01-10 22:39:11 +00:00
< ? php
namespace DarksLight2\Training ;
use Core\Db ;
2023-01-18 11:43:45 +00:00
use DarksLight2\Training\Steps\ChatFirstStep ;
use DarksLight2\Training\Steps\MyUserFirstQuest ;
use DarksLight2\Training\Steps\MyUserFirstStep ;
use DarksLight2\Training\Steps\MyUserFourthQuest ;
use DarksLight2\Training\Steps\MyUserFourthStep ;
use DarksLight2\Training\Steps\MyUserSecondQuest ;
use DarksLight2\Training\Steps\MyUserSecondStep ;
use DarksLight2\Training\Steps\MyUserThirdQuest ;
use DarksLight2\Training\Steps\MyUserThirdStep ;
2023-01-10 22:39:11 +00:00
use DarksLight2\Traits\Singleton ;
2023-01-18 11:43:45 +00:00
use PassGen ;
2023-01-10 22:39:11 +00:00
use PDO ;
use stdClass ;
2023-01-18 11:43:45 +00:00
use User ;
2023-01-10 22:39:11 +00:00
class TrainingManager
{
use Singleton ;
private int $user_id ;
2023-01-18 11:43:45 +00:00
public string $current_step = '' ;
private array $registered_steps ;
private array $completed_steps ;
private array $active_steps ;
2023-01-10 22:39:11 +00:00
2023-01-18 11:43:45 +00:00
private $database ;
2023-01-10 22:39:11 +00:00
2023-01-18 11:43:45 +00:00
public function __construct ( int $user_id , $refresh_token = true )
2023-01-10 22:39:11 +00:00
{
2023-01-18 11:43:45 +00:00
try {
$this -> register ([
new ChatFirstStep (),
new MyUserFirstStep (),
new MyUserFirstQuest (),
new MyUserSecondStep (),
new MyUserSecondQuest (),
new MyUserThirdStep (),
new MyUserThirdQuest (),
new MyUserFourthStep (),
new MyUserFourthQuest (),
]);
} catch ( TrainingException $e ) {
2023-01-10 22:39:11 +00:00
}
2023-01-18 11:43:45 +00:00
$this -> user_id = $user_id ;
if ( $refresh_token ) {
$this -> generateToken ();
2023-01-10 22:39:11 +00:00
}
2023-01-18 11:43:45 +00:00
$this -> database = Db :: getRow ( 'SELECT * FROM user_training WHERE user_id = ?' , [ $user_id ]);
$this -> createDatabaseRecord ();
$this -> database [ 'data' ] = json_decode ( $this -> database [ 'data' ], true );
$this -> selectActiveSteps ();
2023-01-10 22:39:11 +00:00
}
2023-01-18 11:43:45 +00:00
public function getCurrentStepName () : string
2023-01-10 22:39:11 +00:00
{
2023-01-18 11:43:45 +00:00
if ( empty ( $this -> current_step )) {
$this -> current_step = array_key_first ( $this -> active_steps ) ? ? '' ;
2023-01-15 21:47:19 +00:00
}
2023-01-18 11:43:45 +00:00
return $this -> current_step ;
2023-01-15 21:47:19 +00:00
}
2023-01-18 11:43:45 +00:00
public function getRegistered () : array
2023-01-15 21:47:19 +00:00
{
2023-01-18 11:43:45 +00:00
return $this -> registered_steps ;
}
2023-01-15 21:47:19 +00:00
2023-01-18 11:43:45 +00:00
public function getDatabaseData ()
{
return $this -> database ;
}
2023-01-15 21:47:19 +00:00
2023-01-18 11:43:45 +00:00
public function addPoint ( $short_name , $closure = null )
{
if ( $short_name === $this -> getCurrentStepName ()) {
$this -> database [ 'data' ][ $short_name ][ 'progress' ][ 'current' ] ++ ;
if ( isset ( $closure )) {
$closure ( $this );
}
2023-01-15 21:47:19 +00:00
}
2023-01-10 22:39:11 +00:00
}
2023-01-18 11:43:45 +00:00
public function nextStep ()
2023-01-10 22:39:11 +00:00
{
2023-01-15 21:47:19 +00:00
2023-01-18 11:43:45 +00:00
if ( $this -> database [ 'data' ][ $this -> getCurrentStepName ()][ 'progress' ][ 'need' ] <= $this -> database [ 'data' ][ $this -> getCurrentStepName ()][ 'progress' ][ 'current' ]) {
$this -> database [ 'data' ][ $this -> getCurrentStepName ()][ 'progress' ][ 'current' ] = 0 ;
$this -> database [ 'data' ][ $this -> getCurrentStepName ()][ 'completed' ] = true ;
unset ( $this -> active_steps [ $this -> getCurrentStepName ()]);
$this -> current_step = array_key_first ( $this -> active_steps ) ? ? '' ;
$this -> database [ 'current' ] = $this -> getCurrentStepName ();
2023-01-10 22:39:11 +00:00
}
2023-01-18 11:43:45 +00:00
}
2023-01-10 22:39:11 +00:00
2023-01-18 11:43:45 +00:00
public function previousStep ()
{
$this -> current_step = end ( $this -> completed_steps ) ? ? '' ;
$this -> database [ 'current' ] = $this -> current_step ;
$this -> database [ 'data' ][ $this -> getCurrentStepName ()][ 'completed' ] = false ;
2023-01-10 22:39:11 +00:00
}
2023-01-18 11:43:45 +00:00
public function selectActiveSteps ()
2023-01-15 21:47:19 +00:00
{
2023-01-18 11:43:45 +00:00
foreach ( $this -> database [ 'data' ] as $step_name => $data ) {
if ( $data [ 'completed' ] === false ) {
$this -> active_steps [ $step_name ] = $data ;
continue ;
}
2023-01-15 21:47:19 +00:00
2023-01-18 11:43:45 +00:00
$this -> completed_steps [] = $step_name ;
2023-01-15 21:47:19 +00:00
}
}
2023-01-18 11:43:45 +00:00
public function store ()
2023-01-10 22:39:11 +00:00
{
2023-01-18 11:43:45 +00:00
Db :: sql ( 'UPDATE user_training SET data = ?, current = ? WHERE user_id = ?' , [ json_encode ( $this -> database [ 'data' ]), $this -> database [ 'current' ], $this -> user_id ]);
2023-01-10 22:39:11 +00:00
}
2023-01-18 11:43:45 +00:00
/**
* @ param StepFactory [] $steps
*
* @ return void
* @ throws \DarksLight2\Training\TrainingException
*/
public function register ( array $steps )
2023-01-10 22:39:11 +00:00
{
2023-01-18 11:43:45 +00:00
if ( ! empty ( $this -> steps )) {
throw TrainingException :: alreadyRegistered ();
2023-01-15 21:47:19 +00:00
}
2023-01-18 11:43:45 +00:00
foreach ( $steps as $step ) {
if ( $step instanceof StepFactory ) {
$this -> registered_steps [ $step -> getShortName ()] = $step ;
}
}
2023-01-15 21:47:19 +00:00
}
2023-01-18 11:43:45 +00:00
private function generateToken ( $length = 16 )
2023-01-10 22:39:11 +00:00
{
2023-01-18 11:43:45 +00:00
$token = PassGen :: new ( $length );
Db :: run ( 'UPDATE user_training SET api_token = ? WHERE user_id = ?' , [
$token ,
$this -> user_id
]);
2023-01-15 21:47:19 +00:00
}
2023-01-18 11:43:45 +00:00
public function createDatabaseRecord ()
2023-01-15 21:47:19 +00:00
{
2023-01-18 11:43:45 +00:00
if ( ! $this -> database ) {
$data = [];
foreach ( $this -> registered_steps as $step ) {
$data [ $step -> getShortName ()] = $step -> databaseRecord ();
2023-01-15 21:47:19 +00:00
}
2023-01-18 11:43:45 +00:00
Db :: sql ( 'INSERT INTO user_training (user_id, data, current) VALUES (?, ?, ?)' , [
$this -> user_id ,
json_encode ( $data , true ),
array_key_first ( $data )
]);
$this -> database = Db :: getRow ( 'SELECT * FROM user_training WHERE user_id = ?' , [ $this -> user_id ]);
2023-01-15 21:47:19 +00:00
}
2023-01-10 22:39:11 +00:00
}
2023-01-18 11:43:45 +00:00
/**
* @ throws \DarksLight2\Training\TrainingException
*/
public function render ()
2023-01-10 22:39:11 +00:00
{
2023-01-18 11:43:45 +00:00
if ( in_array ( User :: start () -> room [ 'file' ], $this -> registered_steps [ $this -> getCurrentStepName ()] -> onLocations ()) || in_array ( 'all' , $this -> registered_steps [ $this -> getCurrentStepName ()] -> onLocations ())) {
$path = $_SERVER [ 'DOCUMENT_ROOT' ] . '/modules_data/steps/step.php' ;
if ( file_exists ( $path )) {
$short_name = $this -> getCurrentStepName ();
$answer = $this -> registered_steps [ $this -> getCurrentStepName ()] -> getAnswer ();
require $path ;
return ;
}
2023-01-10 22:39:11 +00:00
2023-01-18 11:43:45 +00:00
throw TrainingException :: noRenderingFile ();
}
2023-01-10 22:39:11 +00:00
}
}