UploadController.php 6.55 KiB
<?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\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
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");
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
$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); $range = $request->headers->get('Content-Range'); $final = true; if($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]); $total = intval($matches[3]); $stream = $file->open('ab'); $stream->seek($start); $final = $end === ($total-1); } else { $stream = $file->open('wb'); } $stream->write($request->getContent()); $stream->close(); if(!$final) { return $this->createResponse(Response::HTTP_OK, 'Chunk received', ['range' => compact('start', 'end', 'total')]); } $this->fileManager->completed($file); $parameters = [ 'id' => $file->getId(), 'token' => $request->query->get('token') ]; return $this->createResponse( Response::HTTP_OK, 'File uploaded', [ 'files' => [ [ 'id' => $file->getId(), 'name' => $file->getOriginalFilename(),