Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UploadFileHelper - change api to support multiple files #40

Merged
merged 4 commits into from
Aug 19, 2013
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
}
62 changes: 44 additions & 18 deletions File/UploadFileHelper.php
Original file line number Diff line number Diff line change
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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it is a good idea to refer to an "editor" here. Could we not use this upload thingy from a web form, or something else?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What use-case do you think about? Can you explain a bit more?

I think (atm) we are mostly going to automate the upload process for different web editors. And that otherwise the handleUploadedFile can be used for custom web forms were the response is created by yourself.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should check this later, added a note to the earlier created issue #34 so we do not forget.

}
}
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>
63 changes: 63 additions & 0 deletions Tests/Resources/Controller/PhpcrFileTestController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

namespace Symfony\Cmf\Bundle\MediaBundle\Tests\Resources\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Cmf\Bundle\MediaBundle\File\UploadFileHelper;
use Symfony\Component\HttpFoundation\Request;

class PhpcrFileTestController extends Controller
{
public function getUploadForm($editor = null)
{
if ($editor) {
$action = $this->generateUrl('cmf_media_file_upload', array('editor' => $editor));
} else {
$action = $this->generateUrl('phpcr_file_test_upload');
}

return $this->container->get('form.factory')->createNamedBuilder(null, 'form', null, array('action' => $action))
->add('file', 'file')
->add('submit', 'submit')
->getForm()
;
}

public function fileAction(Request $request)
{
$fileClass = 'Symfony\Cmf\Bundle\MediaBundle\Doctrine\Phpcr\File';
$dm = $this->get('doctrine_phpcr')->getManager('default');
$files = $dm->getRepository($fileClass)->findAll();

$uploadForm = $this->getUploadForm();
$editorUploadForm = $this->getUploadForm('default');

return $this->render('::tests/file.html.twig', array(
'upload_form' => $uploadForm->createView(),
'editor_form' => $editorUploadForm->createView(),
'files' => $files,
));
}

public function uploadAction(Request $request)
{
$form = $this->getUploadForm();
$form->handleRequest($request);

if ($form->isValid()) {
/** @var UploadFileHelper $uploadFileHelper */
$uploadFileHelper = $this->get('cmf_media.upload_file_helper');

$uploadedFile = $request->files->get('file');

$file = $uploadFileHelper->handleUploadedFile($uploadedFile);

// persist
$dm = $this->get('doctrine_phpcr')->getManager('default');
$dm->persist($file);
$dm->flush();
}

return $this->redirect($this->generateUrl('phpcr_file_test'));
}
}
13 changes: 0 additions & 13 deletions Tests/Resources/Controller/TestController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,8 @@

class TestController extends Controller
{
private $fileClass = 'Symfony\Cmf\Bundle\MediaBundle\Doctrine\Phpcr\File';

public function indexAction(Request $request)
{
return $this->render('::index.html.twig');
}

public function fileAction(Request $request)
{
$files = $this->get('doctrine_phpcr')
->getRepository($this->fileClass)
->findAll();

return $this->render('::tests/file.html.twig', array(
'files' => $files,
));
}
}
12 changes: 8 additions & 4 deletions Tests/Resources/DataFixtures/Phpcr/LoadMediaData.php
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<?php

namespace Symfony\Cmf\Bundle\MediaBundle\Tests\Resources\DataFixtures\Phpcr;
namespace Symfony\Cmf\Bundle\MediaBundle\Tests\Resources\DataFixtures\PHPCR;

use Doctrine\Common\DataFixtures\DependentFixtureInterface;
use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\ODM\PHPCR\Document\Generic;
use Symfony\Cmf\Bundle\MediaBundle\Doctrine\Phpcr\File;

