Commit fa897042 authored by Raidelet Nicolas's avatar Raidelet Nicolas Committed by Guillaume Perréal
Browse files

CS

parent 4cc11abe
......@@ -25,8 +25,7 @@ class CheckCommand extends ContainerAwareCommand
{
$this
->setName('irstea:file-upload:check')
->setDescription("Vérifie l'intégrité des fichiers.")
;
->setDescription("Vérifie l'intégrité des fichiers.");
}
protected function execute(InputInterface $input, OutputInterface $output)
......@@ -38,7 +37,7 @@ class CheckCommand extends ContainerAwareCommand
$files = $manager->findFilesToValidate();
if(count($files) == 0) {
if (count($files) == 0) {
$output->writeln('Aucun fichier à vérifier.');
return;
}
......@@ -48,9 +47,9 @@ class CheckCommand extends ContainerAwareCommand
$progress = new ProgressBar($output, count($files));
$progress->start();
foreach($files as $file){
foreach ($files as $file) {
$file->validate();
if(!$file->isValid()) {
if (!$file->isValid()) {
$output->writeln(sprintf("\nFichier %s: %s", $file->getEtat(), $file->getPath()));
$em->persist($file);
}
......
......@@ -26,8 +26,7 @@ class CollectGarbageCommand extends ContainerAwareCommand
$this
->setName('irstea:file-upload:collect-garbage')
->setDescription("Nettoie les fichiers orphelins et partiels.")
->addOption('dry-run', null, InputOption::VALUE_NONE, 'Affiche ce qui devrait être fait, sans le faire')
;
->addOption('dry-run', null, InputOption::VALUE_NONE, 'Affiche ce qui devrait être fait, sans le faire');
}
protected function execute(InputInterface $input, OutputInterface $output)
......@@ -37,12 +36,12 @@ class CollectGarbageCommand extends ContainerAwareCommand
$files = $manager->findGarbage();
if(count($files) == 0) {
if (count($files) == 0) {
$output->writeln('Aucun fichier à supprimer.');
return;
}
if($input->getOption('dry-run')) {
if ($input->getOption('dry-run')) {
$output->writeln(sprintf('%d fichier(s) à supprimer.', count($files)));
return;
}
......@@ -52,7 +51,7 @@ class CollectGarbageCommand extends ContainerAwareCommand
$progress = new ProgressBar($output, count($files));
$progress->start();
foreach($files as $file){
foreach ($files as $file) {
$manager->delete($file);
$progress->advance();
}
......
......@@ -30,8 +30,7 @@ class CreateCommand extends ContainerAwareCommand
->addOption('mime-type', 't', InputOption::VALUE_REQUIRED, "Force le type MIME.")
->addOption('display-name', 'd', InputOption::VALUE_REQUIRED, "Indique un nom de fichier.")
->addOption('metadata', 'm', InputOption::VALUE_REQUIRED, "Ajoute des métadata (format JSON).")
->addArgument('path', InputArgument::REQUIRED, "Nom du fichier à ajouter, - pour lire l'entrée standard")
;
->addArgument('path', InputArgument::REQUIRED, "Nom du fichier à ajouter, - pour lire l'entrée standard");
}
protected function execute(InputInterface $input, OutputInterface $output)
......@@ -41,52 +40,54 @@ class CreateCommand extends ContainerAwareCommand
$id = $written = null;
$em->transactional(function() use($input, $output, $em, &$file, &$written) {
/* @var $manager FileManagerInterface */
$manager = $this->getContainer()->get('irstea_file_upload.file_manager');
$path = $input->getArgument("path");
if("-" === $path) {
$realPath = 'php://stdin';
$displayName = "stdin";
$lastModified = time();
$size = 0;
} else {
$realPath = $path;
$displayName = pathinfo($path, PATHINFO_FILENAME);
$size = filesize($path);
$lastModified = filemtime($path);
$em->transactional(
function () use ($input, $output, $em, &$file, &$written) {
/* @var $manager FileManagerInterface */
$manager = $this->getContainer()->get('irstea_file_upload.file_manager');
$path = $input->getArgument("path");
if ("-" === $path) {
$realPath = 'php://stdin';
$displayName = "stdin";
$lastModified = time();
$size = 0;
} else {
$realPath = $path;
$displayName = pathinfo($path, PATHINFO_FILENAME);
$size = filesize($path);
$lastModified = filemtime($path);
}
$mimeType = $input->getOption('mime-type');
if (null !== $forcedDisplayName = $input->getOption('display-name')) {
$displayName = $forcedDisplayName;
}
$metadata = null;
if (null !== $jsonMetadata = $input->getOption('metadata')) {
$metadata = json_decode($jsonMetadata);
}
$file = $manager->create($displayName, $size, $mimeType ?: 'application/octet-stream', $lastModified, null, 'console');
$fh = fopen($realPath, 'rb');
$written = $file->copyFrom($fh);
fclose($fh);
$manager->completed($file);
if ($mimeType) {
$file->setMimeType($mimetype);
}
if ($metadata) {
$file->setMetadata(array_merge($file->getMetadata(), $metadata));
}
$em->flush();
}
);
$mimeType = $input->getOption('mime-type');
if(null !== $forcedDisplayName = $input->getOption('display-name')) {
$displayName = $forcedDisplayName;
}
$metadata = null;
if(null !== $jsonMetadata = $input->getOption('metadata')) {
$metadata = json_decode($jsonMetadata);
}
$file = $manager->create($displayName, $size, $mimeType ?: 'application/octet-stream', $lastModified, null, 'console');
$fh = fopen($realPath, 'rb');
$written = $file->copyFrom($fh);
fclose($fh);
$manager->completed($file);
if($mimeType) {
$file->setMimeType($mimetype);
}
if($metadata) {
$file->setMetadata(array_merge($file->getMetadata(), $metadata));
}
$em->flush();
});
if($output->isVerbose()) {
if ($output->isVerbose()) {
$output->writeln(sprintf("%s crée, %d octets lus.", $file->getId(), $written));
} else {
$output->writeln($file->getId());
......
......@@ -30,8 +30,7 @@ class ReadCommand extends ContainerAwareCommand
->addOption('append', 'a', InputOption::VALUE_NONE, "Ajoute au fichier de destination au lieu de l'écraser.")
->addOption('overwrite', 'y', InputOption::VALUE_NONE, "Ecrase le fichier de destination s'il existe.")
->addArgument('id', InputArgument::REQUIRED, "Identifiant du fichier à récupérer.")
->addArgument('filepath', InputArgument::OPTIONAL, "Chemin du fichier dans lequel écrire.")
;
->addArgument('filepath', InputArgument::OPTIONAL, "Chemin du fichier dans lequel écrire.");
}
protected function execute(InputInterface $input, OutputInterface $output)
......@@ -43,12 +42,12 @@ class ReadCommand extends ContainerAwareCommand
$path = $input->getArgument('filepath');
if(null == $path) {
if (null == $path) {
$fh = fopen('php://stdout', 'wb');
} else {
if($input->getOption('append')) {
if ($input->getOption('append')) {
$fh = fopen($path, 'ab');
} elseif($input->getOption('overwrite')) {
} elseif ($input->getOption('overwrite')) {
$fh = fopen($path, 'wb');
} else {
$fh = fopen($path, 'xb');
......@@ -58,7 +57,7 @@ class ReadCommand extends ContainerAwareCommand
$written = $file->copyTo($fh);
fclose($fh);
if($output->isVerbose() && null !== $path) {
if ($output->isVerbose() && null !== $path) {
$output->writeln(sprintf("%d octets écrits.", $written));
}
}
......
......@@ -111,13 +111,13 @@ class UploadController extends Controller
[
'put_url' => $this->urlGenerator->generate('file_upload_put_content', $parameters),
'delete_type' => 'DELETE',
'delete_url' => $deleteUrl
'delete_url' => $deleteUrl,
]
),
// On a pas de get pour l'instant, le DELETE et ce qui y ressemble le plus
[ 'Location' => $deleteUrl ]
['Location' => $deleteUrl]
);
} catch(\Exception $ex) {
} catch (\Exception $ex) {
return $this->createExceptionResponse($ex);
}
}
......@@ -140,13 +140,12 @@ class UploadController extends Controller
$file->copyFrom($input, $maxlen, $offset);
fclose($input);
if($complete) {
if ($complete) {
return $this->completeUpload($file);
}
return $this->createResponse(Response::HTTP_OK, 'Chunk received');
} catch(\Exception $ex) {
} catch (\Exception $ex) {
return $this->createExceptionResponse($ex);
}
}
......@@ -154,42 +153,44 @@ class UploadController extends Controller
/**
*
* @param Request $request
*
* @return array
*/
protected function handleRangeHeader(Request $request)
{
if(null === $range = $request->headers->get('Content-Range', null)) {
if (null === $range = $request->headers->get('Content-Range', null)) {
return [0, PHP_INT_MAX, true];
}
$matches = [];
if(!preg_match('@^bytes (\d+)-(\d+)/(\d+)$@', $range, $matches)) {
if (!preg_match('@^bytes (\d+)-(\d+)/(\d+)$@', $range, $matches)) {
throw new BadRequestHttpException("Invalid Content-Range");
}
$start = intval($matches[1]);
$end = intval($matches[2]);
$end = intval($matches[2]);
$total = intval($matches[3]);
if($start < 0 || $start >= $end || $end >= $total) {
if ($start < 0 || $start >= $end || $end >= $total) {
throw new HttpException(Response::HTTP_REQUESTED_RANGE_NOT_SATISFIABLE);
}
return [$start, 1 + ($end - $start), $end === ($total-1)];
return [$start, 1 + ($end - $start), $end === ($total - 1)];
}
/**
*
* @param UploadedFileInterface $file
*
* @return Response
*/
protected function completeUpload(UploadedFileInterface $file)
{
try {
$this->fileManager->completed($file);
} catch(RejectedFileException $ex) {
return $this->createResponse(Response::HTTP_FORBIDDEN, 'File rejected: '.$ex->getMessage());
} catch (RejectedFileException $ex) {
return $this->createResponse(Response::HTTP_FORBIDDEN, 'File rejected: ' . $ex->getMessage());
}
$parameters = ['id' => $file->getId()];
......@@ -202,7 +203,7 @@ class UploadController extends Controller
'repr' => $this->templating->render(
'IrsteaFileUploadBundle:Extension:uploaded_file.html.twig',
['file' => $file->toArray()]
)
),
]
);
......@@ -219,7 +220,7 @@ class UploadController extends Controller
{
$this->validateCsrfToken($request);
if(!$file->isValid()) {
if (!$file->isValid()) {
throw new NotFoundHttpException();
}
......@@ -242,7 +243,7 @@ class UploadController extends Controller
$this->fileManager->delete($file);
return $this->createResponse();
} catch(\Exception $ex) {
} catch (\Exception $ex) {
return $this->createExceptionResponse($ex);
}
}
......@@ -250,11 +251,12 @@ class UploadController extends Controller
/**
*
* @param Request $request
*
* @throws HttpException
*/
protected function validateCsrfToken(Request $request)
{
if(!$this->csrfProvider->isCsrfTokenValid(self::CSRF_INTENTION, $request->query->get('token', null))) {
if (!$this->csrfProvider->isCsrfTokenValid(self::CSRF_INTENTION, $request->query->get('token', null))) {
throw new HttpException(Response::HTTP_FORBIDDEN, 'Invalid CSRF token');
}
}
......@@ -265,6 +267,7 @@ class UploadController extends Controller
* @param string $message
* @param array $data
* @param array $headers
*
* @return JsonResponse
*/
protected function createResponse($status = Response::HTTP_OK, $message = 'OK', array $data = [], array $headers = [])
......@@ -279,6 +282,7 @@ class UploadController extends Controller
/**
*
* @param \Exception $ex
*
* @return JsonResponse
*/
protected function createExceptionResponse(\Exception $ex)
......@@ -289,11 +293,11 @@ class UploadController extends Controller
[
'exception' => [
'class' => get_class($ex),
'file' => $ex->getFile(),
'line' => $ex->getLine(),
'code' => $ex->getCode(),
'file' => $ex->getFile(),
'line' => $ex->getLine(),
'code' => $ex->getCode(),
'trace' => $ex->getTrace(),
]
],
]
);
}
......
......@@ -43,7 +43,7 @@ class UploadedFileController extends Controller
return [
'uploadedFiles' => $uploadedFiles,
'pager' => $pager,
'pager' => $pager,
];
}
......
......@@ -20,27 +20,29 @@ class Configuration implements ConfigurationInterface
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('irstea_file_upload');
$rootNode
$rootNode
->children()
->integerNode('max_chunk_size')
->beforeNormalization()
->ifString()
->then(function($v) {
$int = intval($v);
if(strpos($v, "K")) {
return 1000*$int;
}
if(strpos($v, "M")) {
return 1000000*$int;
}
return $int;
})
->end()
->defaultValue(0)
->treatNullLike(0)
->treatFalseLike(0)
->min(0)
->end()
->integerNode('max_chunk_size')
->beforeNormalization()
->ifString()
->then(
function ($v) {
$int = intval($v);
if (strpos($v, "K")) {
return 1000 * $int;
}
if (strpos($v, "M")) {
return 1000000 * $int;
}
return $int;
}
)
->end()
->defaultValue(0)
->treatNullLike(0)
->treatFalseLike(0)
->min(0)
->end()
->end();
return $treeBuilder;
......
......@@ -18,13 +18,13 @@ class IrsteaFileUploadExtension extends Extension implements PrependExtensionInt
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
$loader->load('services.yml');
$container->setParameter('irstea_file_upload.max_chunk_size', $config['max_chunk_size']);
$bundles = $container->getParameter('kernel.bundles');
if(!isset($bundles['CLTissueBundle'])) {
if (!isset($bundles['CLTissueBundle'])) {
// On a pas le CLTissueBundle => pas d'antivirus
$container->removeDefinition('irstea_file_upload.virus_scanner');
}
......@@ -41,8 +41,8 @@ class IrsteaFileUploadExtension extends Extension implements PrependExtensionInt
'assetic',
[
'assets' => [
'form_js' => [
'inputs' => [
'form_js' => [
'inputs' => [
"$pluginDir/js/jquery.fileupload.js",
"$pluginDir/js/jquery.fileupload-process.js",
"$pluginDir/js/jquery.fileupload-validate.js",
......@@ -50,14 +50,14 @@ class IrsteaFileUploadExtension extends Extension implements PrependExtensionInt
"@BazingaJsTranslationBundle/Resources/js/translator.js",
'js/translations/file_upload/*.js',
'js/translations/validators/*.js',
'@IrsteaFileUploadBundle/Resources/js/widget/file_upload.js'
'@IrsteaFileUploadBundle/Resources/js/widget/file_upload.js',
],
],
'form_css' => [
'inputs' => [
'inputs' => [
"$pluginDir/css/jquery.fileupload.css",
"$pluginDir/css/jquery.fileupload-ui.css",
'@IrsteaFileUploadBundle/Resources/less/file_upload.less'
'@IrsteaFileUploadBundle/Resources/less/file_upload.less',
],
],
],
......
......@@ -73,8 +73,8 @@ class UploadedFileRepository extends EntityRepository implements FileManagerInte
'filename' => $filename,
'size' => $size,
'mimeType' => $mimeType,
'lastModified' => $lastModified
]
'lastModified' => $lastModified,
],
]
);
......@@ -89,7 +89,7 @@ class UploadedFileRepository extends EntityRepository implements FileManagerInte
public function duplicate(UploadedFileInterface $original)
{
if (!$original->isValid()) {
throw new InvalidArgumentException("Impossible de dupliquer le fichier ".$original->getId()." car il est invalide !");
throw new InvalidArgumentException("Impossible de dupliquer le fichier " . $original->getId() . " car il est invalide !");
}
$new = new UploadedFile();
......@@ -157,7 +157,6 @@ class UploadedFileRepository extends EntityRepository implements FileManagerInte
$this->_em->flush();
$this->log(LogLevel::INFO, 'File completed', ['file' => $file]);
} catch (RejectedFileException $ex) {
$file->setEtat(UploadedFileInterface::ETAT_REJETE);
......
......@@ -129,7 +129,7 @@ class UploadedFile implements UploadedFileInterface
public function __construct()
{
$this->id = Uuid::uuid4()->toString();
$this->actualPath = $this->path = self::ORPHAN_PREFIX.$this->id;
$this->actualPath = $this->path = self::ORPHAN_PREFIX . $this->id;
}
/**
......@@ -182,7 +182,7 @@ class UploadedFile implements UploadedFileInterface
*/
public function setPath($path)
{
if(!static::isSafePath($path)) {
if (!static::isSafePath($path)) {
throw new InvalidArgumentException("Unsafe path: $path");
}
$this->path = trim($path, '/');
......@@ -257,7 +257,7 @@ class UploadedFile implements UploadedFileInterface
*/
public function setEtat($etat)
{
if(!in_array(
if (!in_array(
$etat,
[
self::ETAT_CORROMPU,
......@@ -265,14 +265,14 @@ class UploadedFile implements UploadedFileInterface
self::ETAT_MANQUANT,
self::ETAT_NORMAL,
self::ETAT_ORPHELIN,
self::ETAT_REJETE
self::ETAT_REJETE,
]
)) {
throw new InvalidArgumentException(sprintf("Etat invalide: '%s'", (string)$etat));
}
// Déplace le fichier hors de l'orphelinat quand on passe d'orphelin à nouveau
if($this->etat === self::ETAT_ORPHELIN && $etat === self::ETAT_NORMAL && 0 === strpos($this->path, self::ORPHAN_PREFIX)) {
if ($this->etat === self::ETAT_ORPHELIN && $etat === self::ETAT_NORMAL && 0 === strpos($this->path, self::ORPHAN_PREFIX)) {
$this->path = substr($this->path, strlen(self::ORPHAN_PREFIX));
}
......@@ -322,10 +322,10 @@ class UploadedFile implements UploadedFileInterface
{
$unit = "";
$size = $this->size ?: 0;
if($size >= 10240) {
if ($size >= 10240) {
$size /= 1024;
$unit = "k";
if($size >= 10240) {
if ($size >= 10240) {
$size /= 1024;
$unit = "m";
}
......@@ -335,6 +335,7 @@ class UploadedFile implements UploadedFileInterface
/**
* @param Filesystem $filesystem
*
* @return self
*
* @internal
......@@ -391,7 +392,7 @@ class UploadedFile implements UploadedFileInterface
{
try {
return new \DateTime(sprintf('@%d', $this->filesystem->mtime($this->getActualPath())));
} catch(FileNotFound $ex) {
} catch (FileNotFound $ex) {
return null;
}
}
......@@ -417,7 +418,7 @@ class UploadedFile implements UploadedFileInterface
*/
public function copyFrom($source, $maxlen = -1, $writeOffset = 0)
{
if($maxlen === 0) {
if ($maxlen === 0) {
return 0;
}
......@@ -425,16 +426,16 @@ class UploadedFile implements UploadedFileInterface
$stream->open(new StreamMode('cb'));
$stream->seek($writeOffset);
if(false !== $fileHandle = $stream->cast(STREAM_CAST_AS_STREAM)) {
if (false !== $fileHandle = $stream->cast(STREAM_CAST_AS_STREAM)) {
// Utilise stream_copy_to_stream si le Gaufrette\Stream peut nous retourner un filehandle
$copied = $this->stream_copy_to_stream($source, $fileHandle, $maxlen);
} else {
// Sinon fait une copie par blocs (moins performant)
if($maxlen === -1) {
if ($maxlen === -1) {
$maxlen = PHP_INT_MAX;
}
$copied = 0;
while(!$this->feof($source) && $copied <= $maxlen) {
while (!$this->feof($source) && $copied <= $maxlen) {
$copied += $stream->write($this->fread($source, min(static::$copyBlockSize, $maxlen - $copied)));
}
}
......@@ -448,7 +449,7 @@ class UploadedFile implements UploadedFileInterface
*/
public function copyTo($dest, $maxlen = -1, $readOffset = 0)
{
if($maxlen === -1) {
if ($maxlen === -1) {
$actualLength = $this->getSize() - $readOffset;
} else {
$actualLength = min($maxlen, $this->getSize() - $readOffset);
......@@ -462,13 +463,13 @@ class UploadedFile implements UploadedFileInterface
$stream->open(new StreamMode('rb'));
$stream->seek($readOffset);
if(false !== $fileHandle = $stream->cast(STREAM_CAST_AS_STREAM)) {
if (false !== $fileHandle = $stream->cast(STREAM_CAST_AS_STREAM)) {
// Utilise stream_copy_to_stream si le Stream nous renvoie un filehandle
$copied = $this->stream_copy_to_stream($fileHandle, $dest, $actualLength);
} else {
// Sinon, on fait ça à la main par blocs de 8ko