diff --git a/.env.dist b/.env.dist index 42b9988580d..d532aca9562 100644 --- a/.env.dist +++ b/.env.dist @@ -21,6 +21,9 @@ DATABASE_URL=sqlite:///var/eccube.db # The version of your database engine DATABASE_SERVER_VERSION=3 + +# The charset of your database engine +DATABASE_CHARSET=utf8 ###< doctrine/doctrine-bundle ### ###> symfony/mailer ### @@ -51,4 +54,4 @@ MAILER_DSN=null://null #ECCUBE_2FA_COOKIE_NAME=eccube_2fa #ECCUBE_2FA_EXPIRE=14 -###< APPLICATION CONFIG ### \ No newline at end of file +###< APPLICATION CONFIG ### diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 7c7d367c9c3..95f6e106280 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -26,12 +26,15 @@ jobs: - db: mysql database_url: mysql://root:password@127.0.0.1:3306/eccube_db database_server_version: 5 + database_charset: utf8mb4 - db: pgsql database_url: postgres://postgres:password@127.0.0.1:5432/eccube_db database_server_version: 14 + database_charset: utf8 - db: sqlite3 database_url: sqlite:///var/eccube.db database_server_version: 3 + database_charset: utf8 services: mysql: @@ -79,6 +82,7 @@ jobs: APP_ENV: 'test' DATABASE_URL: ${{ matrix.database_url }} DATABASE_SERVER_VERSION: ${{ matrix.database_server_version }} + DATABASE_CHARSET: ${{ matrix.database_charset }} run: | bin/console doctrine:database:create bin/console doctrine:schema:create @@ -89,6 +93,7 @@ jobs: APP_ENV: 'test' DATABASE_URL: ${{ matrix.database_url }} DATABASE_SERVER_VERSION: ${{ matrix.database_server_version }} + DATABASE_CHARSET: ${{ matrix.database_charset }} MAILER_URL: 'smtp://127.0.0.11025' run: bin/phpunit --exclude-group cache-clear,cache-clear-install,update-schema-doctrine,plugin-service - name: PHPUnit @@ -96,6 +101,7 @@ jobs: APP_ENV: 'test' DATABASE_URL: ${{ matrix.database_url }} DATABASE_SERVER_VERSION: ${{ matrix.database_server_version }} + DATABASE_CHARSET: ${{ matrix.database_charset }} MAILER_URL: 'smtp://127.0.0.11025' run: | bin/phpunit --group cache-clear @@ -118,6 +124,7 @@ jobs: APP_ENV: 'test' DATABASE_URL: ${{ matrix.database_url }} DATABASE_SERVER_VERSION: ${{ matrix.database_server_version }} + DATABASE_CHARSET: ${{ matrix.database_charset }} MAILER_URL: 'smtp://127.0.0.11025' run: | rm -r app/Plugin/* diff --git a/app/config/eccube/packages/doctrine.yaml b/app/config/eccube/packages/doctrine.yaml index ae37ba2fa94..fd2e627acac 100644 --- a/app/config/eccube/packages/doctrine.yaml +++ b/app/config/eccube/packages/doctrine.yaml @@ -5,15 +5,18 @@ parameters: # You should not need to change this value. env(DATABASE_URL): '' env(DATABASE_SERVER_VERSION): ~ + env(DATABASE_CHARSET): 'utf8' + doctrine: dbal: driver: 'pdo_sqlite' server_version: "%env(DATABASE_SERVER_VERSION)%" - charset: utf8 + charset: '%env(DATABASE_CHARSET)%' # for mysql only default_table_options: - collate: 'utf8_general_ci' + charset: 'utf8mb4' + collation: 'utf8mb4_bin' # With Symfony 3.3, remove the `resolve:` prefix url: '%env(DATABASE_URL)%' diff --git a/docker-compose.mysql.yml b/docker-compose.mysql.yml index dbdff19f635..506b23ff447 100644 --- a/docker-compose.mysql.yml +++ b/docker-compose.mysql.yml @@ -11,6 +11,7 @@ services: environment: DATABASE_URL: "mysql://dbuser:secret@mysql/eccubedb" DATABASE_SERVER_VERSION: 5.7 + DATABASE_CHARSET: 'utf8mb4' mysql: image: mysql:5.7 diff --git a/docker-compose.pgsql.yml b/docker-compose.pgsql.yml index 38ddbb798df..c7c9e89f1d1 100644 --- a/docker-compose.pgsql.yml +++ b/docker-compose.pgsql.yml @@ -11,6 +11,7 @@ services: environment: DATABASE_URL: "postgres://dbuser:secret@postgres/eccubedb" DATABASE_SERVER_VERSION: 14 + DATABASE_CHARSET: 'utf8' postgres: image: postgres:14 diff --git a/docker-compose.yml b/docker-compose.yml index 5dbb574741c..27db2dedc24 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -39,6 +39,7 @@ services: APP_DEBUG: 1 DATABASE_URL: "sqlite:///var/eccube.db" DATABASE_SERVER_VERSION: 3 + DATABASE_CHARSET: 'utf8' MAILER_DSN: "smtp://mailcatcher:1025" ECCUBE_AUTH_MAGIC: "" # TRUSTED_HOSTS: '^127.0.0.1$$,^localhost$$' diff --git a/src/Eccube/Command/InstallerCommand.php b/src/Eccube/Command/InstallerCommand.php index 213c0f33fd1..3a4d921eebf 100644 --- a/src/Eccube/Command/InstallerCommand.php +++ b/src/Eccube/Command/InstallerCommand.php @@ -58,6 +58,7 @@ public function __construct(ContainerInterface $container) public $appDebug; public $databaseUrl; public $serverVersion; + public $databaseCharset; public $mailerDsn; public $authMagic; public $adminRoute; @@ -74,6 +75,7 @@ private function getEnvParameters() 'APP_DEBUG' => $this->appDebug, 'DATABASE_URL' => $this->databaseUrl, 'DATABASE_SERVER_VERSION' => $this->serverVersion, + 'DATABASE_CHARSET' => $this->databaseCharset, 'MAILER_DSN' => $this->mailerDsn, 'ECCUBE_AUTH_MAGIC' => $this->authMagic, 'ECCUBE_ADMIN_ROUTE' => $this->adminRoute, @@ -141,6 +143,9 @@ protected function interact(InputInterface $input, OutputInterface $output) // DATABASE_SERVER_VERSION $this->envFileUpdater->serverVersion = $this->getDatabaseServerVersion($databaseUrl); + // DATABASE_CHARSET + $this->envFileUpdater->databaseCharset = \str_starts_with($databaseUrl, 'mysql') ? 'utf8mb4' : 'utf8'; + // MAILER_DSN $mailerDsn = $this->container->getParameter('eccube_mailer_dsn'); if (empty($mailerDsn)) { diff --git a/src/Eccube/Controller/Install/InstallController.php b/src/Eccube/Controller/Install/InstallController.php index 70bc90d5c90..843f2689e5b 100644 --- a/src/Eccube/Controller/Install/InstallController.php +++ b/src/Eccube/Controller/Install/InstallController.php @@ -481,6 +481,7 @@ public function complete(Request $request) 'ECCUBE_TEMPLATE_CODE' => 'default', 'ECCUBE_LOCALE' => 'ja', 'TRUSTED_HOSTS' => '^'.str_replace('.', '\\.', $request->getHost()).'$', + 'DATABASE_CHARSET' => \str_starts_with($databaseUrl, 'mysql') ? 'utf8mb4' : 'utf8', ]; $env = StringUtil::replaceOrAddEnv($env, $replacement); @@ -563,9 +564,10 @@ protected function checkModules() protected function createConnection(array $params) { if (strpos($params['url'], 'mysql') !== false) { - $params['charset'] = 'utf8'; + $params['charset'] = 'utf8mb4'; $params['defaultTableOptions'] = [ - 'collate' => 'utf8_general_ci', + 'charset' => 'utf8mb4', + 'collation' => 'utf8mb4_bin', ]; } diff --git a/src/Eccube/Entity/Product.php b/src/Eccube/Entity/Product.php index 8321d776600..9c934e63372 100644 --- a/src/Eccube/Entity/Product.php +++ b/src/Eccube/Entity/Product.php @@ -462,28 +462,28 @@ public function hasProductClass() /** * @var string|null * - * @ORM\Column(name="note", type="string", length=4000, nullable=true) + * @ORM\Column(name="note", type="text", nullable=true) */ private $note; /** * @var string|null * - * @ORM\Column(name="description_list", type="string", length=4000, nullable=true) + * @ORM\Column(name="description_list", type="text", nullable=true) */ private $description_list; /** * @var string|null * - * @ORM\Column(name="description_detail", type="string", length=4000, nullable=true) + * @ORM\Column(name="description_detail", type="text", nullable=true) */ private $description_detail; /** * @var string|null * - * @ORM\Column(name="search_word", type="string", length=4000, nullable=true) + * @ORM\Column(name="search_word", type="text", nullable=true) */ private $search_word; diff --git a/tests/Eccube/Tests/Web/Admin/Product/ProductControllerTest.php b/tests/Eccube/Tests/Web/Admin/Product/ProductControllerTest.php index 40aa73e0a23..f096494ac95 100644 --- a/tests/Eccube/Tests/Web/Admin/Product/ProductControllerTest.php +++ b/tests/Eccube/Tests/Web/Admin/Product/ProductControllerTest.php @@ -1133,4 +1133,23 @@ public function testDeleteAndDeleteProductImage() $this->assertTrue(file_exists($dir.$DuplicatedImage->getFileName())); $this->assertFalse(file_exists($dir.$NotDuplicatedImage->getFileName())); } + + public function test絵文字() + { + $name = '🍣🍺'; + $crawler = $this->client->request('GET', $this->generateUrl('product_list', ['name' => $name])); + $this->assertTrue($this->client->getResponse()->isSuccessful()); + + $message = $crawler->filter('.ec-searchnavRole__counter > span')->text(); + $this->assertSame('お探しの商品は見つかりませんでした', $message); + + // 絵文字の商品を登録 + $this->createProduct($name); + + $crawler = $this->client->request('GET', $this->generateUrl('product_list', ['name' => $name])); + $this->assertTrue($this->client->getResponse()->isSuccessful()); + + $message = $crawler->filter('.ec-searchnavRole__counter > span')->text(); + $this->assertSame('1件', $message); + } }