diff --git a/modules/backend/behaviors/ImportExportController.php b/modules/backend/behaviors/ImportExportController.php index dffa2ead5..1f32a06e3 100644 --- a/modules/backend/behaviors/ImportExportController.php +++ b/modules/backend/behaviors/ImportExportController.php @@ -7,7 +7,7 @@ use Response; use Backend; use BackendAuth; use Backend\Classes\ControllerBehavior; -use Backend\Classes\StreamFilterTranscode; +use Backend\Behaviors\ImportExportController\TranscodeFilter; use League\Csv\Reader as CsvReader; use League\Csv\Writer as CsvWriter; use ApplicationException; @@ -175,20 +175,14 @@ class ImportExportController extends ControllerBehavior try { $model = $this->importGetModel(); $matches = post('column_match', []); - $importOptions = [ - 'sessionKey' => $this->importUploadFormWidget->getSessionKey() - ]; if ($optionData = post('ImportOptions')) { $model->fill($optionData); } - if (post('format_preset') == 'custom') { - $importOptions['delimiter'] = post('format_delimiter'); - $importOptions['enclosure'] = post('format_enclosure'); - $importOptions['escape'] = post('format_escape'); - $importOptions['encoding'] = post('format_encoding'); - } + $importOptions = $this->getFormatOptionsFromPost(); + $importOptions['sessionKey'] = $this->importUploadFormWidget->getSessionKey(); + $importOptions['firstRowTitles'] = post('first_row_titles', false); $model->import($matches, $importOptions); @@ -226,7 +220,7 @@ class ImportExportController extends ControllerBehavior } $path = $this->getImportFilePath(); - $reader = $this->createCsvReader($path); + $reader = $this->createCsvReader($path); if (post('first_row_titles')) { $reader->setOffset(1); @@ -301,7 +295,7 @@ class ImportExportController extends ControllerBehavior return null; } - $reader = $this->createCsvReader($path); + $reader = $this->createCsvReader($path); $firstRow = $reader->fetchOne(0); if (!post('first_row_titles')) { @@ -310,8 +304,10 @@ class ImportExportController extends ControllerBehavior }); } - // Prevents unfriendly error to be thrown due to bad encoding at response time - if (false === json_encode($firstRow)) { + /* + * Prevents unfriendly error to be thrown due to bad encoding at response time. + */ + if (json_encode($firstRow) === false) { throw new ApplicationException(Lang::get('backend::lang.import_export.encoding_not_supported_error')); } @@ -395,19 +391,13 @@ class ImportExportController extends ControllerBehavior try { $model = $this->exportGetModel(); $columns = $this->processExportColumnsFromPost(); - $exportOptions = [ - 'sessionKey' => $this->exportFormatFormWidget->getSessionKey() - ]; if ($optionData = post('ExportOptions')) { $model->fill($optionData); } - if (post('format_preset') == 'custom') { - $exportOptions['delimiter'] = post('format_delimiter'); - $exportOptions['enclosure'] = post('format_enclosure'); - $exportOptions['escape'] = post('format_escape'); - } + $exportOptions = $this->getFormatOptionsFromPost(); + $exportOptions['sessionKey'] = $this->exportFormatFormWidget->getSessionKey(); $reference = $model->export($columns, $exportOptions); $fileUrl = $this->controller->actionUrl( @@ -705,7 +695,6 @@ class ImportExportController extends ControllerBehavior return $this->controller->actionUrl($type); } - /** * Create a new CSV reader with options selected by the user * @param string $path @@ -715,39 +704,59 @@ class ImportExportController extends ControllerBehavior protected function createCsvReader($path) { $reader = CsvReader::createFromPath($path); + $options = $this->getFormatOptionsFromPost(); - if (post('format_preset') == 'custom') { - $options = [ - 'delimiter' => post('format_delimiter'), - 'enclosure' => post('format_enclosure'), - 'escape' => post('format_escape'), - 'encoding' => post('format_encoding') - ]; + if ($options['delimiter'] !== null) { + $reader->setDelimiter($options['delimiter']); + } - if ($options['delimiter'] !== null) { - $reader->setDelimiter($options['delimiter']); - } + if ($options['enclosure'] !== null) { + $reader->setEnclosure($options['enclosure']); + } - if ($options['enclosure'] !== null) { - $reader->setEnclosure($options['enclosure']); - } + if ($options['escape'] !== null) { + $reader->setEscape($options['escape']); + } - if ($options['escape'] !== null) { - $reader->setEscape($options['escape']); - } - - if ($options['encoding'] !== null) { - if ($reader->isActiveStreamFilter()) { - $reader->appendStreamFilter(sprintf( - '%s%s:%s', - StreamFilterTranscode::FILTER_NAME, - strtolower($options['encoding']), - 'utf-8' - )); - } - } + if ( + $options['encoding'] !== null && + $reader->isActiveStreamFilter() + ) { + $reader->appendStreamFilter(sprintf( + '%s%s:%s', + TranscodeFilter::FILTER_NAME, + strtolower($options['encoding']), + 'utf-8' + )); } return $reader; } -} \ No newline at end of file + + /** + * Returns the file format options from postback. This method + * can be used to define presets. + * @return array + */ + protected function getFormatOptionsFromPost() + { + $presetMode = post('format_preset'); + + $options = [ + 'delimiter' => null, + 'enclosure' => null, + 'escape' => null, + 'encoding' => null + ]; + + if ($presetMode == 'custom') { + $options['delimiter'] = post('format_delimiter'); + $options['enclosure'] = post('format_enclosure'); + $options['escape'] = post('format_escape'); + $options['encoding'] = post('format_encoding'); + } + + return $options; + } + +} diff --git a/modules/backend/behaviors/importexportcontroller/TranscodeFilter.php b/modules/backend/behaviors/importexportcontroller/TranscodeFilter.php new file mode 100644 index 000000000..146eaeeb3 --- /dev/null +++ b/modules/backend/behaviors/importexportcontroller/TranscodeFilter.php @@ -0,0 +1,69 @@ +data = @mb_convert_encoding( + $resource->data, + $this->encodingTo, + $this->encodingFrom + ); + + $consumed += $resource->datalen; + + stream_bucket_append($out, $resource); + } + + return PSFS_PASS_ON; + } + + public function onCreate() + { + if (strpos($this->filtername, self::FILTER_NAME) !== 0) { + return false; + } + + $params = substr($this->filtername, strlen(self::FILTER_NAME)); + if (!preg_match('/^([-\w]+)(:([-\w]+))?$/', $params, $matches)) { + return false; + } + + if (isset($matches[1])) { + $this->encodingFrom = $matches[1]; + } + + $this->encodingTo = mb_internal_encoding(); + if (isset( $matches[3] )) { + $this->encodingTo = $matches[3]; + } + + $this->params['locale'] = setlocale(LC_CTYPE, '0'); + if (stripos($this->params['locale'], 'UTF-8') === false) { + setlocale(LC_CTYPE, 'en_US.UTF-8'); + } + + return true; + } + + public function onClose() + { + setlocale(LC_CTYPE, $this->params['locale']); + } +} diff --git a/modules/backend/classes/StreamFilterTranscode.php b/modules/backend/classes/StreamFilterTranscode.php deleted file mode 100644 index 14b852b51..000000000 --- a/modules/backend/classes/StreamFilterTranscode.php +++ /dev/null @@ -1,71 +0,0 @@ -filtername, self::FILTER_NAME) !== 0) { - return false; - } - - $params = substr($this->filtername, strlen(self::FILTER_NAME)); - if ( ! preg_match('/^([-\w]+)(:([-\w]+))?$/', $params, $matches)) { - return false; - } - - if (isset( $matches[1] )) { - $this->encoding_from = $matches[1]; - } - - $this->encoding_to = mb_internal_encoding(); - if (isset( $matches[3] )) { - $this->encoding_to = $matches[3]; - } - - $this->params['locale'] = setlocale(LC_CTYPE, '0'); - if (stripos($this->params['locale'], 'UTF-8') === false) { - setlocale(LC_CTYPE, 'en_US.UTF-8'); - } - - return true; - } - - - public function onClose() - { - setlocale(LC_CTYPE, $this->params['locale']); - } - - - public function filter($in, $out, &$consumed, $closing) - { - while ($res = stream_bucket_make_writeable($in)) { - $res->data = @mb_convert_encoding($res->data, $this->encoding_to, $this->encoding_from); - $consumed += $res->datalen; - stream_bucket_append($out, $res); - } - - return PSFS_PASS_ON; - } -} \ No newline at end of file diff --git a/modules/backend/models/ExportModel.php b/modules/backend/models/ExportModel.php index f10b6829d..d0c9c3537 100644 --- a/modules/backend/models/ExportModel.php +++ b/modules/backend/models/ExportModel.php @@ -16,7 +16,6 @@ use SplTempFileObject; */ abstract class ExportModel extends Model { - /** * Called when data is being exported. * The return value should be an array in the format of: @@ -202,5 +201,4 @@ abstract class ExportModel extends Model return implode($delimeter, $newData); } - -} \ No newline at end of file +} diff --git a/modules/backend/models/ImportModel.php b/modules/backend/models/ImportModel.php index c8668013e..870a4146d 100644 --- a/modules/backend/models/ImportModel.php +++ b/modules/backend/models/ImportModel.php @@ -1,5 +1,6 @@ import_file() ->withDeferred($sessionKey) - ->first(); + ->first() + ; if (!$file) { return null; @@ -195,7 +197,7 @@ abstract class ImportModel extends Model */ public function getFormatEncodingOptions() { - return \Lang::get('backend::lang.import_export.encodings'); + return Lang::get('backend::lang.import_export.encodings'); } // @@ -241,4 +243,4 @@ abstract class ImportModel extends Model { $this->resultStats['skipped'][$rowIndex] = $message; } -} \ No newline at end of file +}