Skip to content

Commit

Permalink
Merge pull request #1342 from tamcy/pull-req-1
Browse files Browse the repository at this point in the history
Add multiple uploadables feature
  • Loading branch information
l3pp4rd committed Mar 8, 2016
2 parents 480e176 + 42fae5b commit 97b67d2
Show file tree
Hide file tree
Showing 15 changed files with 448 additions and 90 deletions.
71 changes: 71 additions & 0 deletions doc/uploadable.md
Original file line number Diff line number Diff line change
Expand Up @@ -466,3 +466,74 @@ way:
$listener->setMimeTypeGuesser(new MyCustomMimeTypeGuesser());

```

### Multiple uploadables in a single entity

It is possible to configure a single entity with more than one uploadable. To do this, you need to:

* Have all Uploadable annotations under the **@Gedmo\Mapping\Annotation\Uploadables** annotation, and give every Uploadable a unique identifier.
* Specify the working configuration identifier in the field configurations.

**Important note: Multiple uploadables is currently supported via annotations only.**

Here is an example:

```php
/**
* @ORM\Entity
* @Gedmo\Uploadables(configurations={
* @Gedmo\Uploadable(identifier="image_large", pathMethod="getPath"),
* @Gedmo\Uploadable(identifier="image_thumb", pathMethod="getPath")
* })
*/
class Product
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;

/**
* @ORM\Column(type="string")
*/
private $title;

/**
* @ORM\Column(type="string")
* @Gedmo\UploadableFileName(identifier="image_thumb")
*/
private $thumbnailImageFile;

/**
* @ORM\Column(type="string")
* @Gedmo\UploadableFileName(identifier="image_large")
*/
private $largeImageFile;

public function getPath()
{
return '/tmp/path_to_upload';
}
}

```

Explanations:

- The class is annotated with a new annotation, `@Uploadables`, which accepts an array of the original `@Uploadable` definitions.
- Each Uploadable is given a unique `identifier`. This is used to distinguish different uploadable configurations.
- You also need to specify which configuration the field refers to via the `identifier` property in `@UploadableFileMimeType`, `@UploadableFileName`, `@UploadableFilePath`, and `@UploadableFileSize`.

*Note: Behind the scene, `identifier` will default to `_default` when not specified, so you don't need to worry about it in case of single upload field.*

Similarly, you need to specify which configuration the file refers to when adding file to the entity. Just pass the identifier as the third parameter of `addEntityFileInfo`, like below:

```php
$entity = new Product();
$listener->addEntityFileInfo($entity, new FileInfoArray($fileInfo), 'image_large');
$listener->addEntityFileInfo($entity, new FileInfoArray($fileInfo), 'image_thumb');
```

*Note: Again, this optional third parameter will default to `_default`, which is why you don't need to specify one in case of single upload.*
4 changes: 3 additions & 1 deletion lib/Gedmo/Mapping/Annotation/Uploadable.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@
* Uploadable annotation for Uploadable behavioral extension
*
* @Annotation
* @Target("CLASS")
* @Target({"CLASS","ANNOTATION"})
*
* @author Gustavo Falco <comfortablynumb84@gmail.com>
* @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
final class Uploadable extends Annotation
{
public $identifier = '_default';

/** @var boolean */
public $allowOverwrite = false;

Expand Down
1 change: 1 addition & 0 deletions lib/Gedmo/Mapping/Annotation/UploadableFileMimeType.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@
*/
final class UploadableFileMimeType extends Annotation
{
public $identifier = '_default';
}
1 change: 1 addition & 0 deletions lib/Gedmo/Mapping/Annotation/UploadableFileName.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@
*/
final class UploadableFileName extends Annotation
{
public $identifier = '_default';
}
1 change: 1 addition & 0 deletions lib/Gedmo/Mapping/Annotation/UploadableFilePath.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@
*/
final class UploadableFilePath extends Annotation
{
public $identifier = '_default';
}
1 change: 1 addition & 0 deletions lib/Gedmo/Mapping/Annotation/UploadableFileSize.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@
*/
final class UploadableFileSize extends Annotation
{
public $identifier = '_default';
}
22 changes: 22 additions & 0 deletions lib/Gedmo/Mapping/Annotation/Uploadables.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace Gedmo\Mapping\Annotation;

use Doctrine\Common\Annotations\Annotation;
use Gedmo\Uploadable\Mapping\Validator;

/**
* Uploadables annotation for multiple Uploadable definitions
*
* @Annotation
* @Target("CLASS")
*
* @author Gustavo Falco <comfortablynumb84@gmail.com>
* @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
final class Uploadables extends Annotation
{
/** @var array<Uploadable> @Required */
public $configurations = array();
}
20 changes: 19 additions & 1 deletion lib/Gedmo/Uploadable/Event/UploadableBaseEventArgs.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,22 +54,29 @@ abstract class UploadableBaseEventArgs extends EventArgs
*/
private $action;

/**
* @var string $identifier - The identifier this upload belongs to.
*/
private $identifier;

/**
* @param UploadableListener $listener
* @param \Doctrine\ORM\EntityManager $em
* @param array $config
* @param FileInfoInterface $fileInfo
* @param object $entity
* @param string $action
* @param string $identifier
*/
public function __construct(UploadableListener $listener, EntityManager $em, array $config, FileInfoInterface $fileInfo, $entity, $action)
public function __construct(UploadableListener $listener, EntityManager $em, array $config, FileInfoInterface $fileInfo, $entity, $action, $identifier = '_default')
{
$this->uploadableListener = $listener;
$this->em = $em;
$this->config = $config;
$this->fileInfo = $fileInfo;
$this->entity = $entity;
$this->action = $action;
$this->identifier = $identifier;
}

/**
Expand Down Expand Up @@ -131,4 +138,15 @@ public function getAction()
{
return $this->action;
}

/**
* Retrieve the identifier this upload belongs to
*
* @return string
*/
public function getIdentifier()
{
return $this->identifier;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class FilenameGeneratorAlphanumeric implements FilenameGeneratorInterface
/**
* @inheritDoc
*/
public static function generate($filename, $extension, $object = null)
public static function generate($filename, $extension, $object = null, $identifier = null)
{
return preg_replace('/[^a-z0-9]+/', '-', strtolower($filename)).$extension;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ interface FilenameGeneratorInterface
* @param string - Filename without extension
* @param string - Extension with dot: .jpg, .gif, etc
* @param $object
* @param string|null The identifier of the upload file property
*
* @return string
*/
public static function generate($filename, $extension, $object = null);
public static function generate($filename, $extension, $object = null, $identifier = null);
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ class FilenameGeneratorSha1 implements FilenameGeneratorInterface
/**
* @inheritDoc
*/
public static function generate($filename, $extension, $object = null)
public static function generate($filename, $extension, $object = null, $identifier = null)
{
return sha1(uniqid($filename.$extension, true)).$extension;
return sha1(uniqid(((null == $identifier)?'':$identifier).$filename.$extension, true)).$extension;
}
}
95 changes: 60 additions & 35 deletions lib/Gedmo/Uploadable/Mapping/Driver/Annotation.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Gedmo\Uploadable\Mapping\Driver;

use Gedmo\Mapping\Annotation\Uploadable;
use Gedmo\Mapping\Driver\AbstractAnnotationDriver;
use Gedmo\Uploadable\Mapping\Validator;

Expand All @@ -18,8 +19,9 @@
class Annotation extends AbstractAnnotationDriver
{
/**
* Annotation to define that this object is loggable
* Annotation to define that this object is uploadable
*/
const UPLOADABLES = 'Gedmo\\Mapping\\Annotation\\Uploadables';
const UPLOADABLE = 'Gedmo\\Mapping\\Annotation\\Uploadable';
const UPLOADABLE_FILE_MIME_TYPE = 'Gedmo\\Mapping\\Annotation\\UploadableFileMimeType';
const UPLOADABLE_FILE_NAME = 'Gedmo\\Mapping\\Annotation\\UploadableFileName';
Expand All @@ -34,41 +36,13 @@ public function readExtendedMetadata($meta, array &$config)
$class = $this->getMetaReflectionClass($meta);

// class annotations
if ($annot = $this->reader->getClassAnnotation($class, self::UPLOADABLE)) {
$config['uploadable'] = true;
$config['allowOverwrite'] = $annot->allowOverwrite;
$config['appendNumber'] = $annot->appendNumber;
$config['path'] = $annot->path;
$config['pathMethod'] = $annot->pathMethod;
$config['fileMimeTypeField'] = false;
$config['fileNameField'] = false;
$config['filePathField'] = false;
$config['fileSizeField'] = false;
$config['callback'] = $annot->callback;
$config['filenameGenerator'] = $annot->filenameGenerator;
$config['maxSize'] = (double) $annot->maxSize;
$config['allowedTypes'] = $annot->allowedTypes;
$config['disallowedTypes'] = $annot->disallowedTypes;

foreach ($class->getProperties() as $prop) {
if ($this->reader->getPropertyAnnotation($prop, self::UPLOADABLE_FILE_MIME_TYPE)) {
$config['fileMimeTypeField'] = $prop->getName();
}

if ($this->reader->getPropertyAnnotation($prop, self::UPLOADABLE_FILE_NAME)) {
$config['fileNameField'] = $prop->getName();
}

if ($this->reader->getPropertyAnnotation($prop, self::UPLOADABLE_FILE_PATH)) {
$config['filePathField'] = $prop->getName();
}

if ($this->reader->getPropertyAnnotation($prop, self::UPLOADABLE_FILE_SIZE)) {
$config['fileSizeField'] = $prop->getName();
}
if ($annot = $this->reader->getClassAnnotation($class, self::UPLOADABLES)) {
foreach ($annot->configurations as $uploadable) {
/* @var $uploadable \Gedmo\Mapping\Annotation\Uploadable */
$config[$uploadable->identifier] = $this->readUploadableMetadata($class, $uploadable, $meta);
}

Validator::validateConfiguration($meta, $config);
} else if ($annot = $this->reader->getClassAnnotation($class, self::UPLOADABLE)) {
$config[$annot->identifier] = $this->readUploadableMetadata($class, $annot, $meta);
}

/*
Expand Down Expand Up @@ -99,4 +73,55 @@ public function readExtendedMetadata($meta, array &$config)

$this->validateFullMetadata($meta, $config);
}

protected function readUploadableMetadata(
\ReflectionClass $class,
Uploadable $annot,
$meta)
{
$config = array();
$config['uploadable'] = true;
$config['allowOverwrite'] = $annot->allowOverwrite;
$config['appendNumber'] = $annot->appendNumber;
$config['path'] = $annot->path;
$config['pathMethod'] = $annot->pathMethod;
$config['fileMimeTypeField'] = false;
$config['fileNameField'] = false;
$config['filePathField'] = false;
$config['fileSizeField'] = false;
$config['callback'] = $annot->callback;
$config['filenameGenerator'] = $annot->filenameGenerator;
$config['maxSize'] = (double)$annot->maxSize;
$config['allowedTypes'] = $annot->allowedTypes;
$config['disallowedTypes'] = $annot->disallowedTypes;

foreach ($class->getProperties() as $prop) {
if ($propAnnot = $this->reader->getPropertyAnnotation($prop, self::UPLOADABLE_FILE_MIME_TYPE)) {
if ($propAnnot->identifier == $annot->identifier) {
$config['fileMimeTypeField'] = $prop->getName();
}
}

if ($propAnnot = $this->reader->getPropertyAnnotation($prop, self::UPLOADABLE_FILE_NAME)) {
if ($propAnnot->identifier == $annot->identifier) {
$config['fileNameField'] = $prop->getName();
}
}

if ($propAnnot = $this->reader->getPropertyAnnotation($prop, self::UPLOADABLE_FILE_PATH)) {
if ($propAnnot->identifier == $annot->identifier) {
$config['filePathField'] = $prop->getName();
}
}

if ($propAnnot = $this->reader->getPropertyAnnotation($prop, self::UPLOADABLE_FILE_SIZE)) {
if ($propAnnot->identifier == $annot->identifier) {
$config['fileSizeField'] = $prop->getName();
}
}
}

Validator::validateConfiguration($meta, $config);
return $config;
}
}

0 comments on commit 97b67d2

Please sign in to comment.