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) { Db::run('UPDATE user_training SET api_token = ? WHERE user_id = ?', [ PassGen::new($length), $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(); } } }