Skip to content
Snippets Groups Projects
Commit d5d4c11f authored by Sebastien's avatar Sebastien
Browse files

Merge branch 'tuleap-139-fix-capsule-time-loading-regression' into 'main'

Close tuleap-139-fix-capsule-time-loading-regression

See merge request !49
parents c429b876 1e308260
No related branches found
No related tags found
1 merge request!49tuleap-139-fix-capsule-time-loading-regression
Pipeline #783 passed
assets/images/project_not_found.jpg

4.81 KiB

......@@ -22,10 +22,14 @@ use Symfony\Contracts\Translation\TranslatorInterface;
class CapsuleController extends AbstractController
{
private CapsuleRepository $capsule_repository;
private TranslatorInterface $translator;
public function __construct(TranslatorInterface $translator)
{
public function __construct(
CapsuleRepository $capsule_repository,
TranslatorInterface $translator
) {
$this->capsule_repository = $capsule_repository;
$this->translator = $translator;
}
......@@ -94,7 +98,7 @@ class CapsuleController extends AbstractController
{
$file_path = '../legacy/' . $path;
if (!file_exists($file_path)) {
return $this->render('capsule/capsule_not_found.html.twig');
return $this->render('project/project_not_found.html.twig');
}
$url = $this->getParameter('app.legacy_external_prefix') . '/' . $path . "/?w=1";
......@@ -108,7 +112,7 @@ class CapsuleController extends AbstractController
/**
* @Route("capsule/edit/{path}", name="edit_capsule")
*/
public function edit(string $path, CapsuleRepository $capsuleRepository, TranslatorInterface $translator): Response
public function edit(string $path): Response
{
$current_user = $this->getUser();
......@@ -116,21 +120,20 @@ class CapsuleController extends AbstractController
return $this->redirectToRoute('app_logout');
}
$capsule = $capsuleRepository->findOneBy(['link_path' => $path]);
$capsule = $this->capsule_repository->findOneBy(['link_path' => $path]);
if (null === $capsule) {
$this->addFlash('warning', $translator->trans('capsule.edit.not_found'));
$this->addFlash('warning', $this->translator->trans('capsule.edit.not_found'));
return $this->redirectToRoute('capsule_list');
}
if (! $capsule->getEditors()->contains($current_user)) {
$this->addFlash('warning', $translator->trans('capsule.edit.not_allowed'));
$this->addFlash('warning', $this->translator->trans('capsule.edit.not_allowed'));
return $this->redirectToRoute('capsule_list');
}
$file_path = '../legacy/' . $path;
if (!file_exists($file_path)) {
return $this->render('capsule/capsule_not_found.html.twig');
return $this->render('project/project_not_found.html.twig');
}
$url = $this->getParameter('app.legacy_external_prefix') . '/' . $capsule->getEditionLink();
......
......@@ -3,10 +3,12 @@
namespace App\Entity;
use App\Entity\User;
use App\Retriever\ProjectRetriever;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Security\Core\User\UserInterface;
/**
......@@ -209,4 +211,24 @@ class Capsule
{
return $this->editors;
}
public function getVideoPreviewImageLink(): ?string
{
$file_system = new Filesystem();
if (! $file_system->exists('../legacy/' . $this->getLinkPath())) {
return null;
}
$project_retriever = new ProjectRetriever($this);
$video_url = $project_retriever->getVideoUrl();
$video_id = $project_retriever->getVideoId($video_url);
if (strpos($video_url, 'yout') !== false) {
return 'https://img.youtube.com/vi/' . $video_id . '/maxresdefault.jpg';
}
return 'https://vumbnail.com/' . $video_id . '.jpg';
}
}
<?php
namespace App\Retriever;
use App\Entity\Capsule;
class ProjectRetriever
{
private Capsule $capsule;
public function __construct(Capsule $capsule)
{
$this->capsule = $capsule;
}
private static function getDomDocument(): \DOMDocument
{
chdir('../legacy/');
$dom_xml = new \DOMDocument();
$dom_xml->preserveWhiteSpace = false;
return $dom_xml;
}
public function getVideoUrl(): string
{
$dom_xml = self::getDomDocument();
$dom_xml->load($this->capsule->getLinkPath() . '/file/project.xml');
$video_node = $dom_xml->getElementsByTagName('video')->item(0);
if ($video_node === null) {
throw new \Exception("Video node could not be found in XML project file");
}
return $video_node->getAttribute('url');
}
public function getVideoId(string $video_url): string
{
if (strpos($video_url, "vimeo")) {
return $this->getVimeoVideoIdFromUrl($video_url);
}
return $this->getYoutubeVideoIdFromUrl($video_url);
}
private function getYoutubeVideoIdFromUrl(string $video_url): string
{
$pattern = "#(?<=v=|v\/|vi=|vi\/|youtu.be\/)[a-zA-Z0-9_-]{11}#";
$result = preg_match($pattern, $video_url, $matches);
$video_id = "";
if (false !== $result) {
$video_id = $matches[0];
}
return $video_id;
}
private function getVimeoVideoIdFromUrl(string $video_url): string
{
$video_id = "";
$pattern = "/https?:\/\/(?:www\.)?vimeo.com\/(?:channels\/(?:\w+\/)?|groups\/([^\/]*)\/videos\/|album\/(\d+)\/video\/|)(\d+)(?:$|\/|\?)/"; //phpcs:ignore
if (preg_match($pattern, $video_url, $id)) {
$video_id = $id[3];
}
return $video_id;
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{% block title %}MemoRekall{% endblock %}</title>
{% block stylesheets %}
{{ encore_entry_link_tags('app') }}
{% endblock %}
{% block javascripts %}
{{ encore_entry_script_tags('app') }}
{% endblock %}
<link rel="icon" type="image/x-icon" href="{{ asset('build/images/favicon.ico') }}" />
</head>
<body class="container col-10 col-md-8 col-lg-6 m-auto">
<div class="position-relative d-flex flex-row align-items-center justify-content-center mb-5">
<img id="header-memorekall-logo" class="memorekall-logo" src="{{ asset('build/images/MemoRekall.png') }}">
</div>
<div class="m-auto d-flex flex-row align-items-center justify-content-center mb-5 alert alert-warning" role="status">
<span class="p-5">{{ 'capsule.not_found' | trans }}</span>
</div>
</body>
</html>
......@@ -56,11 +56,11 @@
<div class="d-flex flex-column flex-md-row justify-content-center align-items-center">
<div class="m-4 ratio ratio-16x9">
<iframe
src="/capsule/preview/{{ capsule.getLinkPath() }}"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen>
</iframe>
{% if capsule.getVideoPreviewImageLink() is null %}
<img src="{{ asset('build/images/project_not_found.jpg') }}" alt="video preview">
{% else %}
<img src="{{ capsule.getVideoPreviewImageLink() }}" alt="video preview">
{% endif %}
</div>
<div class="d-flex flex-column justify-content-center m-2 pe-2">
......
{% extends 'layout.html.twig' %}
{% block title %}
{{ 'project.not_exist'|trans }}
-
{{ parent() }}
{% endblock %}
{% block body %}
<div class="col-10 col-md-8 col-lg-6 col-xl-5 col-xxl-6 m-auto d-flex flex-row align-items-center justify-content-center mb-5 alert alert-warning" role="status">
<span class="p-5">{{ 'project.not_exist' | trans }}</span>
</div>
{% endblock %}
\ No newline at end of file
......@@ -45,7 +45,7 @@ class CapsuleControllerTest extends WebTestCase
$submit_button = $crawler->selectButton('Create a capsule');
$form = $submit_button->form();
$video_url = "https://TestUrl";
$video_url = "https://www.youtube.com/watch?v=dQw4w9WgXcQ&ab_channel=RickAstley";
$form['create_capsule_form[name]'] = self::CAPSULE_NAME;
$form['create_capsule_form[video_url]'] = $video_url;
......
......@@ -86,7 +86,7 @@ class ProjectControllerTest extends WebTestCase
$submit_button = $crawler->selectButton('Create a capsule');
$this->form = $submit_button->form();
$video_url = "https://TestUrl";
$video_url = "https://www.youtube.com/watch?v=dQw4w9WgXcQ&ab_channel=RickAstley";
$this->form['create_capsule_form[name]'] = self::CAPSULE_NAME;
$this->form['create_capsule_form[video_url]'] = $video_url;
......@@ -123,7 +123,7 @@ class ProjectControllerTest extends WebTestCase
$video_url_in_xml_file = $video_node->getAttribute('url');
$this->assertEquals($video_url, $video_url_in_xml_file);
$this->assertEquals($video_url, htmlspecialchars_decode($video_url_in_xml_file));
$this->assertSame(self::CAPSULE_NAME, $capsule_name_in_db);
}
......@@ -293,7 +293,7 @@ class ProjectControllerTest extends WebTestCase
$submit_button = $crawler->selectButton('Create a capsule');
$this->form = $submit_button->form();
$video_url = "https://TestUrl";
$video_url = "https://www.youtube.com/watch?v=dQw4w9WgXcQ&ab_channel=RickAstley";
$this->form['create_capsule_form[name]'] = self::CAPSULE_NAME;
$this->form['create_capsule_form[video_url]'] = $video_url;
......
......@@ -114,46 +114,3 @@ user:
updated_success: The password has been updated
edit_profile: Edit my profile
edit_password: Edit my password
\ No newline at end of file
editors:
title: Editors
title_name: Editors of capsule %capsule_name%
add_email_address: Add new editor with email address
current_editors_title: Current editors
pending_editors_title: Pending editors
user_not_editor_error: You are not editor of the capsule
add:
pending_editor:
success: The user user_email has been added to pending editor list.
He will receive an email to invite him register on MemoRekall and to inform him he has been added as an editor of this capsule.
already_added: The user user_email has already been added to pending editor list
email:
title: Invitation to edit a MemoRekall capsule
text: You have been added by %user_name% as editor of the capsule "%capsule_name%".
In order to access and edit it, you first need to register on MemoRekall. Please follow this link to
link: https://project.memorekall.com/register/
link_name: register
user:
success: The user user_email is now an editor of the capsule capsule_name.
He will receive an email to inform him he has been added as an editor of this capsule.
already_added: The user user_email is already an editor of this capsule
email:
title: New capsule on your list
text: You have been add by %user_name% as editor of the capsule "%capsule_name%".
You can now access and edit it. You will find the capsule in your capsule list.
link: Go to capsule edition page
remove:
button: Remove
pending_editor:
title: Remove pending editor
text: Do you really want to delete pending editor %editor_email%?
link: Remove pending editor
error: The email address has already been removed from pending editors of the capsule capsule_name
success: The email address pending_editor_email has been successfully removed from pending editors of the capsule capsule_name
editor:
title: Remove editor
text: Do you really want to delete editor %editor_email%?
link: Remove editor
success: User editor_email is no longer and editor of the capsule capsule_name
error: You can't remove yourself as editor of your own capsule.
If you want to remove the capsule from your list, go to the capsule list page and click on "delete capsule"
\ No newline at end of file
......@@ -62,6 +62,7 @@ capsule:
created_success: La capsule capsule_name a été créée
no_edition_access: Pas d'accès au mode édition
contact_capsule_author_for_access: Veuillez contacter l'auteur de la capsule pour lui demander son accès en mode édition
not_found: Le projet n'existe pas
edit_permissions:
link: Modifier les permissions
edit:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment