diff --git a/Adapter/Gaufrette/AbstractCmfMediaDoctrine.php b/Adapter/Gaufrette/AbstractCmfMediaDoctrine.php
index 30157bb..4ef76e6 100644
--- a/Adapter/Gaufrette/AbstractCmfMediaDoctrine.php
+++ b/Adapter/Gaufrette/AbstractCmfMediaDoctrine.php
@@ -11,6 +11,8 @@
use Symfony\Cmf\Bundle\MediaBundle\DirectoryInterface;
use Symfony\Cmf\Bundle\MediaBundle\FileInterface;
use Symfony\Cmf\Bundle\MediaBundle\HierarchyInterface;
+use Symfony\Cmf\Bundle\MediaBundle\MediaInterface;
+use Symfony\Cmf\Bundle\MediaBundle\MediaManagerInterface;
/**
* Cmf doctrine media adapter
@@ -18,17 +20,22 @@
* Gaufrette uses a key to identify a file or directory. This adapter uses a
* filesystem path, like /path/to/file/filename.ext, as key.
*
- * The abstract method getFilePath is used to get the path for a file or
- * directory object. The method mapKeyToId maps a path back to an id.
+ * The method getFilePath is used to get the path for a file or directory
+ * object. The method mapKeyToId maps a path back to an id.
+ *
+ * If you set the autoFlush flag to false, you will get better performance but
+ * must ensure that flush is called after all media operations are done.
*/
-abstract class AbstractCmfMediaDoctrine implements Adapter,
- ChecksumCalculator,
- ListKeysAware,
- MetadataSupporter
+abstract class AbstractCmfMediaDoctrine implements
+ Adapter,
+ ChecksumCalculator,
+ ListKeysAware,
+ MetadataSupporter
{
protected $managerRegistry;
protected $managerName;
protected $class;
+ protected $mediaManager;
protected $rootPath;
protected $create;
protected $dirClass;
@@ -40,24 +47,26 @@ abstract class AbstractCmfMediaDoctrine implements Adapter,
/**
* Constructor
*
- * @param ManagerRegistry $registry
- * @param string $managerName
- * @param string $class fully qualified class name of file
- * @param string $rootPath path where the filesystem is located
- * @param boolean $create whether to create the directory if
- * it does not exist (default FALSE)
- * @param string $dirClass fully qualified class name for dirs
- * (default NULL: dir is same as file)
- * @param string $identifier property used to identify a file and
- * lookup (default NULL: let Doctrine
- * determine the identifier)
- * @param boolean $autoFlush whether to flush write and delete
- * actions (default: true)
+ * @param ManagerRegistry $registry
+ * @param string $managerName
+ * @param string $class fully qualified class name of file
+ * @param MediaManagerInterface $mediaManager
+ * @param string $rootPath path where the filesystem is located
+ * @param boolean $create whether to create the directory if
+ * it does not exist (default FALSE)
+ * @param string $dirClass fully qualified class name for dirs
+ * (default NULL: dir is same as file)
+ * @param string $identifier property used to identify a file and
+ * lookup (default NULL: let Doctrine
+ * determine the identifier)
+ * @param boolean $autoFlush whether to immediately flush write
+ * and delete actions (default: true)
*/
public function __construct(
ManagerRegistry $registry,
$managerName,
$class,
+ MediaManagerInterface $mediaManager,
$rootPath = '/',
$create = false,
$dirClass = null,
@@ -67,6 +76,7 @@ public function __construct(
$this->managerRegistry = $registry;
$this->managerName = $managerName;
$this->class = $class;
+ $this->mediaManager = $mediaManager;
$this->rootPath = Util\Path::normalize($rootPath);
$this->create = $create;
$this->dirClass = $dirClass;
@@ -418,7 +428,10 @@ protected function findAll($prefix = '')
*
* @return string
*/
- abstract protected function getFilePath(FileInterface $file);
+ protected function getFilePath(MediaInterface $file)
+ {
+ return $this->mediaManager->getPath($file);
+ }
/**
* Map the key to an id to retrieve the file
@@ -430,7 +443,10 @@ abstract protected function getFilePath(FileInterface $file);
*
* @return string
*/
- abstract protected function mapKeyToId($key);
+ protected function mapKeyToId($key)
+ {
+ return $this->mediaManager->mapPathToId($key);
+ }
/**
* Computes the key from the specified path
diff --git a/Adapter/Gaufrette/PhpcrCmfMediaDoctrine.php b/Adapter/Gaufrette/PhpcrCmfMediaDoctrine.php
index 18e96ee..64ca035 100644
--- a/Adapter/Gaufrette/PhpcrCmfMediaDoctrine.php
+++ b/Adapter/Gaufrette/PhpcrCmfMediaDoctrine.php
@@ -3,35 +3,11 @@
namespace Symfony\Cmf\Bundle\MediaBundle\Gaufrette\Adapter;
use PHPCR\Util\PathHelper;
-use Symfony\Cmf\Bundle\MediaBundle\FileInterface;
-/**
- * Phpcr Cmf doctrine media adapter
- *
- * The path to a file is: /path/to/file/filename.ext
- *
- * For PHPCR the id is being the path.
- */
class PhpcrCmfMediaDoctrine extends AbstractCmfMediaDoctrine
{
/**
- * {@inheritdoc}
- */
- protected function getFilePath(FileInterface $file)
- {
- return $file->getId();
- }
-
- /**
- * {@inheritdoc}
- */
- protected function mapKeyToId($key)
- {
- return $this->computePath($key);
- }
-
- /**
- * {@inheritdoc}
+ * {@inheritDoc}
*/
protected function getParentPath($path)
{
@@ -39,10 +15,10 @@ protected function getParentPath($path)
}
/**
- * {@inheritdoc}
+ * {@inheritDoc}
*/
protected function getBaseName($path)
{
return PathHelper::getNodeName($path);
}
-}
+}
\ No newline at end of file
diff --git a/Adapter/LiipImagine/AbstractCmfMediaDoctrineLoader.php b/Adapter/LiipImagine/CmfMediaDoctrineLoader.php
similarity index 72%
rename from Adapter/LiipImagine/AbstractCmfMediaDoctrineLoader.php
rename to Adapter/LiipImagine/CmfMediaDoctrineLoader.php
index dae16ce..c9f30b7 100644
--- a/Adapter/LiipImagine/AbstractCmfMediaDoctrineLoader.php
+++ b/Adapter/LiipImagine/CmfMediaDoctrineLoader.php
@@ -8,6 +8,7 @@
use Symfony\Cmf\Bundle\MediaBundle\BinaryInterface;
use Symfony\Cmf\Bundle\MediaBundle\FileSystemInterface;
use Symfony\Cmf\Bundle\MediaBundle\ImageInterface;
+use Symfony\Cmf\Bundle\MediaBundle\MediaManagerInterface;
use Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException;
/**
@@ -15,25 +16,39 @@
*
* The path to a file is: /path/to/file/filename.ext
*/
-abstract class AbstractCmfMediaDoctrineLoader extends AbstractDoctrineLoader
+class CmfMediaDoctrineLoader extends AbstractDoctrineLoader
{
+ protected $mediaManager;
+
/**
* Constructor.
*
- * @param ImagineInterface $imagine
- * @param ManagerRegistry $registry
- * @param string $managerName
- * @param string $class fully qualified class name of image
+ * @param ImagineInterface $imagine
+ * @param ManagerRegistry $registry
+ * @param string $managerName
+ * @param MediaManagerInterface $mediaManager
+ * @param string $class fully qualified class name of image
*/
public function __construct(
ImagineInterface $imagine,
ManagerRegistry $registry,
$managerName,
+ MediaManagerInterface $mediaManager,
$class = null)
{
$manager = $registry->getManager($managerName);
parent::__construct($imagine, $manager, $class);
+
+ $this->mediaManager = $mediaManager;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function mapPathToId($path)
+ {
+ return $this->mediaManager->mapUrlSafePathToId($path);
}
/**
diff --git a/Adapter/LiipImagine/PhpcrCmfMediaDoctrineLoader.php b/Adapter/LiipImagine/PhpcrCmfMediaDoctrineLoader.php
deleted file mode 100644
index c4ff960..0000000
--- a/Adapter/LiipImagine/PhpcrCmfMediaDoctrineLoader.php
+++ /dev/null
@@ -1,22 +0,0 @@
-addCompilerPass(new EditorsCompilerPass());
+
if (class_exists('Doctrine\Bundle\PHPCRBundle\DependencyInjection\Compiler\DoctrinePhpcrMappingsPass')) {
$container->addCompilerPass(
DoctrinePhpcrMappingsPass::createXmlMappingDriver(
diff --git a/Controller/AbstractDownloadController.php b/Controller/FileController.php
similarity index 55%
rename from Controller/AbstractDownloadController.php
rename to Controller/FileController.php
index 8f402cd..a265f79 100644
--- a/Controller/AbstractDownloadController.php
+++ b/Controller/FileController.php
@@ -3,36 +3,59 @@
namespace Symfony\Cmf\Bundle\MediaBundle\Controller;
use Doctrine\Common\Persistence\ManagerRegistry;
+use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Cmf\Bundle\MediaBundle\BinaryInterface;
+use Symfony\Cmf\Bundle\MediaBundle\File\UploadFileHelper;
use Symfony\Cmf\Bundle\MediaBundle\FileInterface;
use Symfony\Cmf\Bundle\MediaBundle\FileSystemInterface;
+use Symfony\Cmf\Bundle\MediaBundle\MediaManagerInterface;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
+use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
+use Symfony\Component\Security\Core\Exception\AccessDeniedException;
+use Symfony\Component\Security\Core\SecurityContextInterface;
/**
- * Controller to handle file downloads for things that have a route
+ * Controller to handle file downloads, uploads and other things that have a route
*/
-abstract class AbstractDownloadController
+class FileController
{
protected $managerRegistry;
protected $managerName;
protected $class;
protected $rootPath;
+ protected $mediaManager;
+ protected $uploadFileHelper;
+ protected $requiredUploadRole;
+ protected $securityContext;
/**
- * @param ManagerRegistry $registry
- * @param string $managerName
- * @param string $class fully qualified class name of file
- * @param string $rootPath path where the filesystem is located
+ * @param ManagerRegistry $registry
+ * @param string $managerName
+ * @param string $class fully qualified class name of file
+ * @param string $rootPath path where the filesystem is located
+ * @param MediaManagerInterface $mediaManager
*/
- public function __construct(ManagerRegistry $registry, $managerName, $class, $rootPath = '/')
+ public function __construct(
+ ManagerRegistry $registry,
+ $managerName,
+ $class,
+ $rootPath = '/',
+ MediaManagerInterface $mediaManager,
+ UploadFileHelper $uploadFileHelper,
+ $requiredUploadRole,
+ SecurityContextInterface $securityContext = null)
{
- $this->managerRegistry = $registry;
- $this->managerName = $managerName;
- $this->class = $class === '' ? null : $class;
- $this->rootPath = $rootPath;
+ $this->managerRegistry = $registry;
+ $this->managerName = $managerName;
+ $this->class = $class === '' ? null : $class;
+ $this->rootPath = $rootPath;
+ $this->mediaManager = $mediaManager;
+ $this->uploadFileHelper = $uploadFileHelper;
+ $this->requiredUploadRole = $requiredUploadRole;
+ $this->securityContext = $securityContext;
}
/**
@@ -72,7 +95,7 @@ public function setRootPath($rootPath)
* Get the object manager from the registry, based on the current
* managerName
*
- * @return \Doctrine\Common\Persistence\ObjectManager
+ * @return ObjectManager
*/
protected function getObjectManager()
{
@@ -80,26 +103,25 @@ protected function getObjectManager()
}
/**
- * Map the requested path (ie. subpath in the URL) to an id that can
- * be used to lookup the file in the Doctrine store.
+ * Action to download a file object that has a route
*
* @param string $path
- *
- * @return string
- */
- abstract protected function mapPathToId($path);
-
- /**
- * Action to download a document that has a route
- *
- * @param string $id
*/
public function downloadAction($path)
{
- $contentDocument = $this->getObjectManager()->find($this->class, $this->mapPathToId($path));
+ try {
+ $id = $this->mediaManager->mapUrlSafePathToId($path, $this->rootPath);
+ } catch (\OutOfBoundsException $e) {
+ throw new NotFoundHttpException($e->getMessage());
+ }
+
+ $contentDocument = $this->getObjectManager()->find($this->class, $id);
if (! $contentDocument || ! $contentDocument instanceof FileInterface) {
- throw new NotFoundHttpException('Content is no file');
+ throw new NotFoundHttpException(sprintf(
+ 'Object with identifier %s cannot be resolved to a valid instance of Symfony\Cmf\Bundle\MediaBundle\FileInterface',
+ $path
+ ));
}
$file = false;
@@ -128,4 +150,19 @@ public function downloadAction($path)
return $response;
}
+
+ /**
+ * Action to upload a file
+ *
+ * @param Request $request
+ * @return Response
+ */
+ public function uploadAction(Request $request)
+ {
+ if ($this->securityContext && false === $this->securityContext->isGranted($this->requiredUploadRole)) {
+ throw new AccessDeniedException();
+ }
+
+ return $this->uploadFileHelper->getUploadResponse($request);
+ }
}
diff --git a/Controller/ImageController.php b/Controller/ImageController.php
new file mode 100644
index 0000000..79e5bba
--- /dev/null
+++ b/Controller/ImageController.php
@@ -0,0 +1,44 @@
+mediaManager->mapUrlSafePathToId($path, $this->rootPath);
+ } catch (\OutOfBoundsException $e) {
+ throw new NotFoundHttpException($e->getMessage());
+ }
+
+ $contentObject = $this->getObjectManager()->find($this->class, $id);
+
+ if (! $contentObject || ! $contentObject instanceof ImageInterface) {
+ throw new NotFoundHttpException(sprintf(
+ 'Object with identifier %s cannot be resolved to a valid instance of Symfony\Cmf\Bundle\MediaBundle\ImageInterface',
+ $path
+ ));
+ }
+
+ $response = new Response($contentObject->getContentAsString());
+ $response->headers->set('Content-Type', $contentObject->getContentType());
+
+ return $response;
+ }
+}
diff --git a/Controller/PhpcrDownloadController.php b/Controller/PhpcrDownloadController.php
deleted file mode 100644
index b6fd512..0000000
--- a/Controller/PhpcrDownloadController.php
+++ /dev/null
@@ -1,31 +0,0 @@
-rootPath)) {
- throw new NotFoundHttpException(sprintf(
- 'The path "%s" is out of the root path "%s" were the file system is located.',
- $path,
- $this->rootPath
- ));
- }
-
- return $id;
- }
-}
diff --git a/DependencyInjection/CmfMediaExtension.php b/DependencyInjection/CmfMediaExtension.php
index a1c4529..c45b00b 100644
--- a/DependencyInjection/CmfMediaExtension.php
+++ b/DependencyInjection/CmfMediaExtension.php
@@ -4,6 +4,7 @@
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
@@ -13,8 +14,28 @@
*
* To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html}
*/
-class CmfMediaExtension extends Extension
+class CmfMediaExtension extends Extension implements PrependExtensionInterface
{
+ /**
+ * {@inheritDoc}
+ */
+ public function prepend(ContainerBuilder $container)
+ {
+ // get all Bundles
+ $bundles = $container->getParameter('kernel.bundles');
+
+ if (isset($bundles['CmfCreateBundle'])) {
+ $config = array(
+ 'image' => array(
+ 'enabled' => true,
+ 'model_class' => '%cmf_media.image_class%',
+ 'basepath' => '%cmf_media.media_basepath%',
+ ),
+ );
+ $container->prependExtensionConfig('cmf_create', $config);
+ }
+ }
+
/**
* {@inheritDoc}
*/
@@ -33,6 +54,7 @@ public function load(array $configs, ContainerBuilder $container)
$container->setParameter($this->getAlias() . '.media_basepath', $config['media_basepath']);
$container->setParameter($this->getAlias() . '.manager_registry', $config['manager_registry']);
$container->setParameter($this->getAlias() . '.manager_name', $config['manager_name']);
+ $container->setParameter($this->getAlias() . '.upload_file_role', $config['upload_file_role']);
if (isset($config['media_class'])) {
$container->setParameter($this->getAlias() . '.media_class', $config['media_class']);
@@ -54,7 +76,13 @@ public function load(array $configs, ContainerBuilder $container)
$this->loadDefaultClasses($config, $container);
- $this->loadLiipImagine($config, $loader, $container);
+ if ($config['use_imagine']) {
+ $this->loadLiipImagine($config, $loader, $container);
+ }
+
+ if ($config['use_jms_serializer']) {
+ $this->loadJmsSerializer($config, $loader, $container);
+ }
}
public function loadDefaultClasses($config, ContainerBuilder $container)
@@ -101,7 +129,17 @@ public function loadLiipImagine($config, XmlFileLoader $loader, ContainerBuilder
$container->setParameter($this->getAlias() . '.imagine.filter', $config['imagine_filter']);
$container->setParameter($this->getAlias() . '.imagine.all_filters', $filters);
- $loader->load($config['manager_registry'] . '.imagine.xml');
+ $loader->load('imagine.'.$config['manager_registry'].'.xml');
+ }
+
+ public function loadJmsSerializer($config, XmlFileLoader $loader, ContainerBuilder $container)
+ {
+ $bundles = $container->getParameter('kernel.bundles');
+ if ('auto' === $config['use_jms_serializer'] && !isset($bundles['JMSSerializerBundle'])) {
+ return;
+ }
+
+ $loader->load('serializer.xml');
}
/**
diff --git a/DependencyInjection/Compiler/EditorsCompilerPass.php b/DependencyInjection/Compiler/EditorsCompilerPass.php
new file mode 100644
index 0000000..91ddc3f
--- /dev/null
+++ b/DependencyInjection/Compiler/EditorsCompilerPass.php
@@ -0,0 +1,23 @@
+findTaggedServiceIds('cmf_media.upload_editor_helper');
+
+ if (count($tags) > 0 && $container->hasDefinition('cmf_media.upload_file_helper')) {
+ $manager = $container->getDefinition('cmf_media.upload_file_helper');
+
+ foreach ($tags as $id => $tag) {
+ $manager->addMethodCall('addEditorHelper', array($tag[0]['alias'], new Reference($id)));
+ }
+ }
+ }
+}
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index fbc5d75..7a0dbfb 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -33,6 +33,12 @@ public function getConfigTreeBuilder()
->scalarNode('file_class')->defaultNull()->end()
->scalarNode('directory_class')->defaultNull()->end()
->scalarNode('image_class')->defaultNull()->end()
+ ->scalarNode('upload_file_role')->defaultValue('ROLE_CAN_UPLOAD_FILE')->end()
+
+ ->enumNode('use_jms_serializer')
+ ->values(array(true, false, 'auto'))
+ ->defaultValue('auto')
+ ->end()
->end()
;
diff --git a/Doctrine/Phpcr/ImageRepository.php b/Doctrine/Phpcr/ImageRepository.php
new file mode 100644
index 0000000..d7cc877
--- /dev/null
+++ b/Doctrine/Phpcr/ImageRepository.php
@@ -0,0 +1,48 @@
+rootPath = $rootPath;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function searchImages($term, $limit = 0, $offset = 0)
+ {
+ $qb = $this->createQueryBuilder();
+
+ if ($this->rootPath) {
+ $qb->andWhere($qb->expr()->descendant($this->rootPath));
+ }
+
+ if (strlen($term)) {
+ $qb->andWhere(
+ $qb->expr()->orX(
+ $qb->expr()->likeNodeName('%'.$term.'%'),
+ $qb->expr()->like('description', '%'.$term.'%')
+ )
+ );
+ }
+
+ $qb->setFirstResult($offset);
+ $qb->setMaxResults($limit);
+
+ return $qb->getQuery()->execute();
+ }
+}
\ No newline at end of file
diff --git a/Doctrine/Phpcr/Media.php b/Doctrine/Phpcr/Media.php
index a1264b0..2701466 100644
--- a/Doctrine/Phpcr/Media.php
+++ b/Doctrine/Phpcr/Media.php
@@ -22,6 +22,14 @@ class Media extends BaseMedia implements HierarchyInterface
*/
protected $updatedBy;
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->name ? $this->name : parent::__toString();
+ }
+
/**
* @param Object $parent
*/
diff --git a/Doctrine/Phpcr/MediaManager.php b/Doctrine/Phpcr/MediaManager.php
new file mode 100644
index 0000000..ef3dfa7
--- /dev/null
+++ b/Doctrine/Phpcr/MediaManager.php
@@ -0,0 +1,154 @@
+managerRegistry = $registry;
+ $this->managerName = $managerName;
+ $this->rootPath = $rootPath;
+ }
+
+ /**
+ * Set the managerName to use to get the object manager;
+ * if not called, the default manager will be used.
+ *
+ * @param string $managerName
+ */
+ 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.
+ *
+ * @param string $rootPath
+ */
+ public function setRootPath($rootPath)
+ {
+ $this->rootPath = $rootPath;
+ }
+
+ /**
+ * Get the object manager from the registry, based on the current
+ * managerName
+ *
+ * @return DocumentManager
+ */
+ protected function getObjectManager()
+ {
+ return $this->managerRegistry->getManager($this->managerName);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getPath(MediaInterface $media)
+ {
+ return $media->getId();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getUrlSafePath(MediaInterface $media)
+ {
+ return ltrim($media->getId(), '/');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setDefaults(MediaInterface $media, $parentPath = null)
+ {
+ $class = ClassUtils::getClass($media);
+
+ // check and add name if possible
+ if (!$media->getName()) {
+ if ($media->getId()) {
+ $media->setName(PathHelper::getNodeName($media->getId()));
+ } else {
+ throw new \RuntimeException(sprintf(
+ 'Unable to set defaults, Media of type "%s" does not have a name or id.',
+ $class
+ ));
+ }
+ }
+
+ $rootPath = is_null($parentPath) ? $this->rootPath : $parentPath;
+ $path = ($rootPath === '/' ? $rootPath : $rootPath . '/') . $media->getName();
+
+ /** @var DocumentManager $dm */
+ $dm = $this->getObjectManager();
+
+ // TODO use PHPCR autoname once this is done: http://www.doctrine-project.org/jira/browse/PHPCR-103
+ if ($dm->find($class, $path)) {
+ // path already exists
+ $media->setName($media->getName() . '_' . time() . '_' . rand());
+ }
+
+ if (!$media->getParent()) {
+ $parent = $dm->find(null, PathHelper::getParentPath($path));
+ $media->setParent($parent);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function mapPathToId($path, $rootPath = null)
+ {
+ // The path is being the id
+ $id = PathHelper::absolutizePath($path, '/');
+
+ if (is_string($rootPath) && 0 !== strpos($id, $rootPath)) {
+ throw new \OutOfBoundsException(sprintf(
+ 'The path "%s" is out of the root path "%s" were the file system is located.',
+ $path,
+ $rootPath
+ ));
+ }
+
+ return $id;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function mapUrlSafePathToId($path, $rootPath = null)
+ {
+ return $this->mapPathToId($path, $rootPath);
+ }
+}
\ No newline at end of file
diff --git a/Editor/Helper/UploadCkeditorHelper.php b/Editor/Helper/UploadCkeditorHelper.php
new file mode 100644
index 0000000..e39dcac
--- /dev/null
+++ b/Editor/Helper/UploadCkeditorHelper.php
@@ -0,0 +1,26 @@
+mediaManager->getUrlSafePath($file);
+ $url = $this->router->generate('cmf_media_image_display', array('path' => $urlSafePath));
+ $funcNum = $request->query->get('CKEditorFuncNum');
+
+ $data = "";
+
+ $response = new Response($data);
+ $response->headers->set('Content-Type', 'text/html');
+
+ return $response;
+ }
+}
\ No newline at end of file
diff --git a/Editor/Helper/UploadDefaultHelper.php b/Editor/Helper/UploadDefaultHelper.php
new file mode 100644
index 0000000..bb11697
--- /dev/null
+++ b/Editor/Helper/UploadDefaultHelper.php
@@ -0,0 +1,54 @@
+mediaManager = $mediaManager;
+ $this->router = $router;
+ $this->propertyMapping = $propertyMapping;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setFileDefaults(Request $request, FileInterface $file)
+ {
+ // map request parameters to Media properties
+ foreach ($this->propertyMapping as $param => $property) {
+ if (strlen($request->get($param))) {
+ $setter = 'set' . ucfirst($property);
+ $file->$setter($request->get($param));
+ }
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getUploadResponse(Request $request, FileInterface $file)
+ {
+ $urlSafePath = $this->mediaManager->getUrlSafePath($file);
+
+ return new RedirectResponse($this->router->generate('cmf_media_image_display', array('path' => $urlSafePath)));
+ }
+}
\ No newline at end of file
diff --git a/Editor/UploadEditorHelperInterface.php b/Editor/UploadEditorHelperInterface.php
new file mode 100644
index 0000000..392a253
--- /dev/null
+++ b/Editor/UploadEditorHelperInterface.php
@@ -0,0 +1,29 @@
+manager = $manager;
- $this->container = $container;
- $this->filters = $filters;
+ $this->mediaManager = $mediaManager;
+ $this->manager = $manager;
+ $this->container = $container;
+ $this->filters = $filters;
}
/**
@@ -101,7 +109,7 @@ private function invalidateCache(LifecycleEventArgs $args)
return;
}
foreach ($this->filters as $filter) {
- $path = $this->manager->resolve($request, $this->getPath($object), $filter);
+ $path = $this->manager->resolve($request, $this->mediaManager->getUrlSafePath($object), $filter);
if ($path instanceof RedirectResponse) {
$path = $path->getTargetUrl();
}
@@ -114,11 +122,4 @@ private function invalidateCache(LifecycleEventArgs $args)
}
}
}
-
- /**
- * Get path for imagine
- *
- * @return string
- */
- abstract protected function getPath(FileInterface $file);
}
diff --git a/EventListener/PhpcrImagineCacheInvalidatorSubscriber.php b/EventListener/PhpcrImagineCacheInvalidatorSubscriber.php
deleted file mode 100644
index 095ac60..0000000
--- a/EventListener/PhpcrImagineCacheInvalidatorSubscriber.php
+++ /dev/null
@@ -1,25 +0,0 @@
-getId();
- }
-}
diff --git a/File/UploadFileHelper.php b/File/UploadFileHelper.php
new file mode 100644
index 0000000..c987acc
--- /dev/null
+++ b/File/UploadFileHelper.php
@@ -0,0 +1,171 @@
+managerRegistry = $registry;
+ $this->managerName = $managerName;
+ $this->class = $class === '' ? null : $class;
+ $this->rootPath = $rootPath;
+ $this->mediaManager = $mediaManager;
+ }
+
+ /**
+ * Set the managerName to use to get the object manager;
+ * if not called, the default manager will be used.
+ *
+ * @param string $managerName
+ */
+ 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.
+ *
+ * @param string $rootPath
+ */
+ public function setRootPath($rootPath)
+ {
+ $this->rootPath = $rootPath;
+ }
+
+ /**
+ * Get the object manager from the registry, based on the current
+ * managerName
+ *
+ * @return ObjectManager
+ */
+ protected function getObjectManager()
+ {
+ return $this->managerRegistry->getManager($this->managerName);
+ }
+
+ /**
+ * Add an editor helper
+ *
+ * @param string $name
+ * @param EditorHelperInterface $helper
+ */
+ public function addEditorHelper($name, UploadEditorHelperInterface $helper)
+ {
+ $this->editorHelpers[$name] = $helper;
+ }
+
+ /**
+ * Get helper
+ *
+ * @param $name leave null to get the default helper
+ *
+ * @return UploadEditorHelperInterface|null
+ */
+ public function getEditorHelper($name = null)
+ {
+ if ($name && isset($this->editorHelpers[$name])) {
+ return $this->editorHelpers[$name];
+ }
+
+ return isset($this->editorHelpers['default']) ? $this->editorHelpers['default'] : null;
+ }
+
+ /**
+ * Validate the uploaded file
+ *
+ * @param UploadedFile $file
+ *
+ * @return bool
+ */
+ protected function validateFile(UploadedFile $file)
+ {
+ return true;
+ }
+
+ /**
+ * Process upload and get a response
+ *
+ * @return Response
+ */
+ public function getUploadResponse(Request $request)
+ {
+ /** @var \Symfony\Cmf\Bundle\MediaBundle\Editor\EditorHelperInterface $editorHelper */
+ $editorHelper = $this->getEditorHelper($request->get('editor', 'default'));
+
+ if (! $editorHelper) {
+ throw new HttpException(409, sprintf(
+ 'Editor type "%s" not found, cannot process upload.',
+ $request->get('editor', 'default')
+ ));
+ }
+
+ $files = $request->files;
+
+ /** @var $file UploadedFile */
+ $uploadedFile = $files->getIterator()->current();
+ $this->validateFile($uploadedFile);
+
+ /** @var $image FileInterface */
+ $file = new $this->class;
+ $file->setName($uploadedFile->getClientOriginalName());
+ $file->copyContentFromFile($uploadedFile);
+
+ $editorHelper->setFileDefaults($request, $file);
+
+ try {
+ $this->mediaManager->setDefaults($file, $this->rootPath);
+ } catch (\RuntimeException $e) {
+ throw new HttpException(409, $e->getMessage());
+ }
+
+ // persist
+ $this->getObjectManager()->persist($file);
+ $this->getObjectManager()->flush();
+
+ // response
+ return $editorHelper->getUploadResponse($request, $file);
+ }
+}
\ No newline at end of file
diff --git a/MediaManagerInterface.php b/MediaManagerInterface.php
new file mode 100644
index 0000000..9d1b0dc
--- /dev/null
+++ b/MediaManagerInterface.php
@@ -0,0 +1,77 @@
+
diff --git a/Resources/config/doctrine_phpcr.xml b/Resources/config/doctrine_phpcr.xml
index 5037c14..42dda5c 100644
--- a/Resources/config/doctrine_phpcr.xml
+++ b/Resources/config/doctrine_phpcr.xml
@@ -5,8 +5,10 @@
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
- Symfony\Cmf\Bundle\MediaBundle\Controller\PhpcrDownloadController
- Symfony\Cmf\Bundle\MediaBundle\Templating\Helper\PhpcrMediaHelper
+ Symfony\Cmf\Bundle\MediaBundle\Doctrine\Phpcr\MediaManager
+ Symfony\Cmf\Bundle\MediaBundle\File\UploadFileHelper
+ Symfony\Cmf\Bundle\MediaBundle\Controller\FileController
+ Symfony\Cmf\Bundle\MediaBundle\Controller\ImageController
@@ -17,16 +19,40 @@
-
+
+
+ %cmf_media.manager_name%
+ %cmf_media.media_basepath%
+
+
+
+
+ %cmf_media.manager_name%
+ %cmf_media.image_class%
+ %cmf_media.media_basepath%
+
+
+
+
%cmf_media.manager_name%
- /
+ %cmf_media.media_basepath%
+
+
+ %cmf_media.upload_file_role%
+
-
-
-
+
+
+ %cmf_media.manager_name%
+
+ %cmf_media.media_basepath%
+
+
+ %cmf_media.upload_file_role%
+
diff --git a/Resources/config/doctrine_orm.imagine.xml b/Resources/config/imagine.doctrine_orm.xml
similarity index 100%
rename from Resources/config/doctrine_orm.imagine.xml
rename to Resources/config/imagine.doctrine_orm.xml
diff --git a/Resources/config/doctrine_phpcr.imagine.xml b/Resources/config/imagine.doctrine_phpcr.xml
similarity index 64%
rename from Resources/config/doctrine_phpcr.imagine.xml
rename to Resources/config/imagine.doctrine_phpcr.xml
index 92b1e31..5144208 100644
--- a/Resources/config/doctrine_phpcr.imagine.xml
+++ b/Resources/config/imagine.doctrine_phpcr.xml
@@ -5,23 +5,25 @@
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
- Symfony\Cmf\Bundle\MediaBundle\Adapter\LiipImagine\PhpcrCmfMediaDoctrineLoader
- Symfony\Cmf\Bundle\MediaBundle\EventListener\PhpcrImagineCacheInvalidatorSubscriber
+ Symfony\Cmf\Bundle\MediaBundle\Adapter\LiipImagine\CmfMediaDoctrineLoader
+ Symfony\Cmf\Bundle\MediaBundle\EventListener\ImagineCacheInvalidatorSubscriber
-
+
%cmf_media.manager_name%
+
%cmf_media.image_class%
-
-
-
+
+
+
+
%cmf_media.imagine.all_filters%
diff --git a/Resources/config/routing/file.xml b/Resources/config/routing/file.xml
new file mode 100644
index 0000000..76401f6
--- /dev/null
+++ b/Resources/config/routing/file.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+ cmf_media.file.controller:downloadAction
+ GET
+ .*
+
+
+
+ cmf_media.file.controller:uploadAction
+ default
+ json
+ POST
+
+
diff --git a/Resources/config/routing/download.xml b/Resources/config/routing/image.xml
similarity index 61%
rename from Resources/config/routing/download.xml
rename to Resources/config/routing/image.xml
index 235c9c5..700a220 100644
--- a/Resources/config/routing/download.xml
+++ b/Resources/config/routing/image.xml
@@ -4,8 +4,9 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
-
- cmf_media.download_controller:downloadAction
+
+ cmf_media.image.controller:displayAction
+ GET
.*
diff --git a/Resources/config/serializer.xml b/Resources/config/serializer.xml
new file mode 100644
index 0000000..ec61a1d
--- /dev/null
+++ b/Resources/config/serializer.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+ Symfony\Cmf\Bundle\MediaBundle\Serializer\Handler
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Resources/config/services.xml b/Resources/config/services.xml
index 1640e26..311bd52 100644
--- a/Resources/config/services.xml
+++ b/Resources/config/services.xml
@@ -6,20 +6,47 @@
Symfony\Cmf\Bundle\MediaBundle\Form\Type\ImageType
+ Symfony\Cmf\Bundle\MediaBundle\Templating\Helper\MediaHelper
Symfony\Cmf\Bundle\MediaBundle\Twig\Extension\MediaExtension
+ Symfony\Cmf\Bundle\MediaBundle\Editor\Helper\UploadDefaultHelper
+ Symfony\Cmf\Bundle\MediaBundle\Editor\Helper\UploadCkeditorHelper
-
+
%cmf_media.image_class%
%cmf_media.use_imagine%
%cmf_media.imagine.filter%
+
+
+
+
+ %cmf_media.use_imagine%
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+ description
+ description
+
+
+
+
+
+
+
diff --git a/Resources/views/Form/fields.html.twig b/Resources/views/Form/fields.html.twig
index 163ceea..e868f43 100644
--- a/Resources/views/Form/fields.html.twig
+++ b/Resources/views/Form/fields.html.twig
@@ -1,8 +1,8 @@
{% block cmf_media_image_widget %}
{{ form_widget(form) }}
{% block cmf_media_image_widget_preview %}
- {% if form.vars.data and form.vars.data.id and imagine_filter %}
-
+ {% if form.vars.data and form.vars.data.id %}
+
{% endif %}
{% endblock %}
{% endblock %}
\ No newline at end of file
diff --git a/Serializer/Handler.php b/Serializer/Handler.php
new file mode 100644
index 0000000..7f6b47c
--- /dev/null
+++ b/Serializer/Handler.php
@@ -0,0 +1,51 @@
+mediaManager = $mediaManager;
+ $this->router = $router;
+ }
+
+ /**
+ * Handles the serialization of an Image object
+ *
+ * @param JsonSerializationVisitor $visitor
+ * @param ImageInterface $image
+ * @return array
+ */
+ public function serializeImageToArray(JsonSerializationVisitor $visitor, ImageInterface $image)
+ {
+ $urlSafePath = $this->mediaManager->getUrlSafePath($image);
+ $url = $this->router->generate('cmf_media_image_display', array('path' => $urlSafePath), true);
+
+ return array(
+ 'id' => $image->getId(),
+ 'name' => $image->getName(),
+ 'url' => $url,
+ 'alt' => $image->getDescription()
+ );
+ }
+
+}
diff --git a/Templating/Helper/AbstractMediaHelper.php b/Templating/Helper/AbstractMediaHelper.php
deleted file mode 100644
index 9878541..0000000
--- a/Templating/Helper/AbstractMediaHelper.php
+++ /dev/null
@@ -1,54 +0,0 @@
-generator = $router;
- }
-
- /**
- * Generates a download URL from the given file.
- *
- * @param FileInterface $file
- * @param Boolean|string $referenceType The type of reference (one of the constants in UrlGeneratorInterface)
- *
- * @return string The generated URL
- */
- public function downloadUrl(FileInterface $file, $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH)
- {
- $path = $this->getFilePath($file);
-
- return $this->generator->generate('cmf_media_download', array('path' => ltrim($path, '/')), $referenceType);
- }
-
- /**
- * Get full file path: /path/to/file/filename.ext
- *
- * @return string
- */
- abstract protected function getFilePath(FileInterface $file);
-
- /**
- * Returns the canonical name of this helper.
- *
- * @return string The canonical name
- */
- public function getName()
- {
- return 'cmf_media';
- }
-}
diff --git a/Templating/Helper/MediaHelper.php b/Templating/Helper/MediaHelper.php
new file mode 100644
index 0000000..1c374d3
--- /dev/null
+++ b/Templating/Helper/MediaHelper.php
@@ -0,0 +1,81 @@
+mediaManager = $mediaManager;
+ $this->generator = $router;
+ $this->useImagine = $useImagine;
+ $this->imagineHelper = $imagineHelper;
+ }
+
+ /**
+ * Generates a download URL from the given file.
+ *
+ * @param FileInterface $file
+ * @param Boolean|string $referenceType The type of reference (one of the constants in UrlGeneratorInterface)
+ *
+ * @return string The generated URL
+ */
+ public function downloadUrl(FileInterface $file, $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH)
+ {
+ $urlSafePath = $this->mediaManager->getUrlSafePath($file);
+
+ return $this->generator->generate('cmf_media_download', array('path' => $urlSafePath), $referenceType);
+ }
+
+ /**
+ * Generates a display URL from the given image.
+ *
+ * @param ImageInterface $file
+ * @param array $options
+ * @param Boolean|string $referenceType The type of reference (one of the constants in UrlGeneratorInterface)
+ *
+ * @return string The generated URL
+ */
+ public function displayUrl(ImageInterface $file, array $options = array(), $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH)
+ {
+ $urlSafePath = $this->mediaManager->getUrlSafePath($file);
+
+ if ($this->useImagine && $this->imagineHelper && isset($options['imagine_filter']) && is_string($options['imagine_filter'])) {
+ return $this->imagineHelper->filter(
+ $urlSafePath,
+ $options['imagine_filter'],
+ $referenceType === UrlGeneratorInterface::ABSOLUTE_URL
+ );
+ }
+
+ return $this->generator->generate('cmf_media_image_display', array('path' => $urlSafePath), $referenceType);
+ }
+
+ /**
+ * Returns the canonical name of this helper.
+ *
+ * @return string The canonical name
+ */
+ public function getName()
+ {
+ return 'cmf_media';
+ }
+}
diff --git a/Templating/Helper/PhpcrMediaHelper.php b/Templating/Helper/PhpcrMediaHelper.php
deleted file mode 100644
index 5cc29c8..0000000
--- a/Templating/Helper/PhpcrMediaHelper.php
+++ /dev/null
@@ -1,16 +0,0 @@
-getId();
- }
-}
diff --git a/Twig/Extension/MediaExtension.php b/Twig/Extension/MediaExtension.php
index 8b7ebfd..8b18ad3 100644
--- a/Twig/Extension/MediaExtension.php
+++ b/Twig/Extension/MediaExtension.php
@@ -2,15 +2,18 @@
namespace Symfony\Cmf\Bundle\MediaBundle\Twig\Extension;
-use Symfony\Cmf\Bundle\MediaBundle\Templating\Helper\AbstractMediaHelper;
+use Symfony\Cmf\Bundle\MediaBundle\Templating\Helper\MediaHelper;
class MediaExtension extends \Twig_Extension
{
- protected $mediaHelper;
+ protected $mediaManager;
- public function __construct(AbstractMediaHelper $mediaHelper)
+ /**
+ * @param MediaHelper $mediaManager
+ */
+ public function __construct(MediaHelper $mediaManager)
{
- $this->mediaHelper = $mediaHelper;
+ $this->mediaManager = $mediaManager;
}
/**
@@ -22,7 +25,11 @@ public function getFunctions()
{
return array(
new \Twig_SimpleFunction('cmf_media_download_url',
- array($this->mediaHelper, 'downloadUrl'),
+ array($this->mediaManager, 'downloadUrl'),
+ array('is_safe' => array('html'))
+ ),
+ new \Twig_SimpleFunction('cmf_media_display_url',
+ array($this->mediaManager, 'displayUrl'),
array('is_safe' => array('html'))
),
);