Skip to content

Commit

Permalink
Merge pull request #40 from symfony-cmf/upload_multiple_files
Browse files Browse the repository at this point in the history
UploadFileHelper - change api to support multiple files
  • Loading branch information
rmsint committed Aug 19, 2013
2 parents 4c3ffbd + 130bb59 commit 879392c
Show file tree
Hide file tree
Showing 20 changed files with 654 additions and 67 deletions.
11 changes: 0 additions & 11 deletions Doctrine/Phpcr/MediaManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,6 @@ public function setManagerName($managerName)
$this->managerName = $managerName;
}

/**
* Set the class to use to get the file object;
* if not called, the default class will be used.
*
* @param string $class fully qualified class name of file
*/
public function setClass($class)
{
$this->class = $class;
}

/**
* Set the root path were the file system is located;
* if not called, the default root path will be used.
Expand Down
10 changes: 8 additions & 2 deletions Editor/Helper/UploadCkeditorHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,15 @@ class UploadCkeditorHelper extends UploadDefaultHelper
/**
* {@inheritdoc}
*/
public function getUploadResponse(Request $request, FileInterface $file)
public function getUploadResponse(Request $request, array $files)
{
$urlSafePath = $this->mediaManager->getUrlSafePath($file);
if (!isset($files[0]) && !$files[0] instanceof FileInterface) {
throw new \InvalidArgumentException(
'Provide at least one Symfony\Cmf\Bundle\MediaBundle\FileInterface file.'
);
}

$urlSafePath = $this->mediaManager->getUrlSafePath($files[0]);
$url = $this->router->generate('cmf_media_image_display', array('path' => $urlSafePath));
$funcNum = $request->query->get('CKEditorFuncNum');

Expand Down
17 changes: 14 additions & 3 deletions Editor/Helper/UploadDefaultHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Symfony\Cmf\Bundle\MediaBundle\Editor\UploadEditorHelperInterface;
use Symfony\Cmf\Bundle\MediaBundle\FileInterface;
use Symfony\Cmf\Bundle\MediaBundle\ImageInterface;
use Symfony\Cmf\Bundle\MediaBundle\MediaManagerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
Expand Down Expand Up @@ -45,10 +46,20 @@ public function setFileDefaults(Request $request, FileInterface $file)
/**
* {@inheritdoc}
*/
public function getUploadResponse(Request $request, FileInterface $file)
public function getUploadResponse(Request $request, array $files)
{
$urlSafePath = $this->mediaManager->getUrlSafePath($file);
if (!isset($files[0]) && !$files[0] instanceof FileInterface) {
throw new \InvalidArgumentException(
'Provide at least one Symfony\Cmf\Bundle\MediaBundle\FileInterface file.'
);
}

$urlSafePath = $this->mediaManager->getUrlSafePath($files[0]);

return new RedirectResponse($this->router->generate('cmf_media_image_display', array('path' => $urlSafePath)));
if ($files[0] instanceof ImageInterface) {
return new RedirectResponse($this->router->generate('cmf_media_image_display', array('path' => $urlSafePath)));
} else {
return new RedirectResponse($request->headers->get('referer'));
}
}
}
7 changes: 6 additions & 1 deletion Editor/UploadEditorHelperInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@ public function setFileDefaults(Request $request, FileInterface $file);
/**
* Get a response for the upload action of the editor
*
* @param Request $request
* @param FileInterface[] $files
*
* @return Response
*
* @throws InvalidArgumentException if no FileInterface file is provided
*/
public function getUploadResponse(Request $request, FileInterface $file);
public function getUploadResponse(Request $request, array $files);
}
66 changes: 46 additions & 20 deletions File/UploadFileHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ protected function getObjectManager()
/**
* Add an editor helper
*
* @param string $name
* @param EditorHelperInterface $helper
* @param string $name
* @param UploadEditorHelperInterface $helper
*/
public function addEditorHelper($name, UploadEditorHelperInterface $helper)
{
Expand Down Expand Up @@ -125,14 +125,43 @@ protected function validateFile(UploadedFile $file)
return true;
}

