Skip to content

Commit

Permalink
Updates to work with SS 4.4.* including AssetStoreRouter
Browse files Browse the repository at this point in the history
Also allows uploads via the drag and drop field
  • Loading branch information
oilee80 committed Jun 20, 2019
1 parent b11f5b3 commit eb5ad57
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 5 deletions.
129 changes: 126 additions & 3 deletions src/Forms/UploadFileField.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,61 @@

namespace MadeHQ\Cloudinary\Forms;

use MadeHQ\Cloudinary\Model\FileLink;

use SilverStripe\AssetAdmin\Controller\AssetAdmin;
use SilverStripe\AssetAdmin\Forms\UploadField;
use SilverStripe\Assets\Upload_Validator;

// use SilverStripe\ORM\ArrayList;
use SilverStripe\Core\Injector\Injector;

use SilverStripe\ORM\SS_List;
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\DataObjectInterface;

use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\FileUploadReceiver;
use SilverStripe\Forms\FormField;
use SilverStripe\Forms\TextField;
use SilverStripe\Forms\TextareaField;

use SilverStripe\View\Requirements;

use SilverStripe\Control\{
HTTPRequest,
HTTPResponse
};

class UploadFileField extends FormField
{
use FileUploadReceiver;

private $fields;

private $uploadField;

/**
* @config
* @var array
*/
private static $allowed_actions = [
'upload'
];

/**
* {@inheritdoc}
*/
public function __construct($name, $title = null, $value = null)
{
$uploadField = new UploadField(sprintf('%s[File]', $name), 'File');
$this->constructFileUploadReceiver();

// When creating new files, rename on conflict
$this->getUpload()->setReplaceFile(false);

$this->uploadField = new CustomUploadField(sprintf('%s[File]', $name), 'File');

$this->fields = [
$uploadField->setAllowedMaxFileNumber(1),
$this->uploadField->setAllowedMaxFileNumber(1),
TextField::create(sprintf('%s[Title]', $name), 'Title'),
TextareaField::create(sprintf('%s[Description]', $name), 'Description'),
];
Expand All @@ -53,6 +80,60 @@ public function addField(FormField $field)
return $this;
}

/**
* Creates a single file based on a form-urlencoded upload.
*
* @param HTTPRequest $request
* @return HTTPResponse
*/
public function upload(HTTPRequest $request)
{
if ($this->isDisabled() || $this->isReadonly()) {
return $this->httpError(403);
}

// CSRF check
$token = $this->getForm()->getSecurityToken();
if (!$token->checkRequest($request)) {
return $this->httpError(400);
}

$tmpFile = $request->postVar('Upload');
/** @var File $file */
$file = $this->saveTemporaryFile($tmpFile, $error);

// Prepare result
if ($error) {
$result = [
'message' => [
'type' => 'error',
'value' => $error,
]
];
$this->getUpload()->clearErrors();
return (new HTTPResponse(json_encode($result), 400))
->addHeader('Content-Type', 'application/json');
}

// We need an ID for getObjectFromData
if (!$file->isInDB()) {
$file->write();
}

// Return success response
$result = [
AssetAdmin::singleton()->getObjectFromData($file)
];

// Don't discard pre-generated client side canvas thumbnail
if ($result[0]['category'] === 'image') {
unset($result[0]['thumbnail']);
}
$this->getUpload()->clearErrors();
return (new HTTPResponse(json_encode($result)))
->addHeader('Content-Type', 'application/json');
}

/**
* Removes the field with the given name from the list of fields
* to show in the CMS
Expand Down Expand Up @@ -184,4 +265,46 @@ public function getValidator()
{
return Upload_Validator::create();
}

/**
* Gets the foreign class that needs to be created, or 'File' as default if there
* is no relationship, or it cannot be determined.
*
* @param string $default Default value to return if no value could be calculated
* @return string Foreign class name.
*/
public function getRelationAutosetClass($default = File::class)
{
// Don't autodetermine relation if no relationship between parent record
if (!$this->getRelationAutoSetting()) {
return $default;
}

// Check record and name
$name = $this->getName();
$record = $this->getRecord();
if (empty($name) || empty($record)) {
return $default;
} else {
$class = $record->getRelationClass($name);
if (is_subclass_of($class, FileLink::class)) {
$class = Injector::inst()->create($class)->getRelationClass('File');
}

return empty($class) ? $default : $class;
}
}
}

/**
* This is a nasty hack so that the child Upload Field ends up pointing to this field
*/
class CustomUploadField extends UploadField
{
public function Link($action = null)
{
$link = parent::Link($action);
$link = str_replace('[File]', '', $link);
return $link;
}
}
20 changes: 18 additions & 2 deletions src/Storage/CloudinaryStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

namespace MadeHQ\Cloudinary\Storage;

use SilverStripe\Assets\Storage\AssetStoreRouter;
use MadeHQ\Cloudinary\Model\File;
use SilverStripe\Assets\Storage;
use Cloudinary;
use Cloudinary\Uploader;
use SilverStripe\Control\Director;

class CloudinaryStorage implements AssetStoreRouter
class CloudinaryStorage implements Storage\AssetStore, Storage\AssetStoreRouter
{
/**
* @inheritdoc
Expand Down Expand Up @@ -35,6 +36,21 @@ public function setFromString($data, $filename, $hash = null, $variant = null, $
// intentionally empty
}

/**
* This is called from the URL `/assets/{$Filename}`
* @inheritdoc
*/
public function getResponseFor($asset)
{
$file = File::getOneByPublicId($asset);
$controller = \SilverStripe\Control\Controller::curr();
if ($file) {
return $controller->redirect($file->AbsoluteURL, 301);
}

return $controller->httpError(404, sprintf('Unable to find [%s]', $asset));
}

/**
* @inheritdoc
*/
Expand Down

0 comments on commit eb5ad57

Please sign in to comment.