UploadController.php 3.67 KB
Newer Older
<?php

/*
 * Copyright (C) 2015 IRSTEA
 * All rights reserved.
 */

namespace Irstea\FileUploadBundle\Controller;

use Irstea\FileUploadBundle\Entity\UploadedFile;
use Irstea\FileUploadBundle\Service\FileManagerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\RouterInterface;

/**
 * @Route("/files", service="irstea_file_upload.upload_controller")
 */
class UploadController extends Controller
{
    /**
     *
     * @var FileManagerInterface
     */
    protected $fileManager;

    /**
     *
     * @var RouterInterface
     */
    protected $router;

    /**
     * @var CsrfProviderInterface
     */
    protected $csrfProvider;


    /**
     *
     */
    public function __construct(FileManagerInterface $fileManager, RouterInterface $router, CsrfProviderInterface $csrfProvider)
    {
        $this->fileManager = $fileManager;
        $this->router = $router;
        $this->csrfProvider = $csrfProvider;
    }

    /**
     * @Route("", name="file_upload_create")
     * @Method("POST")
     * @param Request $request
     */
    public function createAction(Request $request)
    {
        $data = $request->request->get('file');

        $file = $this->fileManager->create($data['name'], $data['size'], $data['type'], $data['lastModified']);

        $token = $this->csrfProvider->generateCsrfToken("file-upload");

        $location = $this->router->generate(
            'file_upload_put',
            [
                'id' => $file->getId(),
                'token' => $token
            ],
            RouterInterface::ABSOLUTE_URL
        );

        return $this->createResponse(
            Response::HTTP_CREATED,
            'New file created',
            [ 'id' => $file->getId(), 'url' => $location ],
            [ 'Location' => $location ]
        );
    }

    /**
     * @Route("/{id}", name="file_upload_put")
     * @Method("PUT")
     * @param Request $request
     * @param UploadedFile $file
     */
    public function putAction(Request $request, UploadedFile $file)
    {
        $this->validateToken($request);

        $stream = $file->open('wb+');
        $stream->write($request->getContent());
        $stream->close();

        return $this->createResponse();
    }

    /**
     * @Route("/{id}", name="file_upload_delete")
     * @Method("DELETE")
     * @param Request $request
     * @param UploadedFile $file
     */
    public function deleteAction(Request $request, UploadedFile $file)
    {
        $this->validateToken($request);

        $this->fileManager->delete($file);
        return $this->createResponse();
    }

    /**
     *
     * @param Request $request
     * @throws JsonReponse
     */
    protected function validateToken(Request $request)
    {
        if(!$this->csrfProvider->isCsrfTokenValid("file-upload", $request->query->get('token', null))) {
            throw $this->createResponse(Response::HTTP_BAD_REQUEST, 'Invalid CRSF token');
        }
    }

    /**
     *
     * @param int $status
     * @param string $message
     * @param array $data
     * @param array $headers
     * @return JsonResponse
     */
    protected function createResponse($status = Response::HTTP_OK, $message = 'OK', array $data = [], array $headers = [])
    {
        $data['status'] = $status;
        $data['message'] = $message;
        return new JsonResponse($data, $status, $headers);
    }
}