video deletion now works

This commit is contained in:
overflowerror 2021-01-08 16:59:20 +01:00
parent 7ec2db7d77
commit de2e13f6e6
9 changed files with 108 additions and 14 deletions

View file

@ -18,12 +18,6 @@
height: 30px;
}
.avatar-dropdown {
/*top: calc(100% + 0.40rem);
right: -0.75rem;*/
left: auto !important;
}
.container {
position: relative;
}

View file

@ -138,4 +138,19 @@
.no-content {
margin-left: 3%;
}
.deleteToggle:after {
display: none;
}
.deleteConfirm {
text-align: center;
padding: 1vw;
font-size: 1vw;
min-width: 14vw;
}
.deleteButton {
color: red;
}

11
public/js/utils.js Normal file
View file

@ -0,0 +1,11 @@
function removeClass(className, elements) {
if (typeof elements == "string") {
elements = [elements];
}
for (let i in elements) {
let element = elements[i];
element = document.querySelector(element);
element.className = element.className.replaceAll(className, "");
}
}

View file

@ -25,6 +25,8 @@ use Symfony\Component\Routing\Annotation\Route;
class DashboardController extends AbstractController
{
public const DELETE_VIDEO_CSRF_TOKEN_ID = "delete-video";
private $userService;
private $videoService;
private $videoLinkService;
@ -102,6 +104,38 @@ class DashboardController extends AbstractController
]);
}
/**
* @Route("/video/delete", name="app_video_delete", methods={"POST"})
*/
public function delete(Request $request): Response
{
$token = $request->request->get("csrfToken");
$videoId = $request->request->get("videoId");
if (!$this->isCsrfTokenValid(self::DELETE_VIDEO_CSRF_TOKEN_ID, $token)) {
throw new AccessDeniedHttpException();
}
if (!$videoId) {
throw new BadRequestHttpException();
}
try {
$videoId = $this->uuidMapper->fromString($videoId);
} catch (ConversionException $e) {
throw new BadRequestHttpException();
}
$video = $this->videoService->get($videoId);
if ($video == null || $video->getUploader() != $this->userService->getLoggedInUser()) {
throw new AccessDeniedHttpException();
}
$this->videoService->delete($video);
return $this->redirectToRoute("app_dashboard");
}
/**
* @Route("/upload/{videoId}", name="app_upload_status")
*/

View file

@ -12,11 +12,15 @@ use Ramsey\Uuid\UuidInterface;
class CustomUuidMapper
{
private const REPLACE_SLASH = "-";
private const REPLACE_PLUS = "_";
public function fromString($str): UuidInterface
{
try {
return Uuid::fromBytes(base64_decode(str_replace(self::REPLACE_SLASH, "/", $str) . "=="));
return Uuid::fromBytes(
base64_decode(
str_replace(self::REPLACE_PLUS, "+",
str_replace(self::REPLACE_SLASH, "/", $str) . "==")));
} catch (InvalidArgumentException $e) {
throw new ConversionException($e);
}
@ -24,6 +28,10 @@ class CustomUuidMapper
public function toString(UuidInterface $uuid): string
{
return str_replace("/", self::REPLACE_SLASH, str_replace("==", "", base64_encode($uuid->getBytes())));
return
str_replace("+", self::REPLACE_PLUS,
str_replace("/", self::REPLACE_SLASH,
str_replace("==", "",
base64_encode($uuid->getBytes()))));
}
}

View file

@ -56,4 +56,10 @@ class VideoRepository extends ServiceEntityRepository
{
$this->_em->flush();
}
public function delete(Video $video)
{
$this->_em->remove($video);
$this->_em->flush();
}
}

View file

@ -52,4 +52,9 @@ class VideoService
{
return $this->videoRepository->findOneById($videoId);
}
public function delete(Video $video)
{
$this->videoRepository->delete($video);
}
}

View file

@ -75,7 +75,8 @@
alt=""
/>
</a>
<ul class="dropdown-menu avatar-dropdown" aria-labelledby="navbarDropdownMenuLink">
<ul class="dropdown-menu dropdown-menu-end avatar-dropdown"
aria-labelledby="navbarDropdownMenuLink">
<li><a class="dropdown-item" href="#">My profile</a></li>
<li><a class="dropdown-item" href="#">Settings</a></li>
<li><a class="dropdown-item" href="{{ path("app_logout") }}">Logout</a></li>
@ -92,6 +93,7 @@
<script src="{{ asset("js/clipboard.js") }}"></script>
<script src="{{ asset("js/toasts.js") }}"></script>
<script src="{{ asset("js/ajax.js") }}"></script>
<script src="{{ asset("js/utils.js") }}"></script>
{% block javascripts %}{% endblock %}
</body>
</html>

View file

@ -39,6 +39,7 @@
{% endblock %}
{% block body %}
{% set deleteCsrfToken = csrf_token(constant("App\\Controller\\DashboardController::DELETE_VIDEO_CSRF_TOKEN_ID")) %}
<div class="grid-container">
<script>var autoupdate = [];</script>
<div class="row">
@ -66,17 +67,35 @@
<div class="info">
<div class="buttons btn-group btn-group-sm">
<button class="btn btn-primary"
onclick="location.href='{{ path("app_new_link") }}?video={{ video.customId | url_encode }}'">
onclick="location.href='{{ path("app_new_link") }}?video={{ video.customId }}'">
<i class="fas fa-link"></i>
</button>
<button class="btn btn-primary"
onclick="">
<i class="fas fa-cog"></i>
</button>
<button class="btn btn-primary btn-danger"
onclick="">
<i class="fas fa-trash-alt"></i>
</button>
<form action="{{ path("app_video_delete") }}" method="POST">
<input type="hidden" name="videoId" value="{{ video.customId }}">
<input type="hidden" name="csrfToken" value="{{ deleteCsrfToken }}">
<button class="btn btn-primary btn-danger dropdown-toggle deleteToggle"
id="{{ video.customId }}-deleteDropDown"
data-mdb-toggle="dropdown"
aria-expanded="false"
onclick="">
<i class="fas fa-trash-alt"></i>
</button>
<div class="dropdown-menu dropdown-menu-end deleteConfirm"
id="{{ video.customId }}-deleteDropDownMenu"
aria-labelledby="{{ video.customId }}-deleteDropDown">
Do you really want to delete "{{ video.name }}"?<br/>
<button class="btn btn-link deleteButton">YES</button>
<button class="btn btn-primary" onclick="removeClass('show', [
'#{{ video.customId }}-deleteDropDown',
'#{{ video.customId }}-deleteDropDownMenu'
]); return false;">NO
</button>
</div>
</form>
</div>
<h5>{{ video.name }}</h5>
<div class="views">