2014-05-14 23:24:20 +10:00
|
|
|
<?php namespace Backend\FormWidgets;
|
|
|
|
|
2014-08-22 14:38:53 +10:00
|
|
|
use Str;
|
2014-05-14 23:24:20 +10:00
|
|
|
use Input;
|
|
|
|
use Validator;
|
|
|
|
use System\Models\File;
|
2015-01-28 18:03:35 +11:00
|
|
|
use SystemException;
|
2014-12-05 18:35:42 +11:00
|
|
|
use Backend\Classes\FormField;
|
2014-05-14 23:24:20 +10:00
|
|
|
use Backend\Classes\FormWidgetBase;
|
2015-01-28 18:03:35 +11:00
|
|
|
use ValidationException;
|
2014-09-06 22:02:56 +10:00
|
|
|
use Exception;
|
2014-05-14 23:24:20 +10:00
|
|
|
|
|
|
|
/**
|
|
|
|
* File upload field
|
|
|
|
* Renders a form file uploader field.
|
|
|
|
*
|
|
|
|
* Supported options:
|
|
|
|
* - mode: image-single, image-multi, file-single, file-multi
|
|
|
|
* - upload-label: Add file
|
|
|
|
* - empty-label: No file uploaded
|
|
|
|
*
|
|
|
|
* @package october\backend
|
|
|
|
* @author Alexey Bobkov, Samuel Georges
|
|
|
|
*/
|
|
|
|
class FileUpload extends FormWidgetBase
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* {@inheritDoc}
|
|
|
|
*/
|
|
|
|
public $defaultAlias = 'fileupload';
|
|
|
|
|
2015-01-31 15:31:46 +11:00
|
|
|
/**
|
|
|
|
* @var int Preview image width
|
|
|
|
*/
|
2014-05-14 23:24:20 +10:00
|
|
|
public $imageWidth;
|
2015-01-31 15:31:46 +11:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @var int Preview image height
|
|
|
|
*/
|
2014-05-14 23:24:20 +10:00
|
|
|
public $imageHeight;
|
2015-01-31 15:31:46 +11:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @var string Text to display when no file is associated
|
|
|
|
*/
|
2014-05-21 17:51:50 +11:00
|
|
|
public $previewNoFilesMessage;
|
2014-05-14 23:24:20 +10:00
|
|
|
|
2015-01-31 15:31:46 +11:00
|
|
|
/**
|
|
|
|
* @var mixed Collection of acceptable file types.
|
|
|
|
*/
|
|
|
|
public $acceptedFileTypes;
|
|
|
|
|
2014-05-14 23:24:20 +10:00
|
|
|
/**
|
|
|
|
* {@inheritDoc}
|
|
|
|
*/
|
|
|
|
public function init()
|
|
|
|
{
|
|
|
|
$this->imageHeight = $this->getConfig('imageHeight', 100);
|
|
|
|
$this->imageWidth = $this->getConfig('imageWidth', 100);
|
2015-01-31 15:31:46 +11:00
|
|
|
$this->acceptedFileTypes = $this->getConfig('fileTypes');
|
2014-10-10 23:50:05 +02:00
|
|
|
$this->previewNoFilesMessage = $this->getConfig(
|
|
|
|
'previewNoFilesMessage',
|
|
|
|
'backend::lang.form.preview_no_files_message'
|
|
|
|
);
|
2014-10-20 18:55:31 +11:00
|
|
|
|
2014-05-14 23:24:20 +10:00
|
|
|
$this->checkUploadPostback();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* {@inheritDoc}
|
|
|
|
*/
|
|
|
|
public function render()
|
|
|
|
{
|
|
|
|
$this->prepareVars();
|
|
|
|
return $this->makePartial('container');
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Prepares the view data
|
|
|
|
*/
|
|
|
|
public function prepareVars()
|
|
|
|
{
|
|
|
|
$this->vars['fileList'] = $this->getFileList();
|
|
|
|
$this->vars['singleFile'] = array_get($this->vars['fileList'], 0, null);
|
|
|
|
$this->vars['displayMode'] = $this->getDisplayMode();
|
|
|
|
$this->vars['emptyIcon'] = $this->getConfig('emptyIcon', 'icon-plus');
|
|
|
|
$this->vars['imageHeight'] = $this->imageHeight;
|
|
|
|
$this->vars['imageWidth'] = $this->imageWidth;
|
2015-01-31 15:31:46 +11:00
|
|
|
$this->vars['acceptedFileTypes'] = $this->getAcceptedFileTypes(true);
|
2014-05-14 23:24:20 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
protected function getFileList()
|
|
|
|
{
|
2014-09-06 21:46:19 +10:00
|
|
|
$list = $this->getRelationObject()->withDeferred($this->sessionKey)->orderBy('sort_order')->get();
|
2014-05-14 23:24:20 +10:00
|
|
|
|
2014-08-01 18:14:39 +10:00
|
|
|
/*
|
|
|
|
* Set the thumb for each file
|
|
|
|
*/
|
2014-05-14 23:24:20 +10:00
|
|
|
foreach ($list as $file) {
|
|
|
|
$file->thumb = $file->getThumb($this->imageWidth, $this->imageHeight, ['mode' => 'crop']);
|
|
|
|
}
|
2014-08-01 18:14:39 +10:00
|
|
|
|
2014-05-14 23:24:20 +10:00
|
|
|
return $list;
|
|
|
|
}
|
|
|
|
|
2014-09-17 19:46:49 +10:00
|
|
|
/**
|
|
|
|
* Returns the display mode for the file upload. Eg: file-multi, image-single, etc.
|
|
|
|
* @return string
|
|
|
|
*/
|
2014-05-14 23:24:20 +10:00
|
|
|
protected function getDisplayMode()
|
|
|
|
{
|
|
|
|
$mode = $this->getConfig('mode', 'image');
|
|
|
|
|
2014-10-10 23:50:05 +02:00
|
|
|
if (str_contains($mode, '-')) {
|
2014-05-14 23:24:20 +10:00
|
|
|
return $mode;
|
2014-10-10 23:50:05 +02:00
|
|
|
}
|
2014-05-14 23:24:20 +10:00
|
|
|
|
2014-09-17 19:46:49 +10:00
|
|
|
$relationType = $this->getRelationType();
|
2014-05-14 23:24:20 +10:00
|
|
|
$mode .= ($relationType == 'attachMany' || $relationType == 'morphMany') ? '-multi' : '-single';
|
|
|
|
|
|
|
|
return $mode;
|
|
|
|
}
|
|
|
|
|
2015-01-31 15:31:46 +11:00
|
|
|
/**
|
|
|
|
* Returns the specified accepted file types, or the default
|
|
|
|
* based on the mode. Image mode will return:
|
|
|
|
* - jpg,jpeg,bmp,png,gif,svg
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getAcceptedFileTypes($includeDot = false)
|
|
|
|
{
|
|
|
|
if (!$types = $this->acceptedFileTypes) {
|
|
|
|
$types = starts_with($this->getDisplayMode(), 'image')
|
|
|
|
? 'jpg,jpeg,bmp,png,gif,svg'
|
|
|
|
: null;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!is_array($types)) {
|
|
|
|
$types = explode(',', $types);
|
|
|
|
}
|
|
|
|
|
|
|
|
$types = array_map(function($value) use ($includeDot) {
|
|
|
|
$value = trim($value);
|
|
|
|
|
|
|
|
if (substr($value, 0, 1) == '.') {
|
|
|
|
$value = substr($value, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($includeDot) {
|
|
|
|
$value = '.'.$value;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $value;
|
|
|
|
}, $types);
|
|
|
|
|
|
|
|
return implode(',', $types);
|
|
|
|
}
|
|
|
|
|
2014-09-17 19:46:49 +10:00
|
|
|
/**
|
|
|
|
* Returns the value as a relation object from the model,
|
|
|
|
* supports nesting via HTML array.
|
|
|
|
* @return Relation
|
|
|
|
*/
|
|
|
|
protected function getRelationObject()
|
|
|
|
{
|
2015-01-05 11:18:43 +11:00
|
|
|
list($model, $attribute) = $this->resolveModelAttribute($this->valueFrom);
|
2014-09-17 19:46:49 +10:00
|
|
|
return $model->{$attribute}();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the value as a relation type from the model,
|
|
|
|
* supports nesting via HTML array.
|
|
|
|
* @return Relation
|
|
|
|
*/
|
|
|
|
protected function getRelationType()
|
|
|
|
{
|
2015-01-05 11:18:43 +11:00
|
|
|
list($model, $attribute) = $this->resolveModelAttribute($this->valueFrom);
|
2014-09-17 19:46:49 +10:00
|
|
|
return $model->getRelationType($attribute);
|
|
|
|
}
|
|
|
|
|
2014-05-14 23:24:20 +10:00
|
|
|
/**
|
|
|
|
* Removes a file attachment.
|
|
|
|
*/
|
|
|
|
public function onRemoveAttachment()
|
|
|
|
{
|
|
|
|
if (($file_id = post('file_id')) && ($file = File::find($file_id))) {
|
2014-09-06 21:46:19 +10:00
|
|
|
$this->getRelationObject()->remove($file, $this->sessionKey);
|
2014-05-14 23:24:20 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sorts file attachments.
|
|
|
|
*/
|
|
|
|
public function onSortAttachments()
|
|
|
|
{
|
|
|
|
if ($sortData = post('sortOrder')) {
|
|
|
|
$ids = array_keys($sortData);
|
|
|
|
$orders = array_values($sortData);
|
|
|
|
|
|
|
|
$file = new File;
|
|
|
|
$file->setSortableOrder($ids, $orders);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Loads the configuration form for an attachment, allowing title and description to be set.
|
|
|
|
*/
|
|
|
|
public function onLoadAttachmentConfig()
|
|
|
|
{
|
|
|
|
if (($file_id = post('file_id')) && ($file = File::find($file_id))) {
|
|
|
|
$this->vars['file'] = $file;
|
|
|
|
return $this->makePartial('config_form');
|
|
|
|
}
|
|
|
|
|
|
|
|
throw new SystemException('Unable to find file, it may no longer exist');
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Commit the changes of the attachment configuration form.
|
|
|
|
*/
|
|
|
|
public function onSaveAttachmentConfig()
|
|
|
|
{
|
|
|
|
try {
|
|
|
|
if (($file_id = post('file_id')) && ($file = File::find($file_id))) {
|
|
|
|
$file->title = post('title');
|
|
|
|
$file->description = post('description');
|
|
|
|
$file->save();
|
|
|
|
|
|
|
|
$file->thumb = $file->getThumb($this->imageWidth, $this->imageHeight, ['mode' => 'crop']);
|
|
|
|
return ['item' => $file->toArray()];
|
|
|
|
}
|
|
|
|
|
|
|
|
throw new SystemException('Unable to find file, it may no longer exist');
|
2014-11-01 12:00:45 +11:00
|
|
|
}
|
|
|
|
catch (Exception $ex) {
|
2014-05-14 23:24:20 +10:00
|
|
|
return json_encode(['error' => $ex->getMessage()]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* {@inheritDoc}
|
|
|
|
*/
|
|
|
|
public function loadAssets()
|
|
|
|
{
|
2014-05-24 16:57:38 +10:00
|
|
|
$this->addCss('css/fileupload.css', 'core');
|
|
|
|
$this->addJs('js/fileupload.js', 'core');
|
2014-05-14 23:24:20 +10:00
|
|
|
}
|
|
|
|
|
2014-09-06 22:22:59 +10:00
|
|
|
/**
|
|
|
|
* {@inheritDoc}
|
|
|
|
*/
|
2015-01-05 09:43:39 +11:00
|
|
|
public function getSaveValue($value)
|
2014-09-06 22:22:59 +10:00
|
|
|
{
|
2014-12-05 18:35:42 +11:00
|
|
|
return FormField::NO_SAVE_DATA;
|
2014-09-06 22:22:59 +10:00
|
|
|
}
|
|
|
|
|
2014-05-14 23:24:20 +10:00
|
|
|
/**
|
|
|
|
* Checks the current request to see if it is a postback containing a file upload
|
|
|
|
* for this particular widget.
|
|
|
|
*/
|
|
|
|
protected function checkUploadPostback()
|
|
|
|
{
|
2014-10-10 23:50:05 +02:00
|
|
|
if (!($uniqueId = post('X_OCTOBER_FILEUPLOAD')) || $uniqueId != $this->getId()) {
|
2014-05-14 23:24:20 +10:00
|
|
|
return;
|
2014-10-10 23:50:05 +02:00
|
|
|
}
|
2014-05-14 23:24:20 +10:00
|
|
|
|
|
|
|
try {
|
|
|
|
$uploadedFile = Input::file('file_data');
|
|
|
|
|
|
|
|
$validationRules = ['max:'.File::getMaxFilesize()];
|
2015-01-31 15:31:46 +11:00
|
|
|
if ($fileTypes = $this->getAcceptedFileTypes()) {
|
|
|
|
$validationRules[] = 'mimes:'.$fileTypes;
|
2014-10-10 23:50:05 +02:00
|
|
|
}
|
2014-05-14 23:24:20 +10:00
|
|
|
|
|
|
|
$validation = Validator::make(
|
|
|
|
['file_data' => $uploadedFile],
|
|
|
|
['file_data' => $validationRules]
|
|
|
|
);
|
|
|
|
|
2014-10-10 23:50:05 +02:00
|
|
|
if ($validation->fails()) {
|
2014-05-14 23:24:20 +10:00
|
|
|
throw new ValidationException($validation);
|
2014-10-10 23:50:05 +02:00
|
|
|
}
|
2014-05-14 23:24:20 +10:00
|
|
|
|
2014-10-10 23:50:05 +02:00
|
|
|
if (!$uploadedFile->isValid()) {
|
2014-05-14 23:24:20 +10:00
|
|
|
throw new SystemException('File is not valid');
|
2014-10-10 23:50:05 +02:00
|
|
|
}
|
2014-05-14 23:24:20 +10:00
|
|
|
|
2014-09-06 21:46:19 +10:00
|
|
|
$fileRelation = $this->getRelationObject();
|
2014-05-14 23:24:20 +10:00
|
|
|
|
|
|
|
$file = new File();
|
|
|
|
$file->data = $uploadedFile;
|
2014-06-06 21:38:34 +10:00
|
|
|
$file->is_public = $fileRelation->isPublic();
|
2014-05-14 23:24:20 +10:00
|
|
|
$file->save();
|
|
|
|
|
|
|
|
$fileRelation->add($file, $this->sessionKey);
|
|
|
|
|
|
|
|
$file->thumb = $file->getThumb($this->imageWidth, $this->imageHeight, ['mode' => 'crop']);
|
|
|
|
$result = $file;
|
|
|
|
|
2014-11-01 12:00:45 +11:00
|
|
|
}
|
|
|
|
catch (Exception $ex) {
|
2014-05-14 23:24:20 +10:00
|
|
|
$result = json_encode(['error' => $ex->getMessage()]);
|
|
|
|
}
|
|
|
|
|
2014-10-20 18:55:31 +11:00
|
|
|
header('Content-Type: application/json');
|
2014-05-14 23:24:20 +10:00
|
|
|
die($result);
|
|
|
|
}
|
2014-10-10 23:50:05 +02:00
|
|
|
}
|