getUploadMaxFileSize(); return $this->render('prod/upload/upload-flash.html.twig', [ 'sessionId' => session_id(), 'collections' => $this->getGrantedCollections($this->getAclForUser()), 'maxFileSize' => $maxFileSize, 'maxFileSizeReadable' => \p4string::format_octets($maxFileSize) ]); } public function getHtml5UploadForm() { $this->setSessionFormToken('prodUpload'); $maxFileSize = $this->getUploadMaxFileSize(); return $this->render('prod/upload/upload.html.twig', [ 'sessionId' => session_id(), 'collections' => $this->getGrantedCollections($this->getAclForUser()), 'maxFileSize' => $maxFileSize, 'maxFileSizeReadable' => \p4string::format_octets($maxFileSize) ]); } public function getUploadForm() { $this->setSessionFormToken('prodUpload'); $maxFileSize = $this->getUploadMaxFileSize(); return $this->render('prod/upload/upload.html.twig', [ 'collections' => $this->getGrantedCollections($this->getAclForUser()), 'maxFileSize' => $maxFileSize, 'maxFileSizeReadable' => \p4string::format_octets($maxFileSize) ]); } 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(['base_uri' => $url]); $res = $guzzle->head(''); $response['content-type'] = $res->getHeaderLine('content-type'); $response['content-length'] = doubleval($res->getHeaderLine('content-length')); $response['basename'] = $basename; } catch (\Exception $e) { // no-op : head will return no info but will not crash } return $this->app->json($response); } /** * Upload processus * * @param Request $request The current request * * parameters : 'bas_id' int (mandatory) : The id of the destination collection * 'status' array (optional) : The status to set to new uploaded files * 'attributes' array (optional) : Attributes id's to attach to the uploaded files * 'forceBehavior' int (optional) : Force upload behavior * - 0 Force record * - 1 Force lazaret * * @return Response */ public function upload(Request $request) { $data = [ 'success' => false, 'code' => null, 'message' => '', 'element' => '', 'reasons' => [], 'id' => '', ]; if (!$this->isCrsfValid($request, 'prodUpload')) { throw new AccessDeniedHttpException('Invalid prodUpload token'); } if (null === $request->files->get('files')) { throw new BadRequestHttpException('Missing file parameter'); } if (count($request->files->get('files')) > 1) { throw new BadRequestHttpException('Upload is limited to 1 file per request'); } $base_id = $request->request->get('base_id'); if (!$base_id) { throw new BadRequestHttpException('Missing base_id parameter'); } if (!$this->getAclForUser()->has_right_on_base($base_id, \ACL::CANADDRECORD)) { 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'); } 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(['base_uri' => $url]); $res = $guzzle->get("", ['save_to' => $tempfile]); } 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', 'worker_tmp_files']))) { $tmpStorage = \p4string::addEndSlash($this->app['conf']->get(['main', 'storage', 'worker_tmp_files'])).'upload/'; if(!is_dir($tmpStorage)){ $this->getFilesystem()->mkdir($tmpStorage); } $renamedFilename = $tmpStorage. pathinfo($file->getRealPath(), PATHINFO_FILENAME) .'.' . pathinfo($file->getClientOriginalName(), PATHINFO_EXTENSION); } 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); $lazaretSession = new LazaretSession(); $lazaretSession->setUser($this->getAuthenticatedUser()); $this->getEntityManager()->persist($lazaretSession); $packageFile = new File($this->app, $media, $collection, $originalName); $postStatus = $request->request->get('status'); if (isset($postStatus[$collection->get_base_id()]) && is_array($postStatus[$collection->get_base_id()])) { $postStatus = $postStatus[$collection->get_base_id()]; $status = ''; foreach (range(0, 31) as $i) { $status .= isset($postStatus[$i]) ? ($postStatus[$i] ? '1' : '0') : '0'; } $packageFile->addAttribute(new Status($this->app, strrev($status))); } $forceBehavior = $request->request->get('forceAction'); $reasons = []; $elementCreated = null; $callback = function ($element, Visa $visa) use (&$reasons, &$elementCreated) { foreach ($visa->getResponses() as $response) { if (!$response->isOk()) { $reasons[] = $response->getMessage($this->app['translator']); } } $elementCreated = $element; }; $code = $this->getBorderManager()->process( $lazaretSession, $packageFile, $callback, $forceBehavior); if($renamedFilename !== $uploadedFilename) { $this->getFilesystem()->rename($renamedFilename, $uploadedFilename); } if (!!$forceBehavior) { $reasons = []; } if ($elementCreated instanceof \record_adapter) { $id = $elementCreated->getId(); $element = 'record'; $message = $this->app->trans('The record was successfully created'); $this->dispatch(PhraseaEvents::RECORD_UPLOAD, new RecordEdit($elementCreated)); // try to create thumbnail from data URI if ('' !== $b64Image = $request->request->get('b64_image', '')) { try { $dataUri = Parser::parse($b64Image); $fileName = $this->getTemporaryFilesystem()->createTemporaryFile('base_64_thumb', null, "png"); file_put_contents($fileName, $dataUri->getData()); $media = $this->app->getMediaFromUri($fileName); $this->getSubDefinitionSubstituer()->substituteSubdef($elementCreated, 'thumbnail', $media); $this->getDataboxLogger($elementCreated->getDatabox()) ->log($elementCreated, \Session_Logger::EVENT_SUBSTITUTE, 'thumbnail', ''); unset($media); $this->getTemporaryFilesystem()->clean('base_64_thumb'); } catch (DataUriException $e) { } } } else { /** @var LazaretFile $elementCreated */ $this->dispatch(PhraseaEvents::LAZARET_CREATE, new LazaretEvent($elementCreated)); $id = $elementCreated->getId(); $element = 'lazaret'; $message = $this->app->trans('The file was moved to the quarantine'); } $data = [ 'success' => true, 'code' => $code, 'message' => $message, 'element' => $element, 'reasons' => $reasons, 'id' => $id, ]; } catch (\Exception $e) { $data['message'] = $this->app->trans('Unable to add file to Phraseanet'); } $response = $this->app->json($data); // IE 7 and 8 does not correctly handle json response in file API // lets send them an html content-type header $response->headers->set('Content-type', 'text/html'); return $response; } /** * Get current user's granted collections where he can upload * * @param \ACL $acl The user's ACL. * * @return array */ private function getGrantedCollections(\ACL $acl) { $collections = []; foreach ($acl->get_granted_sbas() as $databox) { $sbasId = $databox->get_sbas_id(); foreach ($acl->get_granted_base([\ACL::CANADDRECORD], [$sbasId]) as $collection) { $databox = $collection->get_databox(); if (!isset($collections[$sbasId])) { $collections[$databox->get_sbas_id()] = [ 'databox' => $databox, 'databox_collections' => [] ]; } $collections[$databox->get_sbas_id()]['databox_collections'][] = $collection; /** @var DisplaySettingService $settings */ $settings = $this->app['settings']; $userOrderSetting = $settings->getUserSetting($this->app->getAuthenticatedUser(), 'order_collection_by'); // a temporary array to sort the collections $aName = []; list($ukey, $uorder) = ["order", SORT_ASC]; // default ORDER_BY_ADMIN switch ($userOrderSetting) { case $settings::ORDER_ALPHA_ASC : list($ukey, $uorder) = ["name", SORT_ASC]; break; case $settings::ORDER_ALPHA_DESC : list($ukey, $uorder) = ["name", SORT_DESC]; break; } foreach ($collections[$databox->get_sbas_id()]['databox_collections'] as $key => $row) { if ($ukey == "order") { $aName[$key] = $row->get_ord(); } else { $aName[$key] = $row->get_name(); } } // sort the collections array_multisort($aName, $uorder, SORT_REGULAR, $collections[$databox->get_sbas_id()]['databox_collections']); } } return $collections; } /** * Get POST max file size * * @return integer */ private function getUploadMaxFileSize() { $postMaxSize = trim(ini_get('post_max_size')); if ('' === $postMaxSize) { $postMaxSize = PHP_INT_MAX; } $r = 0; switch (strtolower(substr($postMaxSize, -1))) { /** @noinspection PhpMissingBreakStatementInspection */ case 'g': $r += 10; /** @noinspection PhpMissingBreakStatementInspection */ case 'm': $r += 10; case 'k': $r += 10; $postMaxSize = ((int)($postMaxSize))<<$r; } return min(UploadedFile::getMaxFilesize(), (int) $postMaxSize); } }