/** * Create a new room * * @param int $idUser The user creator id * @param string $roomName The room name * @param int $maxUsers The max room users * @param string $password The room password DEFAULT '' * * @throws Exception If the room name is empty * @throws Exception If the room name already exists * @throws Exception If the max number of users is lower than 2 * * @return bool True if the room was successfully created, false otherwise */ public function createRoom(int $idUser, string $roomName, int $maxUsers, string $password = '') : bool { $roomName = trim($roomName); // Checking error if ($roomName === '') { throw new Exception(_('The room name cannot be empty'), LogLevel::PARAMETER); } if ($maxUsers < 2) { throw new Exception(_('The max number of users must be greater than 1'), LogLevel::PARAMETER); } $sqlMarks = 'SELECT COUNT(id) FROM %s WHERE name = %s'; $sql = static::sqlFormat($sqlMarks, (new Room())->getTableName(), DB::quote($roomName)); if ((int) DB::query($sql)->fetchColumn() > 0) { throw new Exception(_('This room name already exists'), LogLevel::PARAMETER); } // Creation $query = 'SELECT MAX(id) FROM ' . $this->entity->getTableName(); $room = new Room(['id' => (int) DB::query($query)->fetchColumn() + 1, 'name' => $roomName, 'creator' => $idUser, 'password' => $password, 'creationDate' => new \DateTime(), 'maxUsers' => $maxUsers]); return $this->saveEntity($room); }
/** * Connect a user with his login / password combination * * @param string[] $inputs Inputs array containing array('login' => 'login', 'password' => 'password') * * @return array The occurred errors or success in a array * @todo refactoring make it shorter... */ public function connect(array $inputs) : array { $errors = array(); $success = false; $login = trim($inputs['login'] ?? ''); $password = $inputs['password'] ?? ''; if ($login === '') { $errors['login'] = _('Login can\'t be empty'); } else { $login = DB::quote($login); } if ($password === '') { $errors['password'] = _('Password can\'t be empty'); } if (count($errors) === 0) { $sqlMarks = 'SELECT * FROM %s WHERE email = %s OR pseudonym = %s'; $sql = static::sqlFormat($sqlMarks, (new User())->getTableName(), $login, $login); $userParams = DB::query($sql)->fetch(); $now = new \DateTime(); $continue = true; if ($userParams !== false) { $this->entity->setAttributes($userParams); if ((int) $this->entity->connectionAttempt === -1) { $intervalInSec = static::dateIntervalToSec($now->diff($this->entity->lastConnectionAttempt)); $minInterval = (int) $this->params['minTimeAttempt']; if ($intervalInSec < $minInterval) { $continue = false; $errors['SERVER'] = _('You have to wait ' . ($minInterval - $intervalInSec) . ' sec before trying to reconnect'); } else { $this->entity->connectionAttempt = 1; } } else { $this->entity->connectionAttempt++; $this->entity->ipAttempt = $_SERVER['REMOTE_ADDR']; $this->entity->lastConnectionAttempt = $now; } if ($this->entity->ipAttempt === $_SERVER['REMOTE_ADDR']) { if ($this->entity->connectionAttempt === (int) $this->params['maxFailConnectAttempt']) { $this->entity->connectionAttempt = -1; } } else { $this->entity->connectionAttempt = 1; $this->entity->ipAttempt = $_SERVER['REMOTE_ADDR']; } if ($continue) { // Connection success if (hash_equals($userParams['password'], crypt($password, $userParams['password']))) { $success = true; $this->entity->lastConnection = $now; $this->entity->connectionAttempt = 0; $this->entity->ip = $_SERVER['REMOTE_ADDR']; $this->entity->securityToken = bin2hex(random_bytes($this->params['securityTokenLength'])); $this->entity->securityTokenExpires = $now->add(new \DateInterval('PT' . $this->params['securityTokenDuration'] . 'S')); } else { $errors['password'] = _('Incorrect password'); } } $this->saveEntity(); } else { $errors['login'] = _('This login does not exist'); } } return array('success' => $success, 'errors' => $errors); }
/** * Check if a column value is not already in database if the column has a unique attribute constraint * * @param string $columnName The column name * @param mixed $value The column value * * @return bool True if the value is already in database and the column has a unique attribute constraint * else false * * @todo Move to EntityManager ? */ public function checkUniqueField(string $columnName, $value) : bool { $alreadyInDatabase = false; if (strpos($this->constraints['unique'], $columnName) !== false) { $sqlMarks = 'SELECT count(*) FROM %s WHERE %s = ' . DB::quote($value); $sql = EntityManager::sqlFormat($sqlMarks, $this->tableName, $columnName); $alreadyInDatabase = (int) DB::query($sql)->fetchColumn() > 0; } return $alreadyInDatabase; }
/** * Get the casted value string for SQL insertion purpose * * @param mixed $value The value to cast * * @return int|string The casted value */ private function castValueForSQLInsertion($value) { switch (gettype($value)) { case 'boolean': $castedValue = $value ? 1 : 0; break; case 'string': $castedValue = DB::quote($value); break; case 'object': if (is_a($value, '\\DateTime')) { $castedValue = DB::quote($value->format('Y-m-d H:i:s')); } else { $castedValue = DB::quote($value); } break; case 'NULL': $castedValue = 'NULL'; break; default: $castedValue = $value; break; } return $castedValue; }