From c087008ffc4ea768f2e9147a86549fcbe1b760ff Mon Sep 17 00:00:00 2001 From: Kentaro Ohkouchi Date: Tue, 20 Sep 2016 18:37:53 +0900 Subject: [PATCH 1/2] =?UTF-8?q?Windows=20=E7=89=88=20PHP7=20=E3=81=AE?= =?UTF-8?q?=E7=92=B0=E5=A2=83=E3=81=A7=20CSV=20=E3=82=A2=E3=83=83=E3=83=97?= =?UTF-8?q?=E3=83=AD=E3=83=BC=E3=83=89=E3=81=AB=E5=A4=B1=E6=95=97=E3=81=99?= =?UTF-8?q?=E3=82=8B=E3=81=AE=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - #1780 - Windows 版 PHP7 の環境で CSV 形式のファイルを SplFileObject クラスを使用してパースする場合, ファイルフォーマットを既定のロケールと一致させる必要がある --- .../Admin/Product/CsvImportController.php | 18 +++++++++++---- src/Eccube/Service/CsvImportService.php | 22 +++++++++++++++++-- .../Admin/Product/CsvImportControllerTest.php | 12 +++++----- 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/Eccube/Controller/Admin/Product/CsvImportController.php b/src/Eccube/Controller/Admin/Product/CsvImportController.php index cb336ed19a0..90788940f87 100644 --- a/src/Eccube/Controller/Admin/Product/CsvImportController.php +++ b/src/Eccube/Controller/Admin/Product/CsvImportController.php @@ -622,10 +622,20 @@ protected function getImportData($app, $formFile) $formFile->move($app['config']['csv_temp_realdir'], $this->fileName); $file = file_get_contents($app['config']['csv_temp_realdir'] . '/' . $this->fileName); - // アップロードされたファイルがUTF-8以外は文字コード変換を行う - $encode = Str::characterEncoding(substr($file, 0, 6)); - if ($encode != 'UTF-8') { - $file = mb_convert_encoding($file, 'UTF-8', $encode); + + if ('\\' === DIRECTORY_SEPARATOR && PHP_VERSION_ID >= 70000) { + // Windows 環境の PHP7 の場合はファイルエンコーディングを CP932 に合わせる + // see https://github.com/EC-CUBE/ec-cube/issues/1780 + setlocale(LC_ALL, ''); // 既定のロケールに設定 + if (mb_detect_encoding($file) === 'UTF-8') { // UTF-8 を検出したら SJIS-win に変換 + $file = mb_convert_encoding($file, 'SJIS-win', 'UTF-8'); + } + } else { + // アップロードされたファイルがUTF-8以外は文字コード変換を行う + $encode = Str::characterEncoding(substr($file, 0, 6)); + if ($encode != 'UTF-8') { + $file = mb_convert_encoding($file, 'UTF-8', $encode); + } } $file = Str::convertLineFeed($file); diff --git a/src/Eccube/Service/CsvImportService.php b/src/Eccube/Service/CsvImportService.php index 27bedd6dc84..741ff222773 100644 --- a/src/Eccube/Service/CsvImportService.php +++ b/src/Eccube/Service/CsvImportService.php @@ -145,7 +145,10 @@ public function current() // Since the CSV has column headers use them to construct an associative array for the columns in this line if ($this->valid()) { - $line = $this->file->current(); + $current = $this->file->current(); + $current = $this->convertEncodingRows($current); + + $line = $current; // See if values for duplicate headers should be merged if (self::DUPLICATE_HEADERS_MERGE === $this->duplicateHeadersFlag) { @@ -181,6 +184,7 @@ public function getColumnHeaders() */ public function setColumnHeaders(array $columnHeaders) { + $columnHeaders = $this->convertEncodingRows($columnHeaders); $this->columnHeaders = array_count_values($columnHeaders); $this->headersCount = count($columnHeaders); } @@ -204,7 +208,7 @@ public function setHeaderRowNumber($rowNumber, $duplicates = null) $headers = $this->readHeaderRow($rowNumber); if ($headers === false) { - return false; + return false; } $this->setColumnHeaders($headers); return true; @@ -400,4 +404,18 @@ protected function mergeDuplicates(array $line) return $values; } + /** + * 行の文字エンコーディングを変換する. + * + * Windows 版 PHP7 環境では、ファイルエンコーディングが CP932 になるため UTF-8 に変換する. + * それ以外の環境では何もしない。 + */ + protected function convertEncodingRows($row) { + if ('\\' === DIRECTORY_SEPARATOR && PHP_VERSION_ID >= 70000) { + foreach ($row as &$col) { + $col = mb_convert_encoding($col , 'UTF-8', 'SJIS-win'); + } + } + return $row; + } } diff --git a/tests/Eccube/Tests/Web/Admin/Product/CsvImportControllerTest.php b/tests/Eccube/Tests/Web/Admin/Product/CsvImportControllerTest.php index 65d6b622cc2..60edc50b786 100644 --- a/tests/Eccube/Tests/Web/Admin/Product/CsvImportControllerTest.php +++ b/tests/Eccube/Tests/Web/Admin/Product/CsvImportControllerTest.php @@ -38,12 +38,12 @@ public function createCsvAsArray($has_header = true) $csv = array( '商品ID' => null, '公開ステータス(ID)' => 1, - '商品名' => $faker->word, - 'ショップ用メモ欄' => $faker->paragraph, - '商品説明(一覧)' => $faker->paragraph, - '商品説明(詳細)' => $faker->text, - '検索ワード' => $faker->word, - 'フリーエリア' => $faker->paragraph, + '商品名' => "商品名".$faker->word."商品名", + 'ショップ用メモ欄' => "ショップ用メモ欄".$faker->paragraph."ショップ用メモ欄", + '商品説明(一覧)' => "商品説明(一覧)".$faker->paragraph."商品説明(一覧)", + '商品説明(詳細)' => "商品説明(詳細)".$faker->text."商品説明(詳細)", + '検索ワード' => "検索ワード".$faker->word."検索ワード", + 'フリーエリア' => "フリーエリア".$faker->paragraph."フリーエリア", '商品削除フラグ' => 0, '商品画像' => $faker->word.'.jpg,'.$faker->word.'.jpg', '商品カテゴリ(ID)' => '5,6', From 0aaf31b7ee915112b9195daf674a35ca4d324493 Mon Sep 17 00:00:00 2001 From: Kentaro Ohkouchi Date: Tue, 20 Sep 2016 18:42:47 +0900 Subject: [PATCH 2/2] =?UTF-8?q?AppVeyor=20=E3=82=92=20PHP7=20=E3=81=A7?= =?UTF-8?q?=E3=83=86=E3=82=B9=E3=83=88=E3=81=99=E3=82=8B=E3=82=88=E3=81=86?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- appveyor.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 564d72c4b39..84d9dd7f89a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -37,8 +37,7 @@ install: #- cinst mysql #- SET PATH=C:\tools\mysql\current\bin\;%PATH% # Set PHP. - #- cinst php php7になってしまうので - - cinst php -version 5.6.17 + - cinst php - SET PATH=C:\tools\php\;%PATH% - copy C:\tools\php\php.ini-production C:\tools\php\php.ini - echo date.timezone="Asia/Tokyo" >> C:\tools\php\php.ini