mirror of
https://github.com/sigmasternchen/MyTube
synced 2025-03-15 21:08:55 +00:00
view logging works
This commit is contained in:
parent
d6197a692a
commit
6e5ac1b55c
8 changed files with 385 additions and 8 deletions
89
migrations/Version20210107200117.php
Normal file
89
migrations/Version20210107200117.php
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DoctrineMigrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-generated Migration: Please modify to your needs!
|
||||||
|
*/
|
||||||
|
final class Version20210107200117 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this up() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('CREATE TABLE "view" (id BLOB NOT NULL, video_id BLOB NOT NULL, link_id BLOB NOT NULL, timestamp DATETIME NOT NULL --(DC2Type:datetime_immutable)
|
||||||
|
, validated DATETIME DEFAULT NULL --(DC2Type:datetime_immutable)
|
||||||
|
, PRIMARY KEY(id))');
|
||||||
|
$this->addSql('CREATE INDEX IDX_FEFDAB8E29C1004E ON "view" (video_id)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_FEFDAB8EADA40271 ON "view" (link_id)');
|
||||||
|
$this->addSql('DROP INDEX UNIQ_8D93D6495E237E06');
|
||||||
|
$this->addSql('CREATE TEMPORARY TABLE __temp__user AS SELECT id, password, name, roles FROM user');
|
||||||
|
$this->addSql('DROP TABLE user');
|
||||||
|
$this->addSql('CREATE TABLE user (id BLOB NOT NULL, password VARCHAR(255) NOT NULL COLLATE BINARY, name VARCHAR(180) NOT NULL COLLATE BINARY, roles CLOB NOT NULL COLLATE BINARY --(DC2Type:json)
|
||||||
|
, PRIMARY KEY(id))');
|
||||||
|
$this->addSql('INSERT INTO user (id, password, name, roles) SELECT id, password, name, roles FROM __temp__user');
|
||||||
|
$this->addSql('DROP TABLE __temp__user');
|
||||||
|
$this->addSql('CREATE UNIQUE INDEX UNIQ_8D93D6495E237E06 ON user (name)');
|
||||||
|
$this->addSql('DROP INDEX IDX_7CC7DA2C16678C77');
|
||||||
|
$this->addSql('CREATE TEMPORARY TABLE __temp__video AS SELECT id, uploader_id, uploaded, name, description, tags, state, length, transcoding_progress FROM video');
|
||||||
|
$this->addSql('DROP TABLE video');
|
||||||
|
$this->addSql('CREATE TABLE video (id BLOB NOT NULL, uploader_id BLOB NOT NULL, uploaded DATETIME NOT NULL --(DC2Type:datetime_immutable)
|
||||||
|
, name VARCHAR(255) NOT NULL COLLATE BINARY, description VARCHAR(1024) NOT NULL COLLATE BINARY, tags CLOB NOT NULL COLLATE BINARY --(DC2Type:array)
|
||||||
|
, state INTEGER NOT NULL, length DOUBLE PRECISION DEFAULT NULL, transcoding_progress INTEGER NOT NULL, PRIMARY KEY(id), CONSTRAINT FK_7CC7DA2C16678C77 FOREIGN KEY (uploader_id) REFERENCES user (id) NOT DEFERRABLE INITIALLY IMMEDIATE)');
|
||||||
|
$this->addSql('INSERT INTO video (id, uploader_id, uploaded, name, description, tags, state, length, transcoding_progress) SELECT id, uploader_id, uploaded, name, description, tags, state, length, transcoding_progress FROM __temp__video');
|
||||||
|
$this->addSql('DROP TABLE __temp__video');
|
||||||
|
$this->addSql('CREATE INDEX IDX_7CC7DA2C16678C77 ON video (uploader_id)');
|
||||||
|
$this->addSql('DROP INDEX IDX_313BC42D61220EA6');
|
||||||
|
$this->addSql('DROP INDEX IDX_313BC42D29C1004E');
|
||||||
|
$this->addSql('CREATE TEMPORARY TABLE __temp__video_link AS SELECT id, video_id, creator_id, created, max_views, viewable_for, viewable_until, comment FROM video_link');
|
||||||
|
$this->addSql('DROP TABLE video_link');
|
||||||
|
$this->addSql('CREATE TABLE video_link (id BLOB NOT NULL, video_id BLOB NOT NULL, creator_id BLOB NOT NULL, created DATETIME NOT NULL --(DC2Type:datetime_immutable)
|
||||||
|
, max_views INTEGER DEFAULT NULL, viewable_for INTEGER DEFAULT NULL, viewable_until DATETIME DEFAULT NULL, comment VARCHAR(1024) DEFAULT NULL COLLATE BINARY, PRIMARY KEY(id), CONSTRAINT FK_313BC42D29C1004E FOREIGN KEY (video_id) REFERENCES video (id) NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_313BC42D61220EA6 FOREIGN KEY (creator_id) REFERENCES user (id) NOT DEFERRABLE INITIALLY IMMEDIATE)');
|
||||||
|
$this->addSql('INSERT INTO video_link (id, video_id, creator_id, created, max_views, viewable_for, viewable_until, comment) SELECT id, video_id, creator_id, created, max_views, viewable_for, viewable_until, comment FROM __temp__video_link');
|
||||||
|
$this->addSql('DROP TABLE __temp__video_link');
|
||||||
|
$this->addSql('CREATE INDEX IDX_313BC42D61220EA6 ON video_link (creator_id)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_313BC42D29C1004E ON video_link (video_id)');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this down() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('DROP TABLE "view"');
|
||||||
|
$this->addSql('DROP INDEX UNIQ_8D93D6495E237E06');
|
||||||
|
$this->addSql('CREATE TEMPORARY TABLE __temp__user AS SELECT id, name, roles, password FROM user');
|
||||||
|
$this->addSql('DROP TABLE user');
|
||||||
|
$this->addSql('CREATE TABLE user (id BLOB NOT NULL, name VARCHAR(180) NOT NULL, roles CLOB NOT NULL --(DC2Type:json)
|
||||||
|
, password VARCHAR(255) NOT NULL, PRIMARY KEY(id))');
|
||||||
|
$this->addSql('INSERT INTO user (id, name, roles, password) SELECT id, name, roles, password FROM __temp__user');
|
||||||
|
$this->addSql('DROP TABLE __temp__user');
|
||||||
|
$this->addSql('CREATE UNIQUE INDEX UNIQ_8D93D6495E237E06 ON user (name)');
|
||||||
|
$this->addSql('DROP INDEX IDX_7CC7DA2C16678C77');
|
||||||
|
$this->addSql('CREATE TEMPORARY TABLE __temp__video AS SELECT id, uploader_id, uploaded, name, description, tags, state, length, transcoding_progress FROM video');
|
||||||
|
$this->addSql('DROP TABLE video');
|
||||||
|
$this->addSql('CREATE TABLE video (id BLOB NOT NULL, uploaded DATETIME NOT NULL --(DC2Type:datetime_immutable)
|
||||||
|
, name VARCHAR(255) NOT NULL, description VARCHAR(1024) NOT NULL, tags CLOB NOT NULL --(DC2Type:array)
|
||||||
|
, state INTEGER NOT NULL, length DOUBLE PRECISION DEFAULT NULL, uploader_id BLOB NOT NULL, transcoding_progress INTEGER DEFAULT NULL, PRIMARY KEY(id))');
|
||||||
|
$this->addSql('INSERT INTO video (id, uploader_id, uploaded, name, description, tags, state, length, transcoding_progress) SELECT id, uploader_id, uploaded, name, description, tags, state, length, transcoding_progress FROM __temp__video');
|
||||||
|
$this->addSql('DROP TABLE __temp__video');
|
||||||
|
$this->addSql('CREATE INDEX IDX_7CC7DA2C16678C77 ON video (uploader_id)');
|
||||||
|
$this->addSql('DROP INDEX IDX_313BC42D29C1004E');
|
||||||
|
$this->addSql('DROP INDEX IDX_313BC42D61220EA6');
|
||||||
|
$this->addSql('CREATE TEMPORARY TABLE __temp__video_link AS SELECT id, video_id, creator_id, created, max_views, viewable_for, viewable_until, comment FROM video_link');
|
||||||
|
$this->addSql('DROP TABLE video_link');
|
||||||
|
$this->addSql('CREATE TABLE video_link (id BLOB NOT NULL, created DATETIME NOT NULL --(DC2Type:datetime_immutable)
|
||||||
|
, max_views INTEGER DEFAULT NULL, viewable_for INTEGER DEFAULT NULL, viewable_until DATETIME DEFAULT NULL, comment VARCHAR(1024) DEFAULT NULL, video_id BLOB NOT NULL, creator_id BLOB NOT NULL, PRIMARY KEY(id))');
|
||||||
|
$this->addSql('INSERT INTO video_link (id, video_id, creator_id, created, max_views, viewable_for, viewable_until, comment) SELECT id, video_id, creator_id, created, max_views, viewable_for, viewable_until, comment FROM __temp__video_link');
|
||||||
|
$this->addSql('DROP TABLE __temp__video_link');
|
||||||
|
$this->addSql('CREATE INDEX IDX_313BC42D29C1004E ON video_link (video_id)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_313BC42D61220EA6 ON video_link (creator_id)');
|
||||||
|
}
|
||||||
|
}
|
|
@ -169,6 +169,7 @@ class DashboardController extends AbstractController
|
||||||
try {
|
try {
|
||||||
$videoId = $this->uuidMapper->fromString($videoId);
|
$videoId = $this->uuidMapper->fromString($videoId);
|
||||||
} catch (ConversionException $e) {
|
} catch (ConversionException $e) {
|
||||||
|
return new Response($videoId);
|
||||||
return $this->redirectToRoute("app_links");
|
return $this->redirectToRoute("app_links");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,9 @@ namespace App\Controller;
|
||||||
|
|
||||||
use App\Entity\User;
|
use App\Entity\User;
|
||||||
use App\Entity\Video;
|
use App\Entity\Video;
|
||||||
|
use App\Entity\VideoLink;
|
||||||
use App\Mapper\CustomUuidMapper;
|
use App\Mapper\CustomUuidMapper;
|
||||||
|
use App\Service\LoggingService;
|
||||||
use App\Service\UserService;
|
use App\Service\UserService;
|
||||||
use App\Service\VideoLinkService;
|
use App\Service\VideoLinkService;
|
||||||
use App\Service\VideoService;
|
use App\Service\VideoService;
|
||||||
|
@ -13,6 +15,7 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
|
||||||
class WatchController extends AbstractController
|
class WatchController extends AbstractController
|
||||||
|
@ -34,28 +37,26 @@ class WatchController extends AbstractController
|
||||||
private $userService;
|
private $userService;
|
||||||
private $videoService;
|
private $videoService;
|
||||||
private $videoLinkService;
|
private $videoLinkService;
|
||||||
|
private $loggingService;
|
||||||
private $uuidMapper;
|
private $uuidMapper;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
UserService $userService,
|
UserService $userService,
|
||||||
VideoService $videoService,
|
VideoService $videoService,
|
||||||
VideoLinkService $videoLinkService,
|
VideoLinkService $videoLinkService,
|
||||||
|
LoggingService $loggingService,
|
||||||
CustomUuidMapper $uuidMapper
|
CustomUuidMapper $uuidMapper
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
$this->userService = $userService;
|
$this->userService = $userService;
|
||||||
$this->videoService = $videoService;
|
$this->videoService = $videoService;
|
||||||
$this->videoLinkService = $videoLinkService;
|
$this->videoLinkService = $videoLinkService;
|
||||||
|
$this->loggingService = $loggingService;
|
||||||
$this->uuidMapper = $uuidMapper;
|
$this->uuidMapper = $uuidMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function isAllowed(?Video $video, ?User $user, $linkId): int
|
private function isAllowed(?Video $video, ?User $user, VideoLink $link): int
|
||||||
{
|
{
|
||||||
if ($video->getUploader() == $user) {
|
|
||||||
return self::IS_OWNER;
|
|
||||||
}
|
|
||||||
|
|
||||||
$link = $this->videoLinkService->get($this->uuidMapper->fromString($linkId));
|
|
||||||
if (!$link) {
|
if (!$link) {
|
||||||
return self::NOT_ALLOWED;
|
return self::NOT_ALLOWED;
|
||||||
}
|
}
|
||||||
|
@ -74,8 +75,18 @@ class WatchController extends AbstractController
|
||||||
try {
|
try {
|
||||||
$video = $this->videoService->get($this->uuidMapper->fromString($videoId));
|
$video = $this->videoService->get($this->uuidMapper->fromString($videoId));
|
||||||
$user = $this->userService->getLoggedInUser();
|
$user = $this->userService->getLoggedInUser();
|
||||||
|
$link = null;
|
||||||
|
|
||||||
$allowed = $this->isAllowed($video, $user, $linkId);
|
$allowed = self::NOT_ALLOWED;
|
||||||
|
|
||||||
|
if ($video->getUploader() == $user) {
|
||||||
|
$allowed = self::IS_OWNER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$allowed) {
|
||||||
|
$link = $this->videoLinkService->get($this->uuidMapper->fromString($linkId));
|
||||||
|
$allowed = $this->isAllowed($video, $user, $link);
|
||||||
|
}
|
||||||
} catch (ConversionException $e) {
|
} catch (ConversionException $e) {
|
||||||
throw new AccessDeniedHttpException();
|
throw new AccessDeniedHttpException();
|
||||||
}
|
}
|
||||||
|
@ -86,6 +97,7 @@ class WatchController extends AbstractController
|
||||||
|
|
||||||
return [
|
return [
|
||||||
"video" => $video,
|
"video" => $video,
|
||||||
|
"link" => $link,
|
||||||
"user" => $user,
|
"user" => $user,
|
||||||
"isOwner" => $allowed == self::IS_OWNER
|
"isOwner" => $allowed == self::IS_OWNER
|
||||||
];
|
];
|
||||||
|
@ -151,6 +163,30 @@ class WatchController extends AbstractController
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Route("/{linkId}/{videoId}/v/{viewId}", methods={"POST"}, name="app_watch_view")
|
||||||
|
*/
|
||||||
|
public function viewCounter($videoId, $linkId, $viewId): Response
|
||||||
|
{
|
||||||
|
$data = $this->checkRequestData($videoId, $linkId);
|
||||||
|
|
||||||
|
if ($data["isOwner"]) {
|
||||||
|
throw new BadRequestHttpException();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$viewId = $this->uuidMapper->fromString($viewId);
|
||||||
|
} catch (ConversionException $e) {
|
||||||
|
throw new BadRequestHttpException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->loggingService->validateView($data["video"], $data["link"], $viewId)) {
|
||||||
|
throw new BadRequestHttpException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Response("ok");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/{linkId}/{videoId}/", name="app_watch_page")
|
* @Route("/{linkId}/{videoId}/", name="app_watch_page")
|
||||||
*/
|
*/
|
||||||
|
@ -158,7 +194,15 @@ class WatchController extends AbstractController
|
||||||
{
|
{
|
||||||
$data = $this->checkRequestData($videoId, $linkId);
|
$data = $this->checkRequestData($videoId, $linkId);
|
||||||
|
|
||||||
|
$viewToken = null;
|
||||||
|
if (!$data["isOwner"]) {
|
||||||
|
$viewToken = $this->uuidMapper->toString($this->loggingService->createView($data["video"], $data["link"]));
|
||||||
|
}
|
||||||
|
|
||||||
|
$data["video"]->setCustomId($videoId);
|
||||||
|
|
||||||
return $this->render("watch/watch.html.twig", [
|
return $this->render("watch/watch.html.twig", [
|
||||||
|
"viewToken" => $viewToken,
|
||||||
"thumbnail" => $this->generateUrl("app_watch_thumbnail", [
|
"thumbnail" => $this->generateUrl("app_watch_thumbnail", [
|
||||||
"linkId" => $linkId,
|
"linkId" => $linkId,
|
||||||
"videoId" => $videoId
|
"videoId" => $videoId
|
||||||
|
@ -167,6 +211,7 @@ class WatchController extends AbstractController
|
||||||
"linkId" => $linkId,
|
"linkId" => $linkId,
|
||||||
"videoId" => $videoId
|
"videoId" => $videoId
|
||||||
]),
|
]),
|
||||||
|
"linkId" => $linkId,
|
||||||
"video" => $data["video"],
|
"video" => $data["video"],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
99
src/Entity/View.php
Normal file
99
src/Entity/View.php
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Entity;
|
||||||
|
|
||||||
|
use App\Repository\ViewRepository;
|
||||||
|
use DateTimeImmutable;
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Ramsey\Uuid\Doctrine\UuidGenerator;
|
||||||
|
use Ramsey\Uuid\UuidInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Entity(repositoryClass=ViewRepository::class)
|
||||||
|
* @ORM\Table(name="`view`")
|
||||||
|
*/
|
||||||
|
class View
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @ORM\Id
|
||||||
|
* @ORM\Column(type="uuid", unique=true)
|
||||||
|
* @ORM\GeneratedValue(strategy="CUSTOM")
|
||||||
|
* @ORM\CustomIdGenerator(class=UuidGenerator::class)
|
||||||
|
*/
|
||||||
|
private $id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\ManyToOne(targetEntity=Video::class)
|
||||||
|
* @ORM\JoinColumn(nullable=false)
|
||||||
|
*/
|
||||||
|
private $video;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\ManyToOne(targetEntity=VideoLink::class)
|
||||||
|
* @ORM\JoinColumn(nullable=false)
|
||||||
|
*/
|
||||||
|
private $link;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(type="datetime_immutable")
|
||||||
|
*/
|
||||||
|
private $timestamp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(type="datetime_immutable", nullable=true)
|
||||||
|
*/
|
||||||
|
private $validated;
|
||||||
|
|
||||||
|
public function getId(): ?UuidInterface
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getVideo(): ?Video
|
||||||
|
{
|
||||||
|
return $this->video;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setVideo(?Video $video): self
|
||||||
|
{
|
||||||
|
$this->video = $video;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLink(): ?VideoLink
|
||||||
|
{
|
||||||
|
return $this->link;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setLink(?VideoLink $link): self
|
||||||
|
{
|
||||||
|
$this->link = $link;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTimestamp(): ?DateTimeImmutable
|
||||||
|
{
|
||||||
|
return $this->timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setTimestamp(): self
|
||||||
|
{
|
||||||
|
$this->timestamp = new DateTimeImmutable();
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getValidated(): ?DateTimeImmutable
|
||||||
|
{
|
||||||
|
return $this->validated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setValidated(): self
|
||||||
|
{
|
||||||
|
$this->validated = new DateTimeImmutable();
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
61
src/Repository/ViewRepository.php
Normal file
61
src/Repository/ViewRepository.php
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Repository;
|
||||||
|
|
||||||
|
use App\Entity\View;
|
||||||
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @method View|null find($id, $lockMode = null, $lockVersion = null)
|
||||||
|
* @method View|null findOneBy(array $criteria, array $orderBy = null)
|
||||||
|
* @method View[] findAll()
|
||||||
|
* @method View[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
|
||||||
|
*/
|
||||||
|
class ViewRepository extends ServiceEntityRepository
|
||||||
|
{
|
||||||
|
public function __construct(ManagerRegistry $registry)
|
||||||
|
{
|
||||||
|
parent::__construct($registry, View::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * @return View[] Returns an array of View objects
|
||||||
|
// */
|
||||||
|
/*
|
||||||
|
public function findByExampleField($value)
|
||||||
|
{
|
||||||
|
return $this->createQueryBuilder('v')
|
||||||
|
->andWhere('v.exampleField = :val')
|
||||||
|
->setParameter('val', $value)
|
||||||
|
->orderBy('v.id', 'ASC')
|
||||||
|
->setMaxResults(10)
|
||||||
|
->getQuery()
|
||||||
|
->getResult()
|
||||||
|
;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
public function findOneBySomeField($value): ?View
|
||||||
|
{
|
||||||
|
return $this->createQueryBuilder('v')
|
||||||
|
->andWhere('v.exampleField = :val')
|
||||||
|
->setParameter('val', $value)
|
||||||
|
->getQuery()
|
||||||
|
->getOneOrNullResult()
|
||||||
|
;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
public function save(View $view)
|
||||||
|
{
|
||||||
|
$this->_em->persist($view);
|
||||||
|
$this->_em->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update()
|
||||||
|
{
|
||||||
|
$this->_em->flush();
|
||||||
|
}
|
||||||
|
}
|
57
src/Service/LoggingService.php
Normal file
57
src/Service/LoggingService.php
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Service;
|
||||||
|
|
||||||
|
|
||||||
|
use App\Entity\Video;
|
||||||
|
use App\Entity\VideoLink;
|
||||||
|
use App\Entity\View;
|
||||||
|
use App\Repository\ViewRepository;
|
||||||
|
use Ramsey\Uuid\UuidInterface;
|
||||||
|
|
||||||
|
class LoggingService
|
||||||
|
{
|
||||||
|
|
||||||
|
private $viewRepository;
|
||||||
|
|
||||||
|
public function __construct(ViewRepository $viewRepository)
|
||||||
|
{
|
||||||
|
$this->viewRepository = $viewRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createView(Video $video, VideoLink $link): UuidInterface
|
||||||
|
{
|
||||||
|
$view = new View();
|
||||||
|
$view->setVideo($video);
|
||||||
|
$view->setLink($link);
|
||||||
|
$view->setTimestamp();
|
||||||
|
|
||||||
|
$this->viewRepository->save($view);
|
||||||
|
|
||||||
|
return $view->getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function validateView(Video $video, VideoLink $link, UuidInterface $viewId): bool
|
||||||
|
{
|
||||||
|
$view = $this->viewRepository->findOneById($viewId);
|
||||||
|
if (!$view) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($view->getVideo() != $video) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ($view->getLink() != $link) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ($view->getValidated()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$view->setValidated();
|
||||||
|
$this->viewRepository->update();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -65,7 +65,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<div class="link">
|
<div class="link">
|
||||||
<a href="{{ path("app_new_link") }}?video={{ video.customId }}">
|
<a href="{{ path("app_new_link") }}?video={{ video.customId | url_encode }}">
|
||||||
<i class="fas fa-link"></i>
|
<i class="fas fa-link"></i>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -18,6 +18,31 @@
|
||||||
// enable quality selector
|
// enable quality selector
|
||||||
videojs('video').hlsQualitySelector();
|
videojs('video').hlsQualitySelector();
|
||||||
</script>
|
</script>
|
||||||
|
<script>
|
||||||
|
{% if viewToken %}
|
||||||
|
(function () {
|
||||||
|
let player = videojs('video');
|
||||||
|
//let target = {{ video.length > 120 ? 60 : video.length * 0.5 }};
|
||||||
|
let target = 10;
|
||||||
|
let current = 0;
|
||||||
|
setInterval(function () {
|
||||||
|
console.log(!player.paused() + ", " + current + ", " + target);
|
||||||
|
if (!player.paused()) {
|
||||||
|
current++;
|
||||||
|
|
||||||
|
if (current === target) {
|
||||||
|
ajaxPost("{{ path("app_watch_view", {
|
||||||
|
linkId: linkId,
|
||||||
|
videoId: video.customId,
|
||||||
|
viewId: viewToken
|
||||||
|
}) }}", null, function () {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
})()
|
||||||
|
{% endif %}
|
||||||
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
|
|
Loading…
Reference in a new issue