diff --git a/src/Controller/DashboardController.php b/src/Controller/DashboardController.php index 080f780..6182c84 100644 --- a/src/Controller/DashboardController.php +++ b/src/Controller/DashboardController.php @@ -62,7 +62,7 @@ class DashboardController extends AbstractController foreach ($videos as $video) { $video->setCustomId($this->uuidMapper->toString($video->getId())); - $video->setViews($this->loggingService->getViews($video)); + $video->setViews($this->loggingService->getViewsVideo($video)); } return $this->render("dashboard/dashboard.html.twig", [ diff --git a/src/Controller/WatchController.php b/src/Controller/WatchController.php index 46a9871..3431fa9 100644 --- a/src/Controller/WatchController.php +++ b/src/Controller/WatchController.php @@ -54,7 +54,7 @@ class WatchController extends AbstractController $this->uuidMapper = $uuidMapper; } - private function isAllowed(?Video $video, VideoLink $link): int + private function isAllowed(?Video $video, VideoLink $link, bool $strict): int { if (!$link) { return self::NOT_ALLOWED; @@ -66,10 +66,14 @@ class WatchController extends AbstractController // TODO: check constraints + if (!$link->viewable($strict)) { + return self::NOT_ALLOWED; + } + return self::ALLOWED; } - private function checkRequestData($videoId, $linkId): array + private function checkRequestData($videoId, $linkId, bool $strict = true): array { try { $video = $this->videoService->get($this->uuidMapper->fromString($videoId)); @@ -84,7 +88,7 @@ class WatchController extends AbstractController if (!$allowed) { $link = $this->videoLinkService->get($this->uuidMapper->fromString($linkId)); - $allowed = $this->isAllowed($video, $link); + $allowed = $this->isAllowed($video, $link, $strict); } } catch (ConversionException $e) { throw new AccessDeniedHttpException(); @@ -122,7 +126,7 @@ class WatchController extends AbstractController */ public function qualityPlaylist($videoId, $linkId, int $quality): Response { - $data = $this->checkRequestData($videoId, $linkId); + $data = $this->checkRequestData($videoId, $linkId, false); $file = self::CONTENT_RELATIVE . self::CONTENT_DIRECTORY . $data["video"]->getId() . "/" . $quality . "p/" . "playlist.m3u8"; @@ -137,7 +141,7 @@ class WatchController extends AbstractController */ public function tsFile($videoId, $linkId, int $quality, int $tsFileId): Response { - $data = $this->checkRequestData($videoId, $linkId); + $data = $this->checkRequestData($videoId, $linkId, false); $file = self::CONTENT_RELATIVE . self::CONTENT_DIRECTORY . $data["video"]->getId() . "/" . $quality . "p/" . sprintf(self::TS_FILE_FORMAT, $tsFileId); @@ -199,7 +203,7 @@ class WatchController extends AbstractController } $data["video"]->setCustomId($videoId); - $data["video"]->setViews($this->loggingService->getViews($data["video"])); + $data["video"]->setViews($this->loggingService->getViewsVideo($data["video"])); return $this->render("watch/watch.html.twig", [ "viewToken" => $viewToken, diff --git a/src/Entity/VideoLink.php b/src/Entity/VideoLink.php index 182c36e..9567393 100644 --- a/src/Entity/VideoLink.php +++ b/src/Entity/VideoLink.php @@ -38,6 +38,7 @@ class VideoLink * @ORM\Column(type="integer", nullable=true) */ private $maxViews; + private $viewsLeft; /** * hours @@ -45,6 +46,7 @@ class VideoLink * @ORM\Column(type="integer", nullable=true) */ private $viewableFor; + private $viewableForLeft; /** * @ORM\Column(type="datetime", nullable=true) @@ -159,4 +161,50 @@ class VideoLink $this->customId = $customId; return $this; } + + public function getViewableForLeft(): ?int + { + return $this->viewableForLeft; + } + + public function setViewableForLeft($viewableForLeft): self + { + $this->viewableForLeft = $viewableForLeft; + return $this; + } + + public function getViewsLeft(): ?int + { + return $this->viewsLeft; + } + + public function setViewsLeft($viewsLeft): self + { + $this->viewsLeft = $viewsLeft; + return $this; + } + + public function viewable(bool $strict = true): bool + { + if ($this->getMaxViews()) { + if ($strict && $this->getViewsLeft() <= 0) { + return false; + } + if (!$strict && $this->getViewsLeft() < 0) { + return false; + } + } + if ($this->getViewableFor()) { + if ($this->getViewableForLeft() && $this->getViewableForLeft() < 0) { + return false; + } + } + if ($this->getViewableUntil()) { + if ($this->getViewableUntil()->getTimestamp() < (new DateTime())->getTimestamp()) { + return false; + } + } + + return true; + } } diff --git a/src/Repository/ViewRepository.php b/src/Repository/ViewRepository.php index 4717d82..78e5dc1 100644 --- a/src/Repository/ViewRepository.php +++ b/src/Repository/ViewRepository.php @@ -3,6 +3,7 @@ namespace App\Repository; use App\Entity\Video; +use App\Entity\VideoLink; use App\Entity\View; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Persistence\ManagerRegistry; @@ -63,10 +64,34 @@ class ViewRepository extends ServiceEntityRepository public function countForVideo(Video $video): int { $qb = $this->createQueryBuilder("v"); - return $qb->select("count(v.id)") - ->andWhere("v.video = :video") + return $qb + ->select("count(v.id)") + ->where("v.video = :video") ->setParameter("video", $video->getId()->getBytes()) ->andWhere($qb->expr()->isNotNull("v.validated")) ->getQuery()->getSingleScalarResult(); } + + public function countForLink(VideoLink $videoLink): int + { + $qb = $this->createQueryBuilder("v"); + return $qb + ->select("count(v.id)") + ->where("v.link = :link") + ->setParameter("link", $videoLink->getId()->getBytes()) + ->andWhere($qb->expr()->isNotNull("v.validated")) + ->getQuery()->getSingleScalarResult(); + } + + public function getFirstViewOfLink(VideoLink $videoLink): ?View + { + $qb = $this->createQueryBuilder("v"); + return $qb + ->where("v.link = :link") + ->setParameter("link", $videoLink->getId()->getBytes()) + ->andWhere($qb->expr()->isNotNull("v.validated")) + ->orderBy("v.validated", "ASC") + ->setMaxResults(1) + ->getQuery()->getOneOrNullResult(); + } } diff --git a/src/Service/LoggingService.php b/src/Service/LoggingService.php index 72eba95..a753b1c 100644 --- a/src/Service/LoggingService.php +++ b/src/Service/LoggingService.php @@ -55,9 +55,18 @@ class LoggingService return true; } - public function getViews(Video $video): int + public function getViewsVideo(Video $video): int { - //return $this->viewRepository->countByVideoAndNotNullValidated($video); return $this->viewRepository->countForVideo($video); } + + public function getViewsLink(VideoLink $videoLink) + { + return $this->viewRepository->countForLink($videoLink); + } + + public function getFirstView(VideoLink $videoLink) + { + return $this->viewRepository->getFirstViewOfLink($videoLink); + } } \ No newline at end of file diff --git a/src/Service/VideoLinkService.php b/src/Service/VideoLinkService.php index 8db367d..8c55f4c 100644 --- a/src/Service/VideoLinkService.php +++ b/src/Service/VideoLinkService.php @@ -7,24 +7,51 @@ namespace App\Service; use App\Entity\User; use App\Entity\VideoLink; use App\Repository\VideoLinkRepository; +use DateTime; class VideoLinkService { private $videoLinkRepository; + private $loggingService; - public function __construct(VideoLinkRepository $videoLinkRepository) + public function __construct( + VideoLinkRepository $videoLinkRepository, + LoggingService $loggingService + ) { $this->videoLinkRepository = $videoLinkRepository; + $this->loggingService = $loggingService; + } + + private function evaluate(VideoLink $videoLink): VideoLink + { + if ($videoLink->getMaxViews()) { + $tmp = $this->loggingService->getViewsLink($videoLink); + $videoLink->setViewsLeft($videoLink->getMaxViews() - $tmp); + } + if ($videoLink->getViewableFor()) { + $tmp = $this->loggingService->getFirstView($videoLink); + if ($tmp) { + $videoLink->setViewableForLeft( + $videoLink->getViewableFor() - + ($tmp->getTimestamp()->getTimestamp() - (new DateTime())->getTimestamp()) / 3600 + ); + } + } + + return $videoLink; } public function get($linkId): ?VideoLink { - return $this->videoLinkRepository->findOneById($linkId); + return $this->evaluate($this->videoLinkRepository->findOneById($linkId)); } public function getAll(User $user): array { - return $this->videoLinkRepository->findByCreator($user); + return array_map(function ($videoLink) { + return $this->evaluate($videoLink); + }, $this->videoLinkRepository->findByCreator($user)); } public function add($videoLink): void diff --git a/templates/dashboard/links.html.twig b/templates/dashboard/links.html.twig index fca841b..94d25c2 100644 --- a/templates/dashboard/links.html.twig +++ b/templates/dashboard/links.html.twig @@ -12,6 +12,7 @@ + Video @@ -39,6 +40,11 @@ + + {% if not link.viewable() %} + + {% endif %} + {% if link.viewableUntil %} - {{ viewableUntil | date("Y-m-d") }} + {{ link.viewableUntil | date("Y-m-d") }} {% else %} - {% endif %} {% if link.maxViews %} - # / {{ link.maxViews }} + {{ link.viewsLeft }} / {{ link.maxViews }} {% else %} - {% endif %} {% if link.viewableFor %} - # / {{ link.viewableFor }} + {{ link.viewableForLeft != null ? link.viewableForLeft : "-" }} / {{ link.viewableFor }} {% else %} - {% endif %}