Skip to content
This repository was archived by the owner on Mar 3, 2020. It is now read-only.

Level Deletion Confirmation and Bug Fixes #512

Merged
merged 2 commits into from Jun 21, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 45 additions & 15 deletions src/controllers/AdminController.php
Original file line number Diff line number Diff line change
Expand Up @@ -1553,14 +1553,26 @@ class=
$quiz_status_off_id =
'fb--levels--level-'.strval($quiz->getId()).'-status--off';

$quiz_id = 'quiz_id'.strval($quiz->getId());
$quiz_id = strval($quiz->getId());
$quiz_id_txt = 'quiz_id'.strval($quiz->getId());

$countries_select =
await $this->genGenerateCountriesSelect($quiz->getEntityId());

$delete_button =
<div style="display: inline">
<input type="hidden" name="level_id" value={$quiz_id} />
<a
href="#"
class="fb-cta cta--red js-delete-level"
style="margin-right: 20px">
{tr('Delete')}
</a>
</div>;

$adminsections->appendChild(
<section class="admin-box validate-form section-locked">
<form class="level_form quiz_form" name={$quiz_id}>
<form class="level_form quiz_form" name={$quiz_id_txt}>
<input type="hidden" name="level_type" value="quiz" />
<input
type="hidden"
Expand Down Expand Up @@ -1689,9 +1701,7 @@ class=
<a href="#" class="admin--edit" data-action="edit">
{tr('EDIT')}
</a>
<button class="fb-cta cta--red" data-action="delete">
{tr('Delete')}
</button>
{$delete_button}
<button class="fb-cta cta--yellow" data-action="save">
{tr('Save')}
</button>
Expand Down Expand Up @@ -1883,7 +1893,19 @@ class=
$flag_status_off_id =
'fb--levels--level-'.strval($flag->getId()).'-status--off';

$flag_id = 'flag_id'.strval($flag->getId());
$flag_id_txt = 'flag_id'.strval($flag->getId());
$flag_id = strval($flag->getId());

$delete_button =
<div style="display: inline">
<input type="hidden" name="level_id" value={$flag_id} />
<a
href="#"
class="fb-cta cta--red js-delete-level"
style="margin-right: 20px">
{tr('Delete')}
</a>
</div>;

$attachments_div =
<div class="attachments">
Expand Down Expand Up @@ -2068,7 +2090,7 @@ class="fb-cta cta--red"

$adminsections->appendChild(
<section class="validate-form admin-box section-locked">
<form class="level_form flag_form" name={$flag_id}>
<form class="level_form flag_form" name={$flag_id_txt}>
<input type="hidden" name="level_type" value="flag" />
<input
type="hidden"
Expand Down Expand Up @@ -2208,9 +2230,7 @@ class=
<a href="#" class="admin--edit" data-action="edit">
{tr('EDIT')}
</a>
<button class="fb-cta cta--red" data-action="delete">
{tr('Delete')}
</button>
{$delete_button}
<button class="fb-cta cta--yellow" data-action="save">
{tr('Save')}
</button>
Expand Down Expand Up @@ -2407,7 +2427,19 @@ class=
$base_status_off_id =
'fb--levels--level-'.strval($base->getId()).'-status--off';

$base_id = 'base_id'.strval($base->getId());
$base_id = strval($base->getId());
$base_id_txt = 'base_id'.strval($base->getId());

$delete_button =
<div style="display: inline">
<input type="hidden" name="level_id" value={$base_id} />
<a
href="#"
class="fb-cta cta--red js-delete-level"
style="margin-right: 20px">
{tr('Delete')}
</a>
</div>;

$attachments_div =
<div class="attachments">
Expand Down Expand Up @@ -2595,7 +2627,7 @@ class="fb-cta cta--red"

$adminsections->appendChild(
<section class="validate-form admin-box section-locked">
<form class="level_form base_form" name={$base_id}>
<form class="level_form base_form" name={$base_id_txt}>
<input type="hidden" name="level_type" value="base" />
<input
type="hidden"
Expand Down Expand Up @@ -2708,9 +2740,7 @@ class=
<a href="#" class="admin--edit" data-action="edit">
{tr('EDIT')}
</a>
<button class="fb-cta cta--red" data-action="delete">
{tr('Delete')}
</button>
{$delete_button}
<button class="fb-cta cta--yellow" data-action="save">
{tr('Save')}
</button>
Expand Down
22 changes: 22 additions & 0 deletions src/controllers/modals/ActionModalController.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,28 @@ private function getModal(string $modal): (:xhp, :xhp) {
</div>
</div>;
return tuple($title, $content);
case 'delete-level':
$title =
<h4>
{tr('delete_')}<span class="highlighted">{tr('Level')}</span>
</h4>;
$content =
<div class="action-main">
<p>
{tr(
'Are you sure you want to delete this level? All data for this level will be irreversibly removed, including scores.',
)}
</p>
<div class="action-actionable">
<a href="#" class="fb-cta cta--red js-close-modal">
{tr('No')}
</a>
<a href="#" id="delete_level" class="fb-cta cta--yellow">
{tr('Yes')}
</a>
</div>
</div>;
return tuple($title, $content);
case 'logout':
$title =
<h4>
Expand Down
22 changes: 20 additions & 2 deletions src/models/HintLog.php
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ private static function hintlogFromRow(Map<string, string> $row): HintLog {
}
}

// Get all scores.
// Get all hints.
public static async function genAllHints(): Awaitable<array<HintLog>> {
$db = await self::genDb();
$result = await $db->queryf('SELECT * FROM hints_log ORDER BY ts DESC');
Expand All @@ -165,7 +165,7 @@ private static function hintlogFromRow(Map<string, string> $row): HintLog {
return $hints;
}

// Get all scores by team.
// Get all hints by team.
public static async function genAllHintsByTeam(
int $team_id,
): Awaitable<array<HintLog>> {
Expand All @@ -182,4 +182,22 @@ private static function hintlogFromRow(Map<string, string> $row): HintLog {

return $hints;
}

// Get all hints by level.
public static async function genAllHintsByLevel(
int $level_id,
): Awaitable<array<HintLog>> {
$db = await self::genDb();
$result = await $db->queryf(
'SELECT * FROM hints_log WHERE level_id = %d',
$level_id,
);

$hints = array();
foreach ($result->mapRows() as $row) {
$hints[] = self::hintlogFromRow($row);
}

return $hints;
}
}
46 changes: 44 additions & 2 deletions src/models/Level.php
Original file line number Diff line number Diff line change
Expand Up @@ -625,9 +625,51 @@ private static function levelFromRow(Map<string, string> $row): Level {
$level = await self::gen($level_id);
await Country::genSetUsed($level->getEntityId(), false);

await $db->queryf('DELETE FROM levels WHERE id = %d LIMIT 1', $level_id);
// Remove team points for level
$scores = await ScoreLog::genAllScoresByLevel($level_id);
$level_delete_queries = Vector {};
foreach ($scores as $score) {
$team_id = $score->getTeamId();
$points = $score->getPoints();
$level_delete_queries->add(
sprintf(
'UPDATE teams SET points = points - %d WHERE id = %d',
$points,
$team_id,
),
);
}

self::invalidateMCRecords(); // Invalidate Memcached Level data.
// Remove hint penalties from teams points for level
$hints = await HintLog::genAllHintsByLevel($level_id);
foreach ($hints as $hint) {
$team_id = $hint->getTeamId();
$penalty = $hint->getPenalty();
$level_delete_queries->add(
sprintf(
'UPDATE teams SET points = points + %d WHERE id = %d',
$penalty,
$team_id,
),
);
}

// Delete all references to level
$level_delete_queries->addAll(
Set {
sprintf('DELETE FROM levels WHERE id = %d LIMIT 1', $level_id),
sprintf('DELETE FROM hints_log WHERE level_id = %d', $level_id),
sprintf('DELETE FROM scores_log WHERE level_id = %d', $level_id),
sprintf('DELETE FROM failures_log WHERE level_id = %d', $level_id),
},
);
await $db->multiQuery($level_delete_queries);

self::invalidateMCRecords();
Control::invalidateMCRecords();
MultiTeam::invalidateMCRecords();
HintLog::invalidateMCRecords();
ScoreLog::invalidateMCRecords();
}

// Enable or disable level by passing 1 or 0.
Expand Down
18 changes: 18 additions & 0 deletions src/models/ScoreLog.php
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,24 @@ private static function scorelogFromRow(Map<string, string> $row): ScoreLog {
return $scores;
}

// Get all scores by level.
public static async function genAllScoresByLevel(
int $level_id,
): Awaitable<array<ScoreLog>> {
$db = await self::genDb();
$result = await $db->queryf(
'SELECT * FROM scores_log WHERE level_id = %d',
$level_id,
);

$scores = array();
foreach ($result->mapRows() as $row) {
$scores[] = self::scorelogFromRow($row);
}

return $scores;
}

// Log successful score.
public static async function genLogValidScore(
int $level_id,
Expand Down
20 changes: 20 additions & 0 deletions src/static/js/admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,15 @@ function deleteTeamPopup(team_id) {
sendAdminRequest(delete_team, true);
}

//Confirm level deletion
function deleteLevelPopup(level_id) {
var delete_level = {
action: 'delete_level',
level_id: level_id
};
sendAdminRequest(delete_level, true);
}

// Reset the database
function resetDatabase() {
var reset_database = {
Expand Down Expand Up @@ -1402,6 +1411,17 @@ module.exports = {
});
});

// prompt delete level
$('.js-delete-level').on('click', function(event) {
event.preventDefault();
var level_id = $(this).prev('input').attr('value');
Modal.loadPopup('p=action&modal=delete-level', 'action-delete-level', function() {
$('#delete_level').click(function() {
deleteLevelPopup(level_id);
});
});
});

// prompt logout
$('.js-prompt-logout').on('click', function(event) {
event.preventDefault();
Expand Down