196 lines
5.7 KiB
PHP
196 lines
5.7 KiB
PHP
<?php
|
|
|
|
namespace DarksLight2\Training;
|
|
|
|
use Core\Db;
|
|
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;
|
|
use DarksLight2\Traits\Singleton;
|
|
use PassGen;
|
|
use PDO;
|
|
use stdClass;
|
|
use User;
|
|
|
|
class TrainingManager
|
|
{
|
|
use Singleton;
|
|
private int $user_id;
|
|
public string $current_step = '';
|
|
private array $registered_steps;
|
|
private array $completed_steps;
|
|
private array $active_steps;
|
|
|
|
private $database;
|
|
|
|
public function __construct(int $user_id, $refresh_token = true)
|
|
{
|
|
try {
|
|
$this->register([
|
|
new ChatFirstStep(),
|
|
new MyUserFirstStep(),
|
|
new MyUserFirstQuest(),
|
|
new MyUserSecondStep(),
|
|
new MyUserSecondQuest(),
|
|
new MyUserThirdStep(),
|
|
new MyUserThirdQuest(),
|
|
new MyUserFourthStep(),
|
|
new MyUserFourthQuest(),
|
|
]);
|
|
} catch (TrainingException $e) {
|
|
}
|
|
|
|
$this->user_id = $user_id;
|
|
|
|
if($refresh_token) {
|
|
$this->generateToken();
|
|
}
|
|
|
|
$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();
|
|
}
|
|
|
|
public function getCurrentStepName(): string
|
|
{
|
|
if(empty($this->current_step)) {
|
|
$this->current_step = array_key_first($this->active_steps) ?? '';
|
|
}
|
|
|
|
return $this->current_step;
|
|
}
|
|
public function getRegistered(): array
|
|
{
|
|
return $this->registered_steps;
|
|
}
|
|
|
|
public function getDatabaseData()
|
|
{
|
|
return $this->database;
|
|
}
|
|
|
|
public function addPoint($short_name, $closure = null)
|
|
{
|
|
if($short_name === $this->getCurrentStepName()) {
|
|
$this->database['data'][$short_name]['progress']['current']++;
|
|
if(isset($closure)) {
|
|
$closure($this);
|
|
}
|
|
}
|
|
}
|
|
|
|
public function nextStep()
|
|
{
|
|
|
|
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();
|
|
}
|
|
}
|
|
|
|
public function previousStep()
|
|
{
|
|
$this->current_step = end($this->completed_steps) ?? '';
|
|
$this->database['current'] = $this->current_step;
|
|
$this->database['data'][$this->getCurrentStepName()]['completed'] = false;
|
|
}
|
|
|
|
public function selectActiveSteps()
|
|
{
|
|
foreach ($this->database['data'] as $step_name => $data) {
|
|
if($data['completed'] === false) {
|
|
$this->active_steps[$step_name] = $data;
|
|
continue;
|
|
}
|
|
|
|
$this->completed_steps[] = $step_name;
|
|
|
|
}
|
|
}
|
|
|
|
public function store()
|
|
{
|
|
Db::sql('UPDATE user_training SET data = ?, current = ? WHERE user_id = ?', [json_encode($this->database['data']), $this->database['current'], $this->user_id]);
|
|
}
|
|
|
|
/**
|
|
* @param StepFactory[] $steps
|
|
*
|
|
* @return void
|
|
* @throws \DarksLight2\Training\TrainingException
|
|
*/
|
|
public function register(array $steps)
|
|
{
|
|
if (!empty($this->steps)) {
|
|
throw TrainingException::alreadyRegistered();
|
|
}
|
|
|
|
foreach ($steps as $step) {
|
|
if($step instanceof StepFactory) {
|
|
$this->registered_steps[$step->getShortName()] = $step;
|
|
}
|
|
}
|
|
}
|
|
private function generateToken($length = 16)
|
|
{
|
|
|
|
$token = PassGen::new($length);
|
|
|
|
Db::run('UPDATE user_training SET api_token = ? WHERE user_id = ?', [
|
|
$token,
|
|
$this->user_id
|
|
]);
|
|
}
|
|
|
|
public function createDatabaseRecord()
|
|
{
|
|
if(!$this->database) {
|
|
|
|
$data = [];
|
|
|
|
foreach ($this->registered_steps as $step) {
|
|
$data[$step->getShortName()] = $step->databaseRecord();
|
|
}
|
|
|
|
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]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @throws \DarksLight2\Training\TrainingException
|
|
*/
|
|
public function render()
|
|
{
|
|
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;
|
|
}
|
|
|
|
throw TrainingException::noRenderingFile();
|
|
}
|
|
}
|
|
} |