class LoadBlockData implements FixtureInterface, DependentFixtureInterface
class LoadMediaData implements FixtureInterface, DependentFixtureInterface
{
public function getDependencies()
{
Expand All @@ -19,11 +19,15 @@ public function getDependencies()

public function load(ObjectManager $manager)
{
$root = $manager->find(null, '/test/media');
$root = $manager->find(null, '/test');
$mediaRoot = new Generic;
$mediaRoot->setNodename('media');
$mediaRoot->setParent($root);
$manager->persist($mediaRoot);

// File
$file = new File();
$file->setParent($root);
$file->setParent($mediaRoot);
$file->setName('file-1.txt');
$file->setContentFromString('Test file 1.');
$file->setContentType('text/plain');
Expand Down
1 change: 1 addition & 0 deletions Tests/Resources/app/Resources/data/testfile.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This is a test file used to test uploads.
3 changes: 2 additions & 1 deletion Tests/Resources/app/Resources/views/index.html.twig
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{% extends "::layout.html.twig" %}
{% block content %}
<h2>Tests</h2>
<h3>Phpcr</h3>
<ul>
<li><a href="{{ path('file_test') }}">File test</a></li>
<li><a href="{{ path('phpcr_file_test') }}">File test</a></li>
</ul>
<h2>About</h2>
<p>This test application is built into the MediaBundle. You can easily run
Expand Down
27 changes: 21 additions & 6 deletions Tests/Resources/app/Resources/views/tests/file.html.twig
Original file line number Diff line number Diff line change
@@ -1,9 +1,24 @@
{% extends "::layout.html.twig" %}
{% block content %}
<h2>Download file</h2>
<ul>
{% for file in files %}
<li><a href="{{ cmf_media_download_url(file) }}" title="Download {{ file.name }}">Download {{ file.name }}</a></li>
{% endfor %}
</ul>
<h2>Upload file</h2>
<h4>Standard upload</h4>
<p>The upload is handled by your own controller action. The UploadFileHelper is used to handle the upload and creates a
FileInterface object, writing the object to storage has to be implemented by yourself.</p>
{{ form(upload_form, { attr: { class: 'standard' } }) }}
<h4>Web editor upload (default)</h4>
<p>The upload is completely handled by the FileController::uploadAction. The UploadFileHelper will process the upload,
writes the created FileInterface object to storage and returns a response that depends on the editor defined in the
request.</p>
{{ form(editor_form, { attr: { class: 'editor default' } }) }}

<h2>Download file(s)</h2>
{% if files is empty %}
<p>No files found, upload a file first.</p>
{% else %}
<ul class="downloads">
{% for file in files %}
<li><a href="{{ cmf_media_download_url(file) }}" title="Download {{ file.name }}">Download {{ file.name }}</a></li>
{% endfor %}
</ul>
{% endif %}
{% endblock %}
1 change: 1 addition & 0 deletions Tests/Resources/app/config/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
$loader->import(CMF_TEST_CONFIG_DIR . '/default.php');
$loader->import(CMF_TEST_CONFIG_DIR . '/phpcr_odm.php');
$loader->import(__DIR__.'/cmf_media.yml');
$loader->import(__DIR__.'/security.yml');
16 changes: 13 additions & 3 deletions Tests/Resources/app/config/routing/cmf_media.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,20 @@ test_index:
defaults:
_controller: Symfony\Cmf\Bundle\MediaBundle\Tests\Resources\Controller\TestController::indexAction

file_test:
pattern: /file-test
phpcr_file_test:
pattern: /phpcr/file-test
defaults:
_controller: Symfony\Cmf\Bundle\MediaBundle\Tests\Resources\Controller\TestController::fileAction
_controller: Symfony\Cmf\Bundle\MediaBundle\Tests\Resources\Controller\PhpcrFileTestController::fileAction

phpcr_file_test_upload:
pattern: /phpcr/file-test/upload
defaults:
_controller: Symfony\Cmf\Bundle\MediaBundle\Tests\Resources\Controller\PhpcrFileTestController::uploadAction

phpcr_file_test_upload_editor:
pattern: /phpcr/file-test/upload/editor
defaults:
_controller: Symfony\Cmf\Bundle\MediaBundle\Tests\Resources\Controller\PhpcrFileTestController::editorUploadAction

cmf_media_file:
resource: "@CmfMediaBundle/Resources/config/routing/file.xml"
Expand Down
4 changes: 4 additions & 0 deletions Tests/Resources/app/config/security.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
security:
role_hierarchy:
ROLE_ADMIN: [ROLE_USER, ROLE_CAN_UPLOAD_FILE]
ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
Loading