/**
* Handle the UploadedFile and create a FileInterface object specified by
* the configured class.
*
* @param Request $request
* @param UploadedFile $uploadedFile
*
* @return FileInterface
*/
public function handleUploadedFile(UploadedFile $uploadedFile)
{
$this->validateFile($uploadedFile);

/** @var $file FileInterface */
$file = new $this->class;
$file->setName($uploadedFile->getClientOriginalName());
$file->copyContentFromFile($uploadedFile);

try {
$this->mediaManager->setDefaults($file, $this->rootPath);
} catch (\RuntimeException $e) {
throw new HttpException(409, $e->getMessage());
}

return $file;
}

/**
* Process upload and get a response
*
* @param Request $request
* @param Request $request
* @param UploadedFile[] $uploadedFiles optionally get the uploaded file(s)
* from the Request yourself
*
* @return Response
*/
public function getUploadResponse(Request $request)
public function getUploadResponse(Request $request, array $uploadedFiles = array())
{
/** @var \Symfony\Cmf\Bundle\MediaBundle\Editor\EditorHelperInterface $editorHelper */
$editorHelper = $this->getEditorHelper($request->get('editor', 'default'));
Expand All @@ -144,30 +173,27 @@ public function getUploadResponse(Request $request)
));
}

$files = $request->files;
if (count($uploadedFiles) === 0) {
// by default get the first file
$uploadedFiles = array($request->files->getIterator()->current());
}

/** @var $file UploadedFile */
$uploadedFile = $files->getIterator()->current();
$this->validateFile($uploadedFile);
// handle the uploaded file(s)
$files = array();
foreach ($uploadedFiles as $uploadedFile) {
$file = $this->handleUploadedFile($uploadedFile);

/** @var $image FileInterface */
$file = new $this->class;
$file->setName($uploadedFile->getClientOriginalName());
$file->copyContentFromFile($uploadedFile);
$editorHelper->setFileDefaults($request, $file);

$editorHelper->setFileDefaults($request, $file);
$this->getObjectManager()->persist($file);

try {
$this->mediaManager->setDefaults($file, $this->rootPath);
} catch (\RuntimeException $e) {
throw new HttpException(409, $e->getMessage());
$files[] = $file;
}

// persist
$this->getObjectManager()->persist($file);
// write created FileInterface file(s) to storage
$this->getObjectManager()->flush();

// response
return $editorHelper->getUploadResponse($request, $file);
return $editorHelper->getUploadResponse($request, $files);
}
}
2 changes: 1 addition & 1 deletion Resources/config/routing/file.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<requirement key="path">.*</requirement>
</route>

<route id="cmf_media_upload" pattern="/media/upload/{editor}">
<route id="cmf_media_file_upload" pattern="/media/file/upload/{editor}">
<default key="_controller">cmf_media.file.controller:uploadAction</default>
<default key="editor">default</default>
<default key="_format">json</default>
Expand Down
7 changes: 7 additions & 0 deletions Resources/config/routing/image.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,11 @@
<requirement key="path">.*</requirement>
</route>

<route id="cmf_media_image_upload" pattern="/media/image/upload/{editor}">
<default key="_controller">cmf_media.image.controller:uploadAction</default>
<default key="editor">default</default>
<default key="_format">json</default>
<requirement key="_method">POST</requirement>
</route>

</routes>
183 changes: 183 additions & 0 deletions Tests/Functional/Doctrine/Phpcr/MediaManagerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
<?php

namespace Symfony\Cmf\Bundle\MediaBundle\Tests\Functional\Doctrine\Phpcr;

use Symfony\Cmf\Bundle\MediaBundle\Doctrine\Phpcr\Directory;
use Symfony\Cmf\Bundle\MediaBundle\Doctrine\Phpcr\Media;
use Symfony\Cmf\Bundle\MediaBundle\Doctrine\Phpcr\MediaManager;

class MediaManagerTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
private $containerMock;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
private $registryMock;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
private $dmMock;
/**
* @var Directory
*/
private $testRoot;

