diff --git a/modules/backend/behaviors/ImportExportController.php b/modules/backend/behaviors/ImportExportController.php index e9a0cf3bb..2e1e38a7e 100644 --- a/modules/backend/behaviors/ImportExportController.php +++ b/modules/backend/behaviors/ImportExportController.php @@ -35,7 +35,6 @@ use Exception; */ class ImportExportController extends ControllerBehavior { - /** * @inheritDoc */ @@ -159,7 +158,9 @@ class ImportExportController extends ControllerBehavior return $response; } - $this->checkUseListExportMode(); + if ($response = $this->checkUseListExportMode()) { + return $response; + } $this->addJs('js/october.export.js', 'core'); $this->addCss('css/export.css', 'core'); @@ -387,6 +388,7 @@ class ImportExportController extends ControllerBehavior public function importIsColumnRequired($columnName) { $model = $this->importGetModel(); + return $model->isAttributeRequired($columnName); } @@ -398,7 +400,9 @@ class ImportExportController extends ControllerBehavior $dbColumns = $this->getImportDbColumns(); foreach ($dbColumns as $column => $label) { - if (!$this->importIsColumnRequired($column)) continue; + if (!$this->importIsColumnRequired($column)) { + continue; + } $found = false; foreach ($matches as $matchedColumns) { @@ -577,7 +581,7 @@ class ImportExportController extends ControllerBehavior $listDefinition = $useList; } - $this->exportFromList($listDefinition); + return $this->exportFromList($listDefinition); } /** @@ -603,6 +607,8 @@ class ImportExportController extends ControllerBehavior $options = array_merge($defaultOptions, $options); + $filename = filter_var($options['fileName'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW); + /* * Prepare CSV */ @@ -629,11 +635,11 @@ class ImportExportController extends ControllerBehavior $query = $widget->prepareQuery(); $results = $query->get(); - + if ($event = $widget->fireSystemEvent('backend.list.extendRecords', [&$results])) { $results = $event; } - + foreach ($results as $result) { $record = []; foreach ($columns as $column) { @@ -647,10 +653,14 @@ class ImportExportController extends ControllerBehavior } /* - * Output + * Response */ - $csv->output($options['fileName']); - exit; + $response = Response::make(); + $response->header('Content-Type', 'text/csv'); + $response->header('Content-Transfer-Encoding', 'binary'); + $response->header('Content-Disposition', sprintf('%s; filename="%s"', 'attachment', $filename)); + $response->setContent((string) $csv); + return $response; } // @@ -666,6 +676,7 @@ class ImportExportController extends ControllerBehavior public function importExportMakePartial($partial, $params = []) { $contents = $this->controller->makePartial('import_export_'.$partial, $params + $this->vars, false); + if (!$contents) { $contents = $this->makePartial($partial, $params); } @@ -819,5 +830,4 @@ class ImportExportController extends ControllerBehavior return $options; } - } diff --git a/modules/backend/classes/Controller.php b/modules/backend/classes/Controller.php index 31578fb81..f76eec54e 100644 --- a/modules/backend/classes/Controller.php +++ b/modules/backend/classes/Controller.php @@ -118,6 +118,11 @@ class Controller extends ControllerBase */ protected $statusCode = 200; + /** + * @var mixed Override the standard controller response. + */ + protected $responseOverride = null; + /** * Constructor. */ @@ -280,6 +285,10 @@ class Controller extends ControllerBase */ $result = $this->execPageAction($action, $params); + if ($this->responseOverride !== null) { + $result = $this->responseOverride; + } + if (!is_string($result)) { return $result; } @@ -684,6 +693,17 @@ class Controller extends ControllerBase return $this; } + /** + * Sets the response for the current page request cycle, this value takes priority + * over the standard response prepared by the controller. + * @param mixed $response Response object or string + */ + public function setResponse($response) + { + $this->responseOverride = $response; + return $this; + } + // // Hints // diff --git a/modules/backend/formwidgets/FileUpload.php b/modules/backend/formwidgets/FileUpload.php index 4ce1dd100..75998b838 100644 --- a/modules/backend/formwidgets/FileUpload.php +++ b/modules/backend/formwidgets/FileUpload.php @@ -410,7 +410,8 @@ class FileUpload extends FormWidgetBase $parent = $fileRelation->getParent(); if ($this->attachOnUpload && $parent && $parent->exists) { $fileRelation->add($file); - } else { + } + else { $fileRelation->add($file, $this->sessionKey); } @@ -422,14 +423,14 @@ class FileUpload extends FormWidgetBase 'path' => $file->pathUrl ]; - Response::json($result, 200)->send(); - + $response = Response::make($result, 200); } catch (Exception $ex) { - Response::json($ex->getMessage(), 400)->send(); + $response = Response::make($ex->getMessage(), 400); } - exit; + // Override the controller response + $this->controller->setResponse($response); } /** diff --git a/modules/backend/widgets/MediaManager.php b/modules/backend/widgets/MediaManager.php index 7d5d8e47e..17cce9df7 100644 --- a/modules/backend/widgets/MediaManager.php +++ b/modules/backend/widgets/MediaManager.php @@ -1563,16 +1563,17 @@ class MediaManager extends WidgetBase */ $this->fireSystemEvent('media.file.upload', [$filePath, $uploadedFile]); - Response::json([ + $response = Response::make([ 'link' => MediaLibrary::url($filePath), 'result' => 'success' - ])->send(); + ]); } catch (Exception $ex) { - Response::json($ex->getMessage(), 400)->send(); + $response = Response::make($ex->getMessage(), 400); } - exit; + // Override the controller response + $this->controller->setResponse($response); } /** diff --git a/modules/cms/widgets/AssetList.php b/modules/cms/widgets/AssetList.php index 667169cf3..21e8a48cd 100644 --- a/modules/cms/widgets/AssetList.php +++ b/modules/cms/widgets/AssetList.php @@ -6,6 +6,7 @@ use File; use Lang; use Input; use Request; +use Response; use Cms\Classes\Theme; use Cms\Classes\Asset; use Backend\Classes\WidgetBase; @@ -54,6 +55,7 @@ class AssetList extends WidgetBase $this->assetExtensions = FileDefinitions::get('assetExtensions'); parent::__construct($controller, []); + $this->bindToController(); $this->checkUploadPostback(); @@ -96,6 +98,7 @@ class AssetList extends WidgetBase } $this->putSession('currentPath', $path); + return [ '#'.$this->getId('asset-list') => $this->makePartial('items', ['items' => $this->getData()]) ]; @@ -661,15 +664,18 @@ class AssetList extends WidgetBase */ $uploadedFile->move($this->getCurrentPath(), $uploadedFile->getClientOriginalName()); - die('success'); + $response = Response::make('success'); } catch (Exception $ex) { $message = $fileName !== null ? Lang::get('cms::lang.asset.error_uploading_file', ['name' => $fileName, 'error' => $ex->getMessage()]) : $ex->getMessage(); - die($message); + $response = Response::make($message); } + + // Override the controller response + $this->controller->setResponse($response); } protected function setSearchTerm($term) diff --git a/modules/cms/widgets/assetlist/assets/js/assetlist.js b/modules/cms/widgets/assetlist/assets/js/assetlist.js index cbe03c3d8..cb070ca99 100644 --- a/modules/cms/widgets/assetlist/assets/js/assetlist.js +++ b/modules/cms/widgets/assetlist/assets/js/assetlist.js @@ -149,9 +149,18 @@ url: window.location, paramName: 'file_data', previewsContainer: $('
').get(0), - clickable: $link.get(0) + clickable: $link.get(0), + headers: {} } + /* + * Add CSRF token to headers + */ + var token = $('meta[name="csrf-token"]').attr('content') + if (token) { + uploaderOptions.headers['X-CSRF-TOKEN'] = token + } + var dropzone = new Dropzone($('').get(0), uploaderOptions) dropzone.on('error', $.proxy(self.onUploadFail, self)) dropzone.on('success', $.proxy(self.onUploadSuccess, self)) @@ -167,4 +176,4 @@ $(document).ready(function(){ new AssetList($('#asset-list-container').closest('form'), $('#asset-list-container').data('alias')) }) -}(window.jQuery); \ No newline at end of file +}(window.jQuery);