Skip to content
Snippets Groups Projects
Commit 933acce9 authored by Camille Simiand's avatar Camille Simiand
Browse files

Clean files

parent b334513a
Branches
Tags
1 merge request!32tuleap-50-create-a-capsule-for-an-unexisting-project-in-the-legacy
......@@ -3,14 +3,14 @@
ServerAlias www.project.memorekall.com
DocumentRoot /sites/memorekall/www/web_dev/public
DirectoryIndex /index1.php
DirectoryIndex /index.php
<Directory /sites/memorekall/www/web_dev/public>
Require all granted
AllowOverride None
Order Allow,Deny
Allow from All
FallbackResource /index1.php
FallbackResource /index.php
RewriteEngine on
</Directory>
ErrorLog /sites/memorekall/www/web_dev/log/memorekall_member_error.log
......
<?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 Version20211230115034 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 capsule (id INT AUTO_INCREMENT NOT NULL, aut_crea INT DEFAULT NULL, aut_maj INT DEFAULT NULL, nom VARCHAR(255) NOT NULL, dt_crea DATETIME NOT NULL, dt_maj DATETIME NOT NULL, link VARCHAR(255) NOT NULL, edition_link VARCHAR(255) NOT NULL, INDEX IDX_C268A183B11ABDF2 (aut_crea), INDEX IDX_C268A183E5F0D775 (aut_maj), UNIQUE INDEX index_capsule_nom (nom), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB');
$this->addSql('CREATE TABLE editeur_capsule (capsule_id INT NOT NULL, user_id INT NOT NULL, INDEX IDX_A18592E2714704E9 (capsule_id), INDEX IDX_A18592E2A76ED395 (user_id), PRIMARY KEY(capsule_id, user_id)) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB');
$this->addSql('ALTER TABLE capsule ADD CONSTRAINT FK_C268A183B11ABDF2 FOREIGN KEY (aut_crea) REFERENCES `user` (id)');
$this->addSql('ALTER TABLE capsule ADD CONSTRAINT FK_C268A183E5F0D775 FOREIGN KEY (aut_maj) REFERENCES `user` (id)');
$this->addSql('ALTER TABLE editeur_capsule ADD CONSTRAINT FK_A18592E2714704E9 FOREIGN KEY (capsule_id) REFERENCES capsule (id)');
$this->addSql('ALTER TABLE editeur_capsule ADD CONSTRAINT FK_A18592E2A76ED395 FOREIGN KEY (user_id) REFERENCES `user` (id)');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE editeur_capsule DROP FOREIGN KEY FK_A18592E2714704E9');
$this->addSql('DROP TABLE capsule');
$this->addSql('DROP TABLE editeur_capsule');
}
}
......@@ -4,15 +4,9 @@ namespace App\Controller;
use App\Entity\Capsule;
use App\Form\CreateCapsuleFormType;
use App\LegacyHelper;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\File\Exception\FileException;
use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Uid\Uuid;
......@@ -56,10 +50,7 @@ class CapsuleController extends AbstractController
$entityManager->persist($capsule);
$entityManager->flush();
// $this->redirectToRoute('create_project', [$capsule_name, $video_url]);
return $this->forward('App\Controller\ProjectController::create', [
'request' => $request,
'capsule_name' => $capsule_name,
'video_url' => $video_url
]);
......
......@@ -3,7 +3,7 @@
namespace App\Controller;
use App\Entity\Capsule;
use App\LegacyHelper;
use App\Helper\LegacyHelper;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
......@@ -17,72 +17,13 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class FallbackController extends AbstractController
{
// /**
// * @Route("/", name="get_legacy_resource_creation", methods={"POST"}, priority=-2)
// * @Route("/{controller}", name="get_legacy_resource_creation_index",
// * requirements={"controller" = "index1.php"}, priority=-1)
// */
// public function getCreationCapsuleAction(Request $request, $controller = null)
// {
//
// // $_POST parameters
// $capsuleName = $request->request->get('create');
// $capsulePass = $request->request->get('p');
// $capsuleLink = $this->sanitize($capsuleName);
//
// $this->denyAccessUnlessGranted('IS_AUTHENTICATED_REMEMBERED');
// $user = $this->getUser();
//
// /*
// // memorykall legacy affichera un message si champ vide
// //bloquer les noms à null
// if($capsuleName == null || $capsuleName == '')
// {
// // rediriger sur une page demandant un nom
// return $this->redirectToRoute('missing_name');
// }*/
//
//// TODO : the following code MUST be re-enabled with tuleap-51
//// // check if capsule exist in database
//// $capByName = $this->getDoctrine()
//// ->getManager()
//// ->getRepository('AppBundle:Capsule')
//// ->findOneByNom($capsuleName)
//// ;
//// $capByLink = $this->getDoctrine()
//// ->getManager()
//// ->getRepository('AppBundle:Capsule')
//// ->findOneByLink($capsuleLink)
//// ;
//// if (!$capByName instanceof Capsule && !$capByLink instanceof Capsule) {
//// $dateCreation = new \DateTime();
//// $cap = new Capsule();
//// $cap->setNom($capsuleName);
//// $cap->setLink($capsuleLink);
//// $cap->setEditionLink($capsuleLink.'/?p='.$capsulePass);
//// $cap->setAutCrea($user);
//// $cap->setDtCrea($dateCreation);
//// $cap->setDtMaj($dateCreation);
//// $cap->addEditeur($user);
////
//// $em = $this->getDoctrine()->getManager();
//// $em->persist($cap);
//// $em->flush();
//// }
//// // si la capsule existe déjà memorkall legacy affichera un message capsule existe déjà
//
// $response = $this->transfertToLegacy($request);
// return $response;
// }
/**
* @Route("/", name="get_legacy_resource", priority=-2)
* @Route("/{controller}", name="get_legacy_resource", requirements={"controller" = ".+"}, priority=-1)
*/
public function getLegacyResourceAction(Request $request, $controller = null)
public function getLegacyResourceAction(Request $request, $controller = null): Response
{
// $logger = $this->get('logger');
// check if capsule edition (pôst or get)
// check if capsule edition (post or get)
if ($request->query->has('p') || $request->request->has('p')) {
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_REMEMBERED');
$user = $this->getUser();
......@@ -130,7 +71,6 @@ class FallbackController extends AbstractController
// $em->flush();
}
if ($controller == null) {
//if no controller, this is index1.php
return $this->redirectToRoute('get_legacy_resource', array('controller' => 'index1.php'));
......
......@@ -2,59 +2,93 @@
namespace App\Controller;
use App\LegacyHelper;
use _PHPStan_c862bb974\Nette\Neon\Exception;
use App\Exception\ZipArchiveNotOpeningException;
use App\Helper\LegacyHelper;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Config\Util\Exception\XmlParsingException;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Contracts\Translation\TranslatorInterface;
use ZipArchive;
use function PHPUnit\Framework\throwException;
class ProjectController extends AbstractController
{
/**
* @Route("/project/create", name="create_project", methods={"POST"})
* @throws ZipArchiveNotOpeningException
*/
public function create(
Request $request,
TranslatorInterface $translator,
string $capsule_name,
string $video_url
) {
$retours = array("success" => 0, "error" => "", "value" => "");
): RedirectResponse {
chdir('../legacy/');
if(! file_exists($capsule_name)) {
$zip = new ZipArchive;
$zip_file_archive = $zip->open("create.zip");
if ($zip_file_archive) {
$zip->extractTo($capsule_name);
$zip->close();
if (file_exists($capsule_name)) {
$this->addFlash(
'project_already_exists',
$translator->trans(
'project.already_exists',
[
'capsule_name' => $capsule_name
]
)
);
file_put_contents(
$capsule_name."/file/project.xml",
str_replace("__video__",
$video_url,
file_get_contents($capsule_name."/file/project.xml"
)));
// TODO: Refacto
$retours["success"] = 1;
} else {
$retours["success"] = -1;
$retours["error"] = "No seed found";
}
return $this->redirectToRoute('capsule_list');
}
else {
$retours["success"] = 0;
$retours["error"] = "Project already exists";
$zip = new ZipArchive();
$zip_file_archive_is_open = $zip->open("create.zip");
if (! $zip_file_archive_is_open) {
throw new ZipArchiveNotOpeningException("Create Zip Archive could not be open");
}
$retours["value"] = $capsule_name;
$this->extractZipArchiveInNewCapsuleDirectory($zip, $capsule_name);
$video_url_XML_tag_is_filled = $this->addProjectVideoUrlInXMLProjectFile($capsule_name, $video_url);
if (! $video_url_XML_tag_is_filled) {
throw new XmlParsingException('Video URL could not be written in XML project file');
}
$this->addFlash(
'flashSuccess',
'La capsule ' . $capsule_name . ' a bien été créée.'
'capsule_created_success',
$translator->trans(
'capsule.created_success',
[
'capsule_name' => $capsule_name
]
)
);
return $this->redirectToRoute('capsule_list');
}
private function extractZipArchiveInNewCapsuleDirectory(ZipArchive $zip, string $capsule_name): void
{
$zip->extractTo($capsule_name);
$zip->close();
}
/**
* @return false|int
*/
private function addProjectVideoUrlInXMLProjectFile(string $capsule_name, string $video_url)
{
$project_xml_file = $capsule_name . "/file/project.xml";
return file_put_contents(
$project_xml_file,
str_replace(
"__video__",
$video_url,
file_get_contents($project_xml_file)
)
);
}
}
<?php
namespace App\Curl;
use App\Exception\CurlInitFailedException;
class CurlHandle
{
/**
* @var resource
*/
private $curl_handler;
public function __construct()
{
$curl_init = curl_init();
if ($curl_init == false) {
throw new CurlInitFailedException();
}
$this->curl_handler = $curl_init;
}
public function setOptions(array $options_array): void
{
curl_setopt_array($this->curl_handler, $options_array);
}
/**
* @return bool|string
*/
public function execute()
{
return curl_exec($this->curl_handler);
}
/**
* @return mixed
*/
public function getInfo(int $name)
{
return curl_getinfo($this->curl_handler, $name);
}
public function getErrorMessage(): string
{
return curl_error($this->curl_handler) . curl_errno($this->curl_handler);
}
public function close(): void
{
curl_close($this->curl_handler);
}
}
......@@ -88,56 +88,68 @@ class Capsule
$this->editors = new ArrayCollection();
}
public function getId() {
public function getId(): int
{
return $this->id;
}
public function setId($id) {
public function setId(int $id): Capsule
{
$this->id = $id;
return $this;
}
public function getName() {
public function getName(): string
{
return $this->name;
}
public function setName($name) {
public function setName(string $name): Capsule
{
$this->name = $name;
return $this;
}
public function getCreationAuthor() {
public function getCreationAuthor(): User
{
return $this->creation_author;
}
public function setCreationAuthor($creation_author) {
public function setCreationAuthor(User $creation_author): Capsule
{
$this->creation_author = $creation_author;
return $this;
}
public function getCreationDate() {
public function getCreationDate(): \DateTime
{
return $this->creation_date;
}
public function setCreationDate($creation_date) {
public function setCreationDate(\DateTime $creation_date): Capsule
{
$this->creation_date = $creation_date;
return $this;
}
public function getPreviewLink() {
public function getPreviewLink(): string
{
return $this->preview_link;
}
public function setPreviewLink(string $preview_link) {
public function setPreviewLink(string $preview_link): Capsule
{
$this->preview_link = $preview_link;
return $this;
}
public function getEditionLink() {
public function getEditionLink(): string
{
return $this->edition_link;
}
public function setEditionLink($edition_link) {
public function setEditionLink(string $edition_link): Capsule
{
$this->edition_link = $edition_link;
return $this;
}
......@@ -157,12 +169,12 @@ class Capsule
return $this->updated_date;
}
public function setUpdatedDate(\DateTime $update_date)
public function setUpdatedDate(\DateTime $update_date): void
{
$this->updated_date = $update_date;
}
public function addEditor(User $editor)
public function addEditor(User $editor): void
{
$editor->addCapsule($this);
$this->editors[] = $editor;
......
<?php
namespace App\Exception;
class CurlInitFailedException extends \Exception
{
}
<?php
namespace App\Exception;
use Throwable;
class ZipArchiveNotOpeningException extends \Exception
{
}
......@@ -13,7 +13,7 @@ use Symfony\Component\Validator\Constraints\NotBlank;
class CreateCapsuleFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add(
......@@ -22,7 +22,8 @@ class CreateCapsuleFormType extends AbstractType
[
'constraints' => [new NotBlank(['message' => 'capsule.name.not_blank'])],
'label' => 'capsule.name'
])
]
)
->add(
'video_url',
UrlType::class,
......@@ -30,7 +31,8 @@ class CreateCapsuleFormType extends AbstractType
'mapped' => false,
'constraints' => [new NotBlank(['message' => 'capsule.video_url.not_blank'])],
'label' => 'capsule.video_url'
])
]
)
->add(
'save',
SubmitType::class,
......@@ -38,7 +40,7 @@ class CreateCapsuleFormType extends AbstractType
);
}
public function configureOptions(OptionsResolver $resolver)
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => Capsule::class,
......
<?php
namespace App;
namespace App\Helper;
use App\Curl\CurlHandle;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\File\Exception\FileException;
use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
......@@ -12,99 +13,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class LegacyHelper
{
public static function transferToLegacy(
Request $request,
string $legacy_external_prefix,
string $legacy_url
): Response
{
$originalController = preg_replace(
"@^$legacy_external_prefix@",
'',
$request->getPathInfo());
$project_directory_name = $request->get('capsule_name');
$originalQueryString = $request->getQueryString();
//@TODO : delete on linux server
// $originalController = str_replace("/", "\\", $originalController); //windows
$extension = strrchr($originalController, '.');
if ($extension != '.html' && $extension != '.php' && $extension != false) {
$url = "{$originalController}";
try {
$mime = self::getMime($url, $extension);
$response = new BinaryFileResponse($url);
$response->headers->set('Content-Type', $mime ?: 'application/octet-stream');
return $response;
} catch (FileNotFoundException $e) {
// try normal access by url
}
}
$separator = '';
if (!$extension) {
$separator = '/';
}
$url = "{$legacy_url}{$originalController}{$separator}?{$originalQueryString}";
//open connection
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
if ($request->getMethod() == 'POST') {
$postParameters = $request->request->all()['create_capsule_form'];
error_log(print_r($postParameters, true));
// upload file to transfer
if (isset($_FILES['fileToUpload'])) {
$data = array(
'fileToUpload' => curl_file_create(
$_FILES['fileToUpload']['tmp_name'],
$_FILES['fileToUpload']['type'],
$_FILES['fileToUpload']['name']
)
);
$postParameters = array_merge($postParameters, $data);
curl_setopt($ch, CURLOPT_HEADER, 1);
}
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postParameters);
}
curl_setopt($ch, CURLOPT_COOKIESESSION, 0);
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt');
//execute post
$result = curl_exec($ch);
$contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
if ($result === false) {
$error_message = "Erreur - Page non trouvée : " .
curl_error($ch) .
' - ' . curl_errno($ch);
curl_close($ch);
throw new NotFoundHttpException($error_message);
}
curl_close($ch);
$response = new Response($result);
$response->headers->set('Content-Type', $contentType);
return $response;
}
public static function getMime($filename, $extension): ?string
{
$mime_types = [
private const MIME_TYPES = [
'txt' => 'text/plain',
'htm' => 'text/html',
'html' => 'text/html',
......@@ -162,17 +71,112 @@ class LegacyHelper
'ods' => 'application/vnd.oasis.opendocument.spreadsheet'
];
if (null === $filename) {
public static function transferToLegacy(
Request $request,
string $legacy_external_prefix,
string $legacy_url
): Response {
$originalController = preg_replace(
"@^$legacy_external_prefix@",
'',
$request->getPathInfo()
);
$originalQueryString = $request->getQueryString();
//@TODO : delete on linux server
// $originalController = str_replace("/", "\\", $originalController); //windows
$extension = strrchr($originalController, '.');
if ($extension != '.html' && $extension != '.php' && $extension != false) {
$file_path = "{$originalController}";
try {
$mime = self::getMime($file_path, $extension);
$response = new BinaryFileResponse($file_path);
$response->headers->set('Content-Type', $mime ?: 'application/octet-stream');
return $response;
} catch (FileNotFoundException $e) {
// try normal access by url
}
}
$separator = '';
if (!$extension) {
$separator = '/';
}
$url = "{$legacy_url}{$originalController}{$separator}?{$originalQueryString}";
$curl_handler = new CurlHandle();
$options_array = [
CURLOPT_URL => $url,
CURLOPT_HEADER => false,
CURLOPT_VERBOSE => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_COOKIESESSION => false,
CURLOPT_COOKIEFILE => 'cookies.txt',
CURLOPT_COOKIEJAR => 'cookies.txt'
];
$curl_handler->setOptions($options_array);
if ($request->getMethod() == 'POST') {
$postParameters = $request->request->all()['create_capsule_form'];
// upload file to transfer
if (isset($_FILES['fileToUpload'])) {
$data = [
'fileToUpload' => curl_file_create(
$_FILES['fileToUpload']['tmp_name'],
$_FILES['fileToUpload']['type'],
$_FILES['fileToUpload']['name']
)
];
$postParameters = array_merge($postParameters, $data);
$curl_handler->setOptions([CURLOPT_HEADER => true]);
}
$curl_handler->setOptions([
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $postParameters
]);
}
$result = $curl_handler->execute();
if (! $result) {
throw new NotFoundHttpException(
(int) $curl_handler->getInfo(CURLINFO_HTTP_CODE) .
$curl_handler->getErrorMessage()
);
}
$curl_handler->close();
$response = new Response($result);
$contentType = $curl_handler->getInfo(CURLINFO_CONTENT_TYPE);
$response->headers->set('Content-Type', $contentType);
return $response;
}
public static function getMime(?string $filepath, string $extension): ?string
{
if (null === $filepath) {
throw new \InvalidArgumentException('File cannot be null.');
}
$extension_without_dot = strtolower(str_replace('.', '', $extension));
if (array_key_exists($extension_without_dot, $mime_types)) {
return $mime_types[$extension_without_dot];
if (array_key_exists($extension_without_dot, self::MIME_TYPES)) {
return self::MIME_TYPES[$extension_without_dot];
}
$file = new File((string) $filename, true);
$file = new File($filepath, true);
if (! $file->isReadable()) {
throw new FileException('File must be readable.');
......
......@@ -8,11 +8,6 @@
{% block body %}
<div class="mt-4">
{% for flashSuccess in app.flashes('capsule_created_success') %}
<div class="alert alert-success col-6 mx-auto my-5 h1" role="alert">{{ flashSuccess }}</div>
{% endfor %}
<div class="d-flex justify-content-center align-items-center">
<form>
<button id="btn-orange" formaction="/create">
......@@ -20,5 +15,11 @@
</button>
</form>
</div>
{% for flashSuccess in app.flashes('capsule_created_success') %}
<div class="text-center alert alert-success col-5 mx-auto my-5" role="alert">
{{ flashSuccess }}
</div>
{% endfor %}
</div>
{% endblock %}
......@@ -27,6 +27,9 @@ reset_password:
message: Enter your email address and we will send you a link to reset your password.
button: Reset password
email:
address_verified: Your email address has been verified
check_email_reset_password:
title: Password Reset Email Sent
text: If an account matching your email exists, then an email was just sent that contains a link that you can use to reset your password.
......@@ -45,3 +48,7 @@ capsule:
create_capsule: Create a capsule
name: Name of the capsule
video_url: Youtube or Vimeo video URL
created_success: Capsule capsule_name was created successfully
project:
already_exists: Project capsule_name already exists so the capsule could not be created
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment