diff --git a/lib/Alchemy/Phrasea/Controller/Api/V1Controller.php b/lib/Alchemy/Phrasea/Controller/Api/V1Controller.php
index ff8764b0d9..1eb2810372 100644
--- a/lib/Alchemy/Phrasea/Controller/Api/V1Controller.php
+++ b/lib/Alchemy/Phrasea/Controller/Api/V1Controller.php
@@ -88,9 +88,10 @@ use Alchemy\Phrasea\Status\StatusStructure;
use Alchemy\Phrasea\TaskManager\LiveInformation;
use Alchemy\Phrasea\Utilities\NullableDateTime;
use Doctrine\ORM\EntityManager;
-use JMS\TranslationBundle\Annotation\Ignore;
+use Guzzle\Http\Client as Guzzle;
use League\Fractal\Resource\Item;
use media_subdef;
+use Neutron\TemporaryFilesystem\TemporaryFilesystemInterface;
use Symfony\Component\Form\Form;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\Request;
@@ -905,19 +906,6 @@ class V1Controller extends Controller
public function addRecordAction(Request $request)
{
- if (count($request->files->get('file')) == 0) {
- return $this->getBadRequestAction($request, 'Missing file parameter');
- }
-
- $file = $request->files->get('file');
- if (!$file instanceof UploadedFile) {
- return $this->getBadRequestAction($request, 'You can upload one file at time');
- }
-
- if (!$file->isValid()) {
- return $this->getBadRequestAction($request, 'Data corrupted, please try again');
- }
-
if (!$request->get('base_id')) {
return $this->getBadRequestAction($request, 'Missing base_id parameter');
}
@@ -930,16 +918,54 @@ class V1Controller extends Controller
))->createResponse();
}
- // Add file extension
- $uploadedFilename = $file->getRealPath();
+ if (count($request->files->get('file')) == 0) {
+ if(count($request->get('url')) == 0) {
+ return $this->getBadRequestAction($request, 'Missing file parameter');
+ }
+ else {
+ // upload via url
+ $url = $request->get('url');
+ $pi = pathinfo($url); // filename, extension
- $renamedFilename = $file->getRealPath() . '.' . pathinfo($file->getClientOriginalName(), PATHINFO_EXTENSION);
+ /** @var TemporaryFilesystemInterface $tmpFs */
+ $tmpFs = $this->app['temporary-filesystem'];
+ $tempfile = $tmpFs->createTemporaryFile('download_', null, $pi['extension']);
- $this->getFilesystem()->rename($uploadedFilename, $renamedFilename);
+ try {
+ $guzzle = new Guzzle($url);
+ $res = $guzzle->get("", [], ['save_to' => $tempfile])->send();
+ }
+ catch (\Exception $e) {
+ return $this->getBadRequestAction($request, sprintf('Error "%s" downloading "%s"', $e->getMessage(), $url));
+ }
- $media = $this->app->getMediaFromUri($renamedFilename);
+ if($res->getStatusCode() !== 200) {
+ return $this->getBadRequestAction($request, sprintf('Error %s downloading "%s"', $res->getStatusCode(), $url));
+ }
- $Package = new File($this->app, $media, $collection, $file->getClientOriginalName());
+ $originalName = $pi['filename'] . '.' . $pi['extension'];
+ $newPathname = $tempfile;
+ }
+ }
+ else {
+ // upload via file
+ $file = $request->files->get('file');
+ if (!$file instanceof UploadedFile) {
+ return $this->getBadRequestAction($request, 'You can upload one file at time');
+ }
+ if (!$file->isValid()) {
+ return $this->getBadRequestAction($request, 'Data corrupted, please try again');
+ }
+ $originalName = $file->getClientOriginalName();
+ $newPathname = $file->getPathname() . '.' . $file->getClientOriginalExtension();
+ if (false === rename($file->getPathname(), $newPathname)) {
+ return Result::createError($request, 403, 'Error while renaming file')->createResponse();
+ }
+ }
+
+ $media = $this->app->getMediaFromUri($newPathname);
+
+ $Package = new File($this->app, $media, $collection, $originalName);
if ($request->get('status')) {
$Package->addAttribute(new Status($this->app, $request->get('status')));
diff --git a/lib/Alchemy/Phrasea/Controller/Prod/UploadController.php b/lib/Alchemy/Phrasea/Controller/Prod/UploadController.php
index 47e6716ac4..89a0d21910 100644
--- a/lib/Alchemy/Phrasea/Controller/Prod/UploadController.php
+++ b/lib/Alchemy/Phrasea/Controller/Prod/UploadController.php
@@ -26,6 +26,7 @@ use Alchemy\Phrasea\Model\Entities\LazaretFile;
use Alchemy\Phrasea\Model\Entities\LazaretSession;
use DataURI\Exception\Exception as DataUriException;
use DataURI\Parser;
+use Guzzle\Http\Client as Guzzle;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@@ -76,6 +77,30 @@ class UploadController extends Controller
]);
}
+ public function getHead(Request $request)
+ {
+ $response = [
+ 'content-type' => null,
+ 'content-length' => null,
+ 'basename' => null
+ ];
+ try {
+ $url = $request->get('url');
+ $basename = pathinfo($url, PATHINFO_BASENAME);
+
+ $guzzle = new Guzzle($url);
+ $res = $guzzle->head("")->send();
+ $response['content-type'] = $res->getContentType();
+ $response['content-length'] = $res->getContentLength();
+ $response['basename'] = $basename;
+ }
+ catch (\Exception $e) {
+ // no-op : head will return no info but will not crash
+ }
+
+ return $this->app->json($response);
+ }
+
/**
* Upload processus
*
@@ -98,7 +123,7 @@ class UploadController extends Controller
'message' => '',
'element' => '',
'reasons' => [],
- 'id' => '',
+ 'id' => '',
];
if (null === $request->files->get('files')) {
@@ -119,18 +144,44 @@ class UploadController extends Controller
throw new AccessDeniedHttpException('User is not allowed to add record on this collection');
}
+ /** @var UploadedFile $file */
$file = current($request->files->get('files'));
if (!$file->isValid()) {
throw new BadRequestHttpException('Uploaded file is invalid');
}
- try {
+ if ($file->getClientOriginalName() === "blob" && $file->getClientMimeType() === "application/json") {
+
+ // a "upload by url" was done, we receive a tiny json that contains url.
+ $json = json_decode(file_get_contents($file->getRealPath()), true);
+ $url = $json['url'];
+ $pi = pathinfo($url); // filename, extension
+
+ $tempfile = $this->getTemporaryFilesystem()->createTemporaryFile('download_', null, $pi['extension']);
+
+ try {
+ $guzzle = new Guzzle($url);
+ $res = $guzzle->get("", [], ['save_to' => $tempfile])->send();
+ }
+ catch (\Exception $e) {
+ throw new BadRequestHttpException(sprintf('Error "%s" downloading "%s"', $e->getMessage(), $url));
+ }
+
+ if($res->getStatusCode() !== 200) {
+ throw new BadRequestHttpException(sprintf('Error %s downloading "%s"', $res->getStatusCode(), $url));
+ }
+
+ $uploadedFilename = $renamedFilename = $tempfile;
+
+ $originalName = $pi['filename'] . '.' . $pi['extension'];
+
+ } else {
// Add file extension, so mediavorus can guess file type for octet-stream file
$uploadedFilename = $file->getRealPath();
$renamedFilename = null;
- if(!empty($this->app['conf']->get(['main', 'storage', 'tmp_files']))){
+ if(!empty($this->app['conf']->get(['main', 'storage', 'tmp_files']))) {
$tmpStorage = \p4string::addEndSlash($this->app['conf']->get(['main', 'storage', 'tmp_files'])).'upload/';
if(!is_dir($tmpStorage)){
@@ -139,12 +190,16 @@ class UploadController extends Controller
$renamedFilename = $tmpStorage. pathinfo($file->getRealPath(), PATHINFO_FILENAME) .'.' . pathinfo($file->getClientOriginalName(), PATHINFO_EXTENSION);
- }else{
+ } else {
$renamedFilename = $file->getRealPath() . '.' . pathinfo($file->getClientOriginalName(), PATHINFO_EXTENSION);
}
$this->getFilesystem()->rename($uploadedFilename, $renamedFilename);
+ $originalName = $file->getClientOriginalName();
+ }
+
+ try {
$media = $this->app->getMediaFromUri($renamedFilename);
$collection = \collection::getByBaseId($this->app, $base_id);
@@ -153,7 +208,7 @@ class UploadController extends Controller
$this->getEntityManager()->persist($lazaretSession);
- $packageFile = new File($this->app, $media, $collection, $file->getClientOriginalName());
+ $packageFile = new File($this->app, $media, $collection, $originalName);
$postStatus = $request->request->get('status');
@@ -184,7 +239,9 @@ class UploadController extends Controller
$code = $this->getBorderManager()->process( $lazaretSession, $packageFile, $callback, $forceBehavior);
- $this->getFilesystem()->rename($renamedFilename, $uploadedFilename);
+ if($renamedFilename !== $uploadedFilename) {
+ $this->getFilesystem()->rename($renamedFilename, $uploadedFilename);
+ }
if (!!$forceBehavior) {
$reasons = [];
diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Prod/Upload.php b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Upload.php
index a32133050f..f310d75744 100644
--- a/lib/Alchemy/Phrasea/ControllerProvider/Prod/Upload.php
+++ b/lib/Alchemy/Phrasea/ControllerProvider/Prod/Upload.php
@@ -66,6 +66,9 @@ class Upload implements ControllerProviderInterface, ServiceProviderInterface
$controllers->get('/html5-version/', 'controller.prod.upload:getHtml5UploadForm')
->bind('upload_html5_form');
+ $controllers->get('/head/', 'controller.prod.upload:getHead')
+ ->bind('upload_head');
+
$controllers->post('/', 'controller.prod.upload:upload')
->bind('upload');
diff --git a/templates/web/prod/upload/upload.html.twig b/templates/web/prod/upload/upload.html.twig
index ebb5b73922..9aef063080 100644
--- a/templates/web/prod/upload/upload.html.twig
+++ b/templates/web/prod/upload/upload.html.twig
@@ -31,7 +31,10 @@
{{ 'Select files...' | trans }}
-
+
+
{{ "Or" | trans }}
+ +