<?php
namespace AWEdmBundle\Controller;
use AWCmsBundle\Security\CurrentUserProvider;
use AWCmsBundle\Tool\FileSystemTool;
use AWEdmBundle\Entity\Document;
use AWEdmBundle\Entity\File;
use AWEdmBundle\Entity\Folder;
use AWEdmBundle\Manager\DocumentManager;
use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
use Doctrine\ORM\EntityManagerInterface;
use League\Flysystem\FileNotFoundException;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use FOS\RestBundle\Controller\Annotations as Rest;
use Symfony\Contracts\Translation\TranslatorInterface;
/**
* Class EdmApiController
* @package AWEdmBundle\Controller
*
* @Security("has_role('ROLE_USER')")
* @Route("/api/ged")
*/
class EdmApiController extends RestController
{
/**
* @Rest\Get("documents", name="get_documents_index", options={"expose"=true,"i18n"=false})
* @Method("GET")
* @Template
* @return array
*/
public function getDocumentsIndexAction()
{
return [];
}
/**
* Returns all the files and folders of a folder
* @Rest\Get("/get_folder_content", name="get_files", options={"expose"=true,"i18n"=false})
* @Security("has_role('ROLE_USER')")
* @Rest\View(serializerGroups={"ged"})
* @param Request $request
* @return array
*/
public function getFolderContentAction(Request $request)
{
$subFolder = $request->query->get('subFolder', '');
$parentId = $request->query->get('parent_id', null);
$folders = $request->query->get('folders', null);
$foldersId = explode(', ', $folders);
$offset = $request->query->get('offset', 0);
$limit = $request->query->get('limit', 100);
/** @var EntityManagerInterface $entityManager */
$entityManager = $this->get('doctrine.orm.default_entity_manager');
if ('' != $subFolder) {
if($parentId === null){
$parentId = $entityManager->getRepository(Folder::class)->findOneBy(['parent' => null])->getId();
}
$folders = $entityManager->getRepository(Folder::class)->findBy(['subFolder' => $subFolder, 'parent' => $parentId], null, $limit, $offset);
$folders = array_merge($folders, $entityManager->getRepository(Folder::class)->findBy(['subFolder' => $subFolder, 'parent' => $parentId, 'id' => $foldersId], null, $limit, $offset));
$files = $entityManager->getRepository(File::class)->findBy(['parent' => $parentId], null, $limit, $offset);
}else{
throw new \InvalidArgumentException('Need a subFolder');
}
return [
'data' => array_merge($folders, $files)
];
}
/**
* @Rest\GET("/get_document/{document}", name="get_document", options={"expose"=true,"i18n"=false})
* @Rest\View(serializerGroups={"ged"})
* @param Document $document
* @return array
*/
public function getDocumentAction(Document $document)
{
return [
'data' => $document
];
}
/**
* @Rest\Post("/post_documents", name="post_documents", options={"expose"=true,"i18n"=false})
* @Security("has_role('ROLE_USER')")
* @Rest\View(serializerGroups={"ged"})
* @param Request $request
* @return array
*/
public function postDocumentsAction(Request $request)
{
$documentManager = $this->get('awedm.manager.document');
$entityManager = $this->get('doctrine.orm.default_entity_manager');
$documentsProperties = $request->get('document_collection')['documents'];
$documents = [];
foreach ($documentsProperties as $documentProperties) {
$id = (array_key_exists('id', $documentProperties) ? $documentProperties['id'] : null);
$name = $documentProperties['name'];
$parentId = $documentProperties['parent_id'];
$type = $documentProperties['type'];
$document = null;
if (null !== $id && '' != $id) {
if($type === Document::TYPE_FILE){
$document = $this->get('doctrine.orm.default_entity_manager')->getRepository(File::class)->findOneBy(['id' => $id]);
}else{
$document = $this->get('doctrine.orm.default_entity_manager')->getRepository(Folder::class)->findOneBy(['id' => $id]);
}
}
$folderParent = null;
/**
* @TODO to remove...
*/
if ('' != $parentId and preg_match('|\.|', $parentId)) {
$folderParent = $entityManager->getRepository(Folder::class)->findOneBy(['uniqueId' => $parentId]);
}elseif ('' != $parentId){
$folderParent = $entityManager->getRepository(Folder::class)->find($parentId);
}
if (null === $document) {
switch ($type) {
case 'folder':
$document = new Folder();
if(array_key_exists('subFolder', $documentProperties)){
$document->setSubFolder($documentProperties['subFolder']);
}elseif ($folderParent){
$document->setSubFolder($folderParent->getSubFolder());
}
break;
case 'file':
$document = new File();
break;
}
}
$document->setName($name);
$document->setParent($folderParent);;
$documentManager->save($document);
$documents[] = $document;
}
return [
'data' => $documents
];
}
/**
* @Rest\Patch("/patch_documents", name="patch_documents", options={"expose"=true,"i18n"=false})
* @Rest\View(serializerGroups={"ged"})
* @Security("has_role('ROLE_USER')")
*
* @param Request $request
* @return array
*/
public function patchDocumentsAction(Request $request)
{
return $this->postDocumentsAction($request);
}
/**
* @Rest\Delete("/delete_documents", name="delete_documents", options={"expose"=true,"i18n"=false})
* @Rest\View(serializerGroups={"ged"})
* @Security("has_role('ROLE_USER')")
*
* @param Request $request
* @param CurrentUserProvider $userProvider
* @return JsonResponse
*/
public function deleteDocumentsAction(Request $request, CurrentUserProvider $userProvider)
{
$documentManager = $this->get('awedm.manager.document');
$fileIds = (array) $request->get('files');
$folderIds = (array) $request->get('folders');
if(!$fileIds && !$folderIds){
return new JsonResponse(['success' => false], Response::HTTP_BAD_REQUEST);
}
$documents = [];
foreach ($fileIds as $documentId) {
/** @var File $document */
if ($document = $this->get('doctrine.orm.default_entity_manager')->getRepository(File::class)->find($documentId)) {
$documents[] = $document;
}
}
foreach ($folderIds as $documentId) {
/** @var File $document */
if ($document = $this->get('doctrine.orm.default_entity_manager')->getRepository(Folder::class)->find($documentId)) {
$documents[] = $document;
}
}
/** @var Document $document */
foreach ($documents as $document) {
if (
!(
$this->isGranted('ROLE_ADMIN')
|| ($this->isGranted('ROLE_USER') && $document->getCreatedBy()->getId() == $userProvider->get()->getId())
)
) {
throw new AccessDeniedException();
}
if ($document) {
try{
$documentManager->delete($document);
}
catch(\Exception $e){
if($e instanceof ForeignKeyConstraintViolationException){
return new JsonResponse(['success' => false, 'error' => $this->get('translator')->trans('error.foreign_key_constraint')], Response::HTTP_BAD_REQUEST);
}
return new JsonResponse(['success' => false, 'error' => $e->getMessage()], Response::HTTP_NOT_FOUND);
}
}
}
return new JsonResponse(['success' => true]);
}
/**
* @Rest\Post("/post_documents_upload/{folder}", name="post_documents_upload", options={"expose"=true,"i18n"=false})
* @Rest\View(serializerGroups={"ged"})
* @Security("has_role('ROLE_USER')")
*
* @param Request $request
* @param Folder $folder
* @return array
* @throws \Exception
*/
public function postDocumentsUploadAction(Request $request, Folder $folder, DocumentManager $documentManager)
{
$subFolder = $request->query->get('subFolder', '');
$data = [];
if (count($_FILES) > 0) {
$data = $documentManager->upload($subFolder, $folder, 'files');
}
return ['data' => $data];
}
/**
* @Rest\Get("/get_download_documents", name="get_download_documents", options={"expose"=true,"i18n"=false})
* @param Request $request
* @return \Symfony\Component\HttpFoundation\RedirectResponse|Response
*/
public function getDownloadDocumentsAction(Request $request)
{
/** @var DocumentManager $documentManager */
$documentManager = $this->get('awedm.manager.document');
$archiveName = "archive_".uniqid();
$subFolder = $request->query->get('subFolder');
$tmpDirectory = '/tmp/'.$archiveName;
$fileIds = (array) $request->get('files');
$folderIds = (array) $request->get('folders');
$documents = [];
foreach ($fileIds as $documentId) {
/** @var File $document */
if ($document = $this->get('doctrine.orm.default_entity_manager')->getRepository(File::class)->find($documentId)) {
$documents[] = $document;
}
}
foreach ($folderIds as $documentId) {
/** @var File $document */
if ($document = $this->get('doctrine.orm.default_entity_manager')->getRepository(Folder::class)->find($documentId)) {
$documents[] = $document;
}
}
if(count($documents) == 1 and reset($documents) instanceof File)
return $documentManager->downloadFile(reset($documents));
$documentManager->createTree($documents, $tmpDirectory, $subFolder);
$zipFile = realpath($tmpDirectory.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.$archiveName.'.zip';
//dump($zipFile);exit;
if (file_exists($tmpDirectory)) {
FileSystemTool::zipFolder(realpath($tmpDirectory), $zipFile);
FileSystemTool::rmRecursive($tmpDirectory);
if (file_exists($zipFile)) {
FileSystemTool::rangeDownload($zipFile, basename($zipFile), true);
exit;
}
}
return new Response('File not found.', Response::HTTP_NOT_FOUND);
}
/**
* @Rest\Get("get_file/{file}", name="get_file", options={"expose"=true,"i18n"=false})
* @Method("GET")
* @param File $file
* @return \Symfony\Component\HttpFoundation\StreamedResponse
*/
public function getFileAction(File $file)
{
/** @var DocumentManager $documentManager */
$documentManager = $this->get('awedm.manager.document');
try {
$response = $documentManager->downloadFile($file);
} catch (FileNotFoundException $e) {
throw new NotFoundHttpException();
}
return $response;
}
/**
* @Rest\Get("/check_folder_tree", name="check_folder_tree", options={"expose"=true,"i18n"=false})
* @Method("GET")
* @param Request $request
* @return JsonResponse
*/
public function getCheckFolderTreeAction(Request $request)
{
$path = str_replace(' ', '', $request->get('path'));
$tree = explode(',', $path);
end($tree); // move the internal pointer to the end of the array
$lastFolderId = key($tree);
/** @var Folder $lastFolder */
$lastFolder = $this->get('doctrine.orm.default_entity_manager')->getRepository(Folder::class)->findOneBy(['id' => $lastFolderId]);
$emdPath = implode(',', $this->container->get('awedm.manager.document')->getFolderIdTree($lastFolder));
$response = new JsonResponse();
$response->setData(['success' => $emdPath == $path]);
return $response;
}
}