Sprint 3
Onze Database:¶
De data van de spelers:
De structuur van de data van de spelers:
Onze EERD van de Database:
Informatie uit de database halen of opsturen¶
Hieronder staat een klein deel van de php code, de switch case. dit hebben we erbij gezet zodat het duidelijk is hoe we naar de verschillende functies callen en om aan te tonen dat er een structuur in onze code zit en waarom wij de actions bij de doorverstuurde jsonData zetten.
switch ($requestMethod) {
case 'PUT':
$params = file_get_contents('php://input');
$paramsArray = json_decode($params, true);
break;
case 'POST':
$params = file_get_contents('php://input');
$paramsArray = json_decode($params, true);
if (array_key_exists('action', $paramsArray)) {
$action = $paramsArray['action'];
switch ($action) {
// Existing cases...
case 'createPlayer':
createPlayer($paramsArray);
break;
case 'updateLevelUnlocked':
updateLevelUnlocked($paramsArray);
break;
case 'updatePlaytime':
updatePlaytime($paramsArray);
break;
case 'updateCurrentPlaytime':
updateCurrentPlaytime($paramsArray);
break;
default:
handleError('Invalid action');
break;
}
// Add the missing break statement here
break;
} else {
handleError('No action key found in the JSON data');
}
break; // Add this break statement to prevent falling through to the GET case
case 'GET':
// Pass the required parameter to findPlayer
if (isset($_GET['code'])) {
$playerData = findPlayer($_GET['code']);
} else {
handleError('No unique player code received via GET');
}
break;
default:
handleError('Invalid HTTP request method');
break;
}
INSERT INTO / Data Versturen¶
Hier gebruiken we als voorbeeld de createPlayer methode, om te laten zien hoe we data versturen en dat we gebruik maken van de INSERT query.
Hieronder zie je de methode createPlayer, deze word gecalled bij de setup van de game en post de data die we eerst door de JSON.stringify halen zodat de code correct word verstuurd, de data die we hebben vertaald wordt met behulp van httpPost doorverstuurd naar dde server en de die data vertalen we in de switch case weer terug.
In deze methode krijgen we ook het resultaat terug die we vervolgens verwerken, zo doen we dat in elke methode die naar de server verwijst.
createPlayer() {
console.log("Called create User");
// Check if a uniqueCode already exists
if (!this.uniqueCode) {
// User not created, proceed to create a new one
// define JSON data
let data = {
action: "createPlayer",
"createPlayer": true,
};
let jsonData = JSON.stringify(data);
let headers = {
'Content-Type': 'application/json'
};
// Use an arrow function to retain the context of 'this'
httpPost(this.userURL, 'json', jsonData, (result) => {
// Success callback
console.log('Success:', result);
localStorage.setItem('uniqueCode', result.uniqueCode);
this.uniqueCode = result.uniqueCode;
}, (error) => {
// Error callback
console.error('Error:', error);
// Log the entire error object for detailed information
console.log('Error Object:', error);
// Log the actual response received from the server
console.log('Server Response:', error.response);
});
} else {
console.log('User already exists with uniqueCode:', this.uniqueCode);
this.getPlayerData(this.uniqueCode)
}
}
Hieronder zie je dat de functie createPlayer is verbeeld, waarin we de stament met de info die naar de server word verstuurd staat, waarin levelUnlocked altijd op 1 start omdat de speler anders niet kan spelen. Als de code correct terugkomt word deze terugverstuurd naar de methode en word er een echo gemaakt met de nieuwe “UniqueCode” en alle andere parameters.
function createPlayer($paramsPostArray) {
$errorMsg = NULL;
$bCreatePlayer = NULL;
if (isset($paramsPostArray['createPlayer'])) {
$uniqueDBCode = -1;
$dbReturnId = -1;
$bCreatePlayer = $paramsPostArray["createPlayer"];
if ($bCreatePlayer == true) {
// Add a new player to the database and return player data (row id, uniqueCode, aanmaakDatum)
try {
$dbConnect = new DatabaseConnection();
// Generate a unique token of 23 characters with a 'player_' prefix (30 characters)
$uniqueDBCode = uniqid('player_', true);
$levelUnlocked = 1;
$statement = "
INSERT INTO Blok2_Speler
(uniqueCode, aanmaakDatumTijd, levelUnlocked, repititieOpLevelUnlocked, speeltijd, huidigeSpeeltijd, spelerRetention)
VALUES
('" . $uniqueDBCode . "', NOW(), $levelUnlocked, 0, 0, 0, 0);
";
// Execute query-statement on the Database
$bSucces = $dbConnect->executeQuery($statement);
if (!$bSucces) {
$errorMsg = $dbConnect->getConnection()->error;
handleError('Insert failed: ' . $errorMsg);
} else {
$dbReturnId = $dbConnect->getConnection()->insert_id;
// Return JSON structured data with requested/needed information about the new player
echo '{"responseType":"ok", "uniqueCode": "' . $uniqueDBCode . '", "levelUnlocked": ' . $levelUnlocked . ', "repititieOpLevelUnlocked": 0, "speeltijd": 0, "huidigeSpeeltijd": 0, "spelerRetention": 0}';
}
} catch (Exception $e) {
$dbReturnId = -1;
$errorMsg = 'Failed to query the database. Err: ' . $e->getMessage();
handleError('' . $errorMsg);
}
}
} else {
handleError('No createPlayer POST param received');
}
}
SELECT / Data Ophalen¶
Omdat we hierboven al een volledig voorbeeld hebben gegeven van hoe we omgaan met de data en hoe we het versturen delen we hier een klein deel van de getPlayerData(uniqueCode) methode. Omdat dit een get is, krijgen we veel code terug die we allemaal moeten indelen.
Deze methode word aan het einde van de createPlayer methode gecalled zodat als er een nieuwe speler is, de codes niet tegelijk af gaan.
getPlayerData(uniqueCode) {
// Construct the URL with the uniqueCode parameter
const url = `${this.userURL}?code=${encodeURIComponent(uniqueCode)}`;
// Make a GET request to the server
httpGet(url, (result) => {
// Success callback
console.log('Success:', result);
// Parse the JSON response
const response = JSON.parse(result);
// Access the response fields
const aanmaakDatumTijd = response.aanmaakDatumTijd;
const id = response.id;
const level = response.level; // Player unlockedLevel.
const repititieOpLevelUnlocked = response.repititieOpLevelUnlocked; // repetition on the latest unlockedLevel.
const speeltijd = response.speeltijd; // player play time.
const huidigeSpeeltijd = response.huidigeSpeeltijd; // playtime of the last time the player played his rounds and stopped.
const spelerRetention = response.spelerRetention; // Amount of times a player comes back to the game.
updateLevel(level);
overallSpeeltijd = speeltijd;
}, (error) => {
// Error callback
console.error('Error:', error);
});
}
Hieronder zie je de findPlayer functie waarin we met de unieke code van de speler en data van de speler ophalen, dit gebeurd op dezelfde manier als het versturen van data alleen gebruiken we dan een SELECT in plaats van een INSERT.
function findPlayer() {
if(isset($_GET['code'])) {
$playerUniqueCode = $_GET["code"];
$dbReturnID = 0;
$dbAanmaakDatum = 0;
try {
$dbConnect = new DatabaseConnection();
$playerUniqueCode = mysqli_real_escape_string($dbConnect->getConnection(), $playerUniqueCode);
$statement = "
SELECT
id, aanmaakDatumTijd, levelUnlocked, repititieOpLevelUnlocked, speeltijd, huidigeSpeeltijd, spelerRetention
FROM
Blok2_Speler
WHERE
uniqueCode = '" . $playerUniqueCode . "';
";
$result = $dbConnect->executeQuery($statement);
if (!$result) {
$errorMsg = $dbConnect->getConnection()->error;
handleError(''. $errorMsg );
} else {
if ($result->num_rows > 0) {
$row = $result->fetch_assoc();
// Create an associative array with the response data
$responseArray = [
'responseType' => 'ok',
'aanmaakDatumTijd' => $dbAanmaakDatum,
'id' => $dbReturnID,
'level' => $dbLevel,
'repititieOpLevelUnlocked' => $row['repititieOpLevelUnlocked'],
'speeltijd' => $row['speeltijd'],
'huidigeSpeeltijd' => $row['huidigeSpeeltijd'],
'spelerRetention' => $row['spelerRetention']
];
// Encode the array as JSON and echo the result
echo json_encode($responseArray);
} else {
handleNotFound('user with uniqueCode ' . $playerUniqueCode);
}
}
$result->free();
} catch (Exception $e) {
$dbReturnID = -1;
$errorMsg = 'Failed to query the database. Err: ' . $e->getMessage();
handleError(''. $errorMsg );
}
} else {
handleError('No unique player code received via GET, or use POST with param createPlayer : true to create a new player.');
}
}
UPDATE / Data Updaten¶
Hieronder de methode die de level die de speler heeft geunlocked update, dit zorgt ervoor dat de speler kan starten op de level waar hij/zij ook is gestopt. Deze methode word gecalled als de speler een level heeft gehaald.
sendLevelUnlockedData(levelUnlocked) {
// Create an object with data to be sent
let data = {
action: 'updateLevelUnlocked',
uniqueCode: this.uniqueCode,
levelUnlocked: levelUnlocked,
};
let jsonData = JSON.stringify(data);
httpPost(this.userURL, 'json', data, (result) => {
// Handle the server response if needed
console.log(result);
}, (error) => {
// Handle errors
console.error('Error:', error);
});
}
Zoals de twee voorbeelden hiervoor maken we een statement met de code die geexecute moet worden, en deze versturen we doormiddel van de executeQuery functie.
function updateLevelUnlocked($requestData) {
if (isset($requestData['action']) && $requestData['action'] === 'updateLevelUnlocked') {
$uniqueCode = $requestData['uniqueCode'];
$levelUnlocked = $requestData['levelUnlocked'];
try {
$dbConnect = new DatabaseConnection();
// Update levelUnlocked data in the database based on $uniqueCode
$statement = "
UPDATE Blok2_Speler
SET levelUnlocked = '$levelUnlocked'
WHERE uniqueCode = '$uniqueCode';
";
// Execute the update statement on the database
$dbConnect->executeQuery($statement);
// Send a response back to the client (optional)
echo json_encode(["responseType" => "ok", "message" => "LevelUnlocked data updated successfully"]);
} catch (Exception $e) {
// Handle database update error
echo json_encode(["responseType" => "error", "message" => "Failed to update LevelUnlocked data"]);
}
} else {
// Handle other actions or no action specified
echo json_encode(["responseType" => "error", "message" => "Invalid action or no action specified"]);
}
}