public function setUp()
{
$this->containerMock = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerInterface')
->disableOriginalConstructor()
->getMock()
;
$this->registryMock = $this->getMockBuilder('Doctrine\Bundle\PHPCRBundle\ManagerRegistry')
->disableOriginalConstructor()
->getMock()
;
$this->dmMock = $this->getMockBuilder('Doctrine\ODM\PHPCR\DocumentManager')
->disableOriginalConstructor()
->getMock()
;
$this->testRoot = new Directory();
$this->testRoot->setId('/test/media');
}

private function getMediaManager()
{
return new MediaManager($this->registryMock, 'themanager', '/test/media');
}

public function testGetPath()
{
$media = new Media();
$media->setId('/test/media/mymedia');
$mediaManager = $this->getMediaManager();

$this->assertEquals('/test/media/mymedia', $mediaManager->getPath($media));
}

public function testGetUrlSafePath()
{
$media = new Media();
$media->setId('/test/media/mymedia');
$mediaManager = $this->getMediaManager();

$this->assertEquals('test/media/mymedia', $mediaManager->getUrlSafePath($media));
}

public function setDefaultsProvider()
{
return array(
array('mymedia', 'mymedia'),
array('mymedia', null, false, '/test/media/mymedia'),
array(null, 'mymedia', true),
);
}

/**
* @dataProvider setDefaultsProvider
*/
public function testSetDefaults($expectedName = null, $name = null, $nameExists = false, $id = null)
{
$returnMediaExists = $nameExists ? new Media() : null;
$rootPath = '/test/media/file';
$managerName = 'anothermanager';

$this->registryMock->expects($this->once())
->method('getManager')
->with($this->equalTo($managerName))
->will($this->returnValue($this->dmMock))
;
$this->dmMock->expects($this->any())
->method('find')
->will($this->returnValueMap(array(
array('Symfony\Cmf\Bundle\MediaBundle\Doctrine\Phpcr\Media', $rootPath.'/'.$name, $returnMediaExists),
array(null, $rootPath, $this->testRoot),
)))
;

$media = new Media();
$media->setId($id);
$media->setName($name);

$mediaManager = $this->getMediaManager();
$mediaManager->setRootPath($rootPath);
$mediaManager->setManagerName($managerName);
$mediaManager->setDefaults($media);

$this->assertEquals($this->testRoot, $media->getParent());
if ($expectedName) {
$this->assertEquals($expectedName, $media->getName());
} else {
$this->assertNotEquals($name, $media->getName());
}
}

/**
* @expectedException \RuntimeException
*/
public function testSetDefaultsException()
{
$media = new Media();

$mediaManager = $this->getMediaManager();
$mediaManager->setDefaults($media);
}

public function mapPathToIdProvider()
{
return array(
array('/test/media/mymedia', null),
array('/test/media/mymedia', '/test/media'),
);
}

/**
* @dataProvider mapPathToIdProvider
*/
public function testMapPathToId($path, $rootPath)
{
$mediaManager = $this->getMediaManager();

$this->assertEquals('/test/media/mymedia', $mediaManager->mapPathToId($path, $rootPath));
}

/**
* @expectedException \OutOfBoundsException
*/
public function testMapPathToIdException()
{
$mediaManager = $this->getMediaManager();

$mediaManager->mapPathToId('/test/media/mymedia', '/out/of/bound');
}

public function mapUrlSafePathToIdProvider()
{
return array(
array('test/media/mymedia', null),
array('test/media/mymedia', '/test/media'),
);
}

/**
* @dataProvider mapUrlSafePathToIdProvider
*/
public function testMapUrlSafePathToId($path, $rootPath)
{
$mediaManager = $this->getMediaManager();

$this->assertEquals('/test/media/mymedia', $mediaManager->mapPathToId($path, $rootPath));
}

/**
* @expectedException \OutOfBoundsException
*/
public function testMapUrlSafePathToIdException()
{
$mediaManager = $this->getMediaManager();

$mediaManager->mapUrlSafePathToId('test/media/mymedia', '/out/of/bound');
}
}
Loading

0 comments on commit 879392c

Please sign in to comment.