add files in StlMesh
This commit is contained in:
parent
478d584047
commit
9415ddfccd
|
@ -795,6 +795,16 @@ $links: (
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
padding-right: 10px;
|
padding-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-file {
|
||||||
|
ul {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-name {
|
||||||
|
min-width: 100px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 1280px) {
|
@media screen and (max-width: 1280px) {
|
||||||
|
|
|
@ -26,26 +26,40 @@ class StlMeshController extends PageController
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/mesh/download/{stlMesh}", name="mesh_download")
|
* @Route("/mesh/download/{stlMesh}/{key}", name="mesh_download")
|
||||||
*/
|
*/
|
||||||
public function download(StlMesh $stlMesh): Response
|
public function download(StlMesh $stlMesh, int $key): Response
|
||||||
{
|
{
|
||||||
$response = new BinaryFileResponse($stlMesh->getFile());
|
$file = $stlMesh->getFiles()[--$key] ?? null;
|
||||||
|
|
||||||
|
if (null === $file) {
|
||||||
|
throw $this->createNotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
$response = new BinaryFileResponse($file['file']);
|
||||||
$response->setContentDisposition(
|
$response->setContentDisposition(
|
||||||
ResponseHeaderBag::DISPOSITION_ATTACHMENT,
|
ResponseHeaderBag::DISPOSITION_ATTACHMENT,
|
||||||
str_replace('.bin', '.stl', basename($stlMesh->getFile()))
|
sprintf('%s.stl', $file['name'])
|
||||||
);
|
);
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/mesh/viewer/{stlMesh}", name="mesh_viewer")
|
* @Route("/mesh/viewer/{stlMesh}/{key}", name="mesh_viewer")
|
||||||
*/
|
*/
|
||||||
public function viewer(StlMesh $stlMesh): Response
|
public function viewer(StlMesh $stlMesh, int $key): Response
|
||||||
{
|
{
|
||||||
|
$file = $stlMesh->getFiles()[--$key] ?? null;
|
||||||
|
|
||||||
|
if (null === $file) {
|
||||||
|
throw $this->createNotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
return $this->render('page/mesh/viewer.html.twig', [
|
return $this->render('page/mesh/viewer.html.twig', [
|
||||||
'mesh' => $stlMesh,
|
'mesh' => $stlMesh,
|
||||||
|
'file' => $file,
|
||||||
|
'key' => $key + 1,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,11 @@ class StlMesh implements EntityInterface
|
||||||
*/
|
*/
|
||||||
private $file;
|
private $file;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(type="array", nullable=true)
|
||||||
|
*/
|
||||||
|
private $files = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="string", length=255, nullable=true)
|
* @ORM\Column(type="string", length=255, nullable=true)
|
||||||
*/
|
*/
|
||||||
|
@ -107,4 +112,30 @@ class StlMesh implements EntityInterface
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getFiles(): ?array
|
||||||
|
{
|
||||||
|
$this->files = (array) $this->files;
|
||||||
|
|
||||||
|
usort($this->files, function($a, $b) {
|
||||||
|
if ($a['position'] > $b['position']) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($a['position'] < $b['position']) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
return $this->files;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setFiles(?array $files): self
|
||||||
|
{
|
||||||
|
$this->files = $files;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
51
src/Form/StlFileType.php
Normal file
51
src/Form/StlFileType.php
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Form;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
use App\Core\Form\FileManager\FilePickerType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
|
||||||
|
use Symfony\Component\Validator\Constraints\NotBlank;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||||
|
|
||||||
|
class StlFileType extends AbstractType
|
||||||
|
{
|
||||||
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
|
{
|
||||||
|
$builder->add('position', HiddenType::class);
|
||||||
|
|
||||||
|
$builder->add(
|
||||||
|
'name',
|
||||||
|
TextType::class,
|
||||||
|
[
|
||||||
|
'label' => 'Nom',
|
||||||
|
'required' => true,
|
||||||
|
'attr' => [
|
||||||
|
],
|
||||||
|
'constraints' => [
|
||||||
|
new NotBlank(),
|
||||||
|
],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$builder->add(
|
||||||
|
'file',
|
||||||
|
FilePickerType::class,
|
||||||
|
[
|
||||||
|
'label' => false,
|
||||||
|
'required' => true,
|
||||||
|
'constraints' => [
|
||||||
|
],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
|
{
|
||||||
|
$resolver->setDefaults([
|
||||||
|
// Configure your form options here
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,14 +2,15 @@
|
||||||
|
|
||||||
namespace App\Form;
|
namespace App\Form;
|
||||||
|
|
||||||
|
use App\Core\Form\FileManager\FilePickerType;
|
||||||
|
use App\Core\Form\Type\CollectionType as MurphCollectionType;
|
||||||
use App\Entity\StlMesh;
|
use App\Entity\StlMesh;
|
||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
use Symfony\Component\Validator\Constraints\NotBlank;
|
use Symfony\Component\Validator\Constraints\NotBlank;
|
||||||
use App\Core\Form\FileManager\FilePickerType;
|
|
||||||
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
|
|
||||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
|
||||||
|
|
||||||
class StlMeshType extends AbstractType
|
class StlMeshType extends AbstractType
|
||||||
{
|
{
|
||||||
|
@ -57,6 +58,19 @@ class StlMeshType extends AbstractType
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$builder->add(
|
||||||
|
'files',
|
||||||
|
MurphCollectionType::class,
|
||||||
|
[
|
||||||
|
'label' => 'Fichiers STL',
|
||||||
|
'entry_type' => StlFileType::class,
|
||||||
|
'by_reference' => false,
|
||||||
|
'allow_add' => true,
|
||||||
|
'allow_delete' => true,
|
||||||
|
'prototype' => true,
|
||||||
|
'collection_name' => 'stlfiles',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
$builder->add(
|
$builder->add(
|
||||||
'preview',
|
'preview',
|
||||||
|
|
|
@ -30,26 +30,31 @@
|
||||||
<div class="col-4 mesh-wrapper">
|
<div class="col-4 mesh-wrapper">
|
||||||
<div class="mesh">
|
<div class="mesh">
|
||||||
<div class="mesh-preview">
|
<div class="mesh-preview">
|
||||||
<a data-modal href="{{ path('mesh_viewer', {stlMesh: mesh.id}) }}">
|
<img src="{{ asset(mesh.preview)|imagine_filter('mesh_preview_filter') }}" alt="{{ mesh.label }}">
|
||||||
<img src="{{ asset(mesh.preview)|imagine_filter('mesh_preview_filter') }}" alt="{{ mesh.label }}">
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
<h2 class="mesh-title">{{ mesh.label }}</h2>
|
<h2 class="mesh-title">{{ mesh.label }}</h2>
|
||||||
<div class="mesh-description">
|
<div class="mesh-description">
|
||||||
{{ mesh.description|murph_url|file_attributes|markdown('post') }}
|
{{ mesh.description|murph_url|file_attributes|markdown('post') }}
|
||||||
|
|
||||||
<ul class="list--inline">
|
{% for key, item in mesh.files %}
|
||||||
<li>
|
<div class="mesh-file">
|
||||||
<a class="button small mesh-viewer" data-modal href="{{ path('mesh_viewer', {stlMesh: mesh.id}) }}">
|
<ul class="list--inline">
|
||||||
Visualiser en 3D
|
<li class="mesh-name">
|
||||||
</a>
|
{{ item.name }}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a class="button small" target="_blank" href="{{ path('mesh_download', {stlMesh: mesh.id}) }}">
|
<a class="button small mesh-viewer" data-modal href="{{ path('mesh_viewer', {stlMesh: mesh.id, key: key + 1}) }}">
|
||||||
Télécharger
|
Voir en 3D
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
<li>
|
||||||
|
<a class="button small" target="_blank" href="{{ path('mesh_download', {stlMesh: mesh.id, key: key + 1}) }}">
|
||||||
|
Télécharger
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>{{ mesh.label }}</title>
|
<title>{{ mesh.label }} / {{ file.name }}</title>
|
||||||
{{ encore_entry_link_tags('viewer') }}
|
{{ encore_entry_link_tags('viewer') }}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="mesh-viewer" data-file="{{ path('mesh_download', {stlMesh: mesh.id}) }}"></div>
|
<div id="mesh-viewer" data-file="{{ path('mesh_download', {stlMesh: mesh.id, key: key}) }}"></div>
|
||||||
|
|
||||||
<script src="{{ asset('stl_viewer/stl_viewer.min.js') }}"></script>
|
<script src="{{ asset('stl_viewer/stl_viewer.min.js') }}"></script>
|
||||||
{{ encore_entry_script_tags('viewer') }}
|
{{ encore_entry_script_tags('viewer') }}
|
||||||
|
|
Loading…
Reference in a new issue