user_id = $user_id; $this->generateToken(); } /** * @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->steps[$step->getShortName()] = new class ( $step->getMessage(), $step->getTitle(), $step->getRewards(), $this->stepData($step->getShortName())->complete, $step->getShortName(), $this->stepData($step->getShortName())->progress ) { public string $message; public string $title; public string $short_name; public array $rewards; public bool $isComplete; public stdClass $progress; public function __construct( string $message, string $title, array $rewards, bool $isComplete, string $short_name, stdClass $progress ) { $this->rewards = $rewards; $this->title = $title; $this->isComplete = $isComplete; $this->message = $message; $this->short_name = $short_name; $this->progress = $progress; } public function render() { if(!$this->isComplete) { $path = $_SERVER['DOCUMENT_ROOT'] . '/modules_data/steps/' . $this->short_name . '.php'; if (file_exists($path)) { require $path; return; } throw TrainingException::noRenderingFile(); } } }; } } } private function stepData(string $short_name): object { $data = $this->getDatabaseRecords()->data; if(!isset($data->$short_name)) { $this->updateDatabaseRecord($short_name); $data = $this->getDatabaseRecords()->data; } return $data->$short_name; } private function generateToken($length = 16) { $letters = 'abcdefgmikiHGJKLjkGASysj7603456'; $token = ''; for ($i = 0; $i <= $length; $i++) { $token .= $letters[rand(0, strlen($letters))]; } Db::run('UPDATE user_training SET api_token = ? WHERE user_id = ?', [ $token, $this->user_id ]); } public function getDatabaseRecords(): stdClass { if(!$this->database_records) { $data = Db::run('SELECT * FROM user_training WHERE user_id = ?', [$this->user_id]) ->fetch(PDO::FETCH_OBJ); $this->database_records = new stdClass(); $this->database_records->user_id = $data->user_id; $this->database_records->api_token = $data->api_token; $this->database_records->data = json_decode($data->data); } return $this->database_records; } public function updateDatabaseRecord(string $short_name) { if($this->getDatabaseRecords()) { $this->database_records->data->$short_name = $this->firstRecordData()->$short_name; Db::run('UPDATE user_training SET data = ? WHERE user_id = ?', [ json_encode($this->database_records->data), $this->user_id ]); } } public function createDatabaseRecord() { if(!$this->getDatabaseRecords()) { Db::run('INSERT INTO user_training (user_id, data) VALUES (?, ?)', [ $this->user_id, json_encode($this->firstRecordData()) ]); } } private function firstRecordData(): stdClass { $data = new stdClass(); $short_names = [ 'first_step', 'second_step' ]; foreach ($short_names as $name) { $data->$name->complete = false; $data->$name->progress->current = 0; $data->$name->progress->need = 1; } return $data; } public function __get(string $name) { return $this->steps[$name]; } public function addPoint(string $short_name) { $this->database_records->data->$short_name->progress->current++; } public function nextStep() { foreach ($this->database_records->data as $step) { if($step->complete === false && $step->progress->current >= $step->progress->need) { $step->complete = true; } } } public function store() { $this->nextStep(); Db::run('UPDATE user_training SET data = ? WHERE user_id = ?', [ json_encode($this->database_records->data), $this->user_id ]); } }