...
 
Commits (3)
......@@ -84,6 +84,7 @@ class NodeController {
$nodeViewModel->subgroup = $node->getSubgroup();
$nodeViewModel->name = $node->getName();
$nodeViewModel->target = $node->getTarget();
$nodeViewModel->searchable = $node->isSearchable();
switch ($nodeViewModel->icon) {
case 'poison':
$nodeViewModel->targetIcon = 'fa-user';
......@@ -141,6 +142,46 @@ class NodeController {
* - down-stair
*/
$node = $this->transformPostData($postData, $difficulty, $user, $missionId);
$this->entityManager->persist($node);
$this->entityManager->flush();
$nodeId = $node->getId();
$i = 0;
foreach ($postData['note-type'] as $noteType) {
$noteText = $postData['note-text'][$i++];
if (trim($noteText) === '') {
continue;
}
$nodeNote = new NodeNote();
$nodeNote->setNodeId($nodeId);
$nodeNote->setType($noteType);
$nodeNote->setText($noteText);
$this->entityManager->persist($nodeNote);
$this->entityManager->flush();
}
return $node;
}
private function transformPostData(array $postData, string $difficulty, User $user, int $missionId): Node {
/*
* - Sabotage uses "action" instead of "target"
* - Distraction uses "action" instead of "target"
* - Agency Pickup uses "pickup-type" instead of "target"
* - "large" -> Large Pickup
* - "small" -> Stash
* - Stairwell uses "stairwell-direction" as its icon
* - up-stair
* - up-down-stair
* - down-stair
*/
list($type, $subgroup) = explode('|', $postData['subgroup']);
$node = new Node();
$node->setDifficulty($difficulty);
......@@ -191,10 +232,19 @@ class NodeController {
}
$node->setApproved(UserRole::hasAccess($user->getRolesAsInts(), [UserRole::TRUSTED_EDITOR]));
return $node;
}
public function editNode(int $nodeId, int $missionId, string $difficulty, array $postData, User $user): Node {
$node = $this->transformPostData($postData, $difficulty, $user, $missionId);
$node->setId($nodeId);
$node = $this->entityManager->merge($node);
$this->entityManager->persist($node);
$this->entityManager->flush();
$nodeId = $node->getId();
$this->entityManager->getConnection()->executeUpdate("DELETE FROM `node_notes` WHERE `node_id` = " . $nodeId);
$i = 0;
foreach ($postData['note-type'] as $noteType) {
......
......@@ -21,4 +21,5 @@ class NodeWithNotesViewModel {
public $notes;
public $approved;
public $image;
public $searchable;
}
\ No newline at end of file
......@@ -192,7 +192,11 @@ $klein->respond('POST', '/api/nodes', function (\Klein\Request $request, \Klein\
$user = \BusinessLogic\Session\Session::read('userContext');
$node = $applicationContext->get(\Controllers\NodeController::class)->createNode(intval($_POST['mission-id']), $_POST['difficulty'], $_POST, $user);
$response->code(201);
return json_encode(transformNode($node, $applicationContext));
});
function transformNode(\DataAccess\Models\Node $node, \DI\Container $applicationContext): \Controllers\ViewModels\NodeWithNotesViewModel {
$nodeViewModel = new \Controllers\ViewModels\NodeWithNotesViewModel();
$nodeViewModel->id = $node->getId();
$nodeViewModel->missionId = $node->getMissionId();
......@@ -208,6 +212,7 @@ $klein->respond('POST', '/api/nodes', function (\Klein\Request $request, \Klein\
$nodeViewModel->group = $node->getGroup();
$nodeViewModel->approved = $node->getApproved();
$nodeViewModel->image = $node->getImage();
$nodeViewModel->searchable = $node->isSearchable();
switch ($nodeViewModel->icon) {
case 'poison':
$nodeViewModel->targetIcon = 'fa-user';
......@@ -234,9 +239,9 @@ $klein->respond('POST', '/api/nodes', function (\Klein\Request $request, \Klein\
$nodeViewModel->notes[] = $innerViewModel;
}
$response->code(201);
return json_encode($nodeViewModel);
});
return $nodeViewModel;
}
$klein->respond('POST', '/api/ledges', function (\Klein\Request $request, \Klein\Response $response) use ($applicationContext) {
if (!userIsLoggedIn()) {
......@@ -286,7 +291,27 @@ $klein->respond('POST', '/api/nodes/move', function (\Klein\Request $request, \K
return json_encode(['message' => 'OK']);
});
$klein->respond('GET', '/api/nodes/delete/[:nodeId]', function(\Klein\Request $request, \Klein\Response $response) use ($applicationContext) {
$klein->respond('POST', '/api/nodes/edit/[:nodeId]', function(\Klein\Request $request, \Klein\Response $response) use ($applicationContext) {
if (!userIsLoggedIn()) {
print json_encode(['message' => 'You must be logged in to modify nodes!']);
return $response->code(401);
}
/* @var $user \DataAccess\Models\User */
$user = \BusinessLogic\Session\Session::read('userContext');
$roles = $user->getRolesAsInts();
if (!\BusinessLogic\UserRole::hasAccess($roles, [\BusinessLogic\UserRole::TRUSTED_EDITOR])) {
print json_encode(['message' => 'You do not have permission to delete nodes!']);
return $response->code(403);
}
$node = $applicationContext->get(\Controllers\NodeController::class)->editNode(intval($request->nodeId), intval($_POST['mission-id']), $_POST['difficulty'], $_POST, $user);
$response->code(200);
return json_encode(transformNode($node, $applicationContext));
});
$klein->respond('GET', '/api/nodes/delete/[:nodeId]', function(\Klein\Request $request, \Klein\Response $response) use ($applicationContext) {
if (!userIsLoggedIn()) {
print json_encode(['message' => 'You must be logged in to modify nodes!']);
return $response->code(401);
......
......@@ -455,9 +455,10 @@
<input type="hidden" name="level" value="{{ model.startingFloor }}">
<input type="hidden" name="latitude">
<input type="hidden" name="longitude">
<input type="hidden" name="image">
<input type="hidden" name="image">
<input type="hidden" name="difficulty" value="{{ model.difficulty }}">
<input type="hidden" name="searchable" value="0">
<input type="hidden" name="id" value="-1">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
......@@ -665,6 +666,8 @@
$('select[name="subgroup"]').selectpicker('val', -1);
$('select[name="icon"]').selectpicker('val', -1);
$('#suggest-edit-modal')
.find('#add-suggest-title').show().end()
.find('#edit-suggest-title').hide().end()
.find('input[name="name"]').val('').end()
.find('input[name="action"]').val('').end()
.find('input[name="target"]').val('').end()
......@@ -677,6 +680,7 @@
.find('[data-type="target"]').hide().end()
.find('[data-type="action"]').hide().end()
.find('[data-type="name"]').hide().end()
.find('input[name="id"]').val(-1).end()
.modal('show');
});
var zoom = L.control.zoom({position: 'topright'});
......@@ -840,6 +844,11 @@
} else {
$(nodeProperties._icon).removeClass('search-result');
}
if (nodeProperties.options.custom.node.deleted === true) {
g_map.removeLayer(nodeProperties);
numberOfItemsOnMap--;
}
}
}
} else {
......@@ -1006,12 +1015,25 @@
$('form[action="/api/nodes"]').submit(function() {
var $form = $(this);
var nodeId = $form.find('input[name="id"]').val();
var uri = '/api/nodes';
var action = 'CREATE';
if (nodeId > -1) {
uri = '/api/nodes/edit/' + nodeId;
action = 'EDIT';
}
$.ajax({
url: '/api/nodes',
url: uri,
method: 'POST',
data: $(this).serialize(),
data: $form.serialize(),
success: function(data) {
if (action === 'EDIT') {
g_openMarker.options.custom.node.deleted = true;
g_openMarker = undefined;
}
var node = JSON.parse(data);
if (node.approved) {
var marker = buildMarker(node).bindPopup(buildPopup);
......@@ -1019,11 +1041,18 @@
marker.bindTooltip(node.name);
}
marker.addTo(g_overlays[node.level][node.type + '|' + node.group]);
toastr["success"]('Item successfully added to map!');
if (action === 'CREATE') {
toastr["success"]('Item successfully added to map!');
} else {
toastr["success"]('Item successfully edited!');
}
} else {
toastr["success"]('Suggestion has been submitted. If it is approved by an administrator, it will become visible on the map.');
}
$('#suggest-edit-modal').modal('hide');
updateNodeLayerState();
},
error: function() {
alert('Error!');
......@@ -1154,7 +1183,9 @@
method: 'GET',
success: function() {
toastr["success"]("Node deleted!");
g_map.removeLayer(g_openMarker);
g_openMarker.options.custom.node.deleted = true;
g_openMarker = undefined;
updateNodeLayerState();
},
error: function() {
toastr["error"]("Error deleting node!");
......@@ -1179,7 +1210,11 @@
.find('input[name="id"]').val(node.id).end()
.find('input[name="level"]').val(node.level).end()
.find('input[name="target"]').val(node.target).end()
.find('input[name="action"]').val(node.target).end();
.find('input[name="action"]').val(node.target).end()
.find('input[name="searchable"]').val(node.searchable === true ? '1' : '0').end()
.find('input[name="image"]').val(node.image).end()
.find('#add-suggest-title').hide().end()
.find('#edit-suggest-title').show().end();
if (node.group === 'Agency Pickup') {
$modal.find('input[name="pickup-type"]').removeAttr('checked').end()
......