Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
16c4858
[Release] 4.1.9
dpfaffenbauer Jan 20, 2026
2b26129
Merge pull request #2947 from dpfaffenbauer/release/4.1.9
dpfaffenbauer Jan 20, 2026
0f1e896
Initial plan
Copilot Jan 29, 2026
ddc0b5a
Initial plan
Copilot Jan 29, 2026
ebc277a
Initial plan
Copilot Jan 29, 2026
c94df7f
Initial plan
Copilot Jan 29, 2026
dc266d5
Add coreshop:setup:states CLI command for creating states/regions
Copilot Jan 29, 2026
d665cad
Address code review feedback: improve exception handling and consistency
Copilot Jan 29, 2026
1527ac8
Initial plan
Copilot Jan 29, 2026
1f01b82
feat: Add multi-select drag & drop support for condition lists
Copilot Jan 29, 2026
8953519
Add auto-refresh feature and rotate queue names in MessengerBundle UI
Copilot Jan 29, 2026
fa143d9
Fix information exposure vulnerability in OrderInvoiceController and …
Copilot Jan 29, 2026
ac3b8a8
Return HTTP 500 status code on error in renderAction methods
Copilot Jan 29, 2026
24fb7c0
docs: update Menu Bundle JavaScript documentation to use modern event…
Copilot Jan 29, 2026
dbfac39
refactor: Use for-of loops instead of traditional for loops
Copilot Jan 29, 2026
4db8fcd
Add 'Copilot' to the allowlist in CLA check
dpfaffenbauer Jan 29, 2026
f58485a
Change chart labels to trim with ellipsis and show full name on bar h…
Copilot Jan 29, 2026
cf30fff
Merge pull request #2966 from coreshop/copilot/update-menu-bundle-docs
dpfaffenbauer Jan 29, 2026
1c7cd94
Merge pull request #2960 from coreshop/copilot/add-drag-and-drop-supp…
dpfaffenbauer Jan 29, 2026
de3345e
Remove logging and simplify error response in renderAction methods
Copilot Jan 29, 2026
a40e747
Show queue name in label for bars with 0 messages
Copilot Jan 29, 2026
0ba0672
Merge pull request #2959 from coreshop/copilot/add-cli-command-for-ma…
dpfaffenbauer Jan 29, 2026
1b15e2c
Revert chart to simple design with tooltip on bar hover
Copilot Jan 29, 2026
d7a1385
Merge pull request #2965 from coreshop/copilot/optimize-messenger-ui
dpfaffenbauer Jan 29, 2026
8af585b
Merge pull request #2962 from coreshop/copilot/fix-information-exposu…
dpfaffenbauer Jan 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/cla-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ jobs:
path-to-signatures: 'signatures/version1/cla.json'
path-to-document: 'https://github.com/coreshop/coreshop/blob/4.0/CLA.md'
branch: "main"
allowlist: user1,bot*
allowlist: user1,bot*,Copilot
remote-organization-name: "coreshop"
remote-repository-name: "cla"
3 changes: 3 additions & 0 deletions CHANGELOG-4.1.x.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## 4.1.9
* Fix Injection in CustomerTransformerController by @dpfaffenbauer in https://github.com/coreshop/CoreShop/pull/2945

## 4.1.8
* [Messenger] dispatch `FailedMessageDetailsEvent` to allow customization of failed message details generation by @jdreesen in https://github.com/coreshop/CoreShop/pull/2911
* [Messenger] wrap failed message details info modal data in `<pre>` tags by @jdreesen in https://github.com/coreshop/CoreShop/pull/2910
Expand Down
10 changes: 5 additions & 5 deletions docs/03_Bundles/Menu_Bundle.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,14 @@ public function registerBundlesToCollection(BundleCollection $collection)

```javascript
new coreshop.menu.coreshop.my_menu();

pimcore.eventDispatcher.registerTarget('coreshopMenuOpen', new (Class.create({
coreshopMenuOpen: function(type, item) {

document.addEventListener(coreshop.events.menu.open, (e) => {
var item = e.detail.item;

if (item.id === 'my-menu-item') {
alert('My Menu Item has been clicked');
}
}

});
```


Expand Down
66 changes: 66 additions & 0 deletions docs/03_Development/02_Localization/03_States/02_Setup_Command.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Setup States Command

CoreShop provides a CLI command to create states/regions for countries after the initial installation.

By default, CoreShop only creates states for Austria (AT) during installation. Use this command to add states for additional countries.

## Usage

```bash
# Setup states for a single country
php bin/console coreshop:setup:states DE

# Setup states for multiple countries
php bin/console coreshop:setup:states DE,US,FR

# Setup states and activate the country if not already active
php bin/console coreshop:setup:states DE --activate-country

# Verbose output to see individual states being created
php bin/console coreshop:setup:states DE -v
```

## Arguments

| Argument | Description |
|----------|-------------|
| countries | Comma-separated list of country ISO codes (e.g., DE,US,FR) |

## Options

| Option | Description |
|--------|-------------|
| --activate-country | Also activate the country if not already active |

## Prerequisites

Before running this command, ensure that:

1. CoreShop is installed (`coreshop:install` has been run)
2. The country fixtures have been loaded (countries exist in the database)

## How It Works

The command:

1. Looks up each specified country in the database by ISO code
2. Loads the country's divisions (states/regions) from the Rinvex country data library
3. Creates states for each division that doesn't already exist
4. Optionally activates the country if `--activate-country` is specified

## Example Output

```
CoreShop States Setup
=====================

Setting up states for countries: DE

Processing country: DE
-----------------------

[OK] Countries processed: 1
States created: 16
States skipped (already exist): 0
Countries activated: 0
```
2 changes: 1 addition & 1 deletion src/CoreShop/Bundle/CoreBundle/Application/Version.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ final class Version

public const MINOR_VERSION = '1';

public const RELEASE_VERSION = '8';
public const RELEASE_VERSION = '9';

public const EXTRA_VERSION = '';

Expand Down
182 changes: 182 additions & 0 deletions src/CoreShop/Bundle/CoreBundle/Command/SetupStatesCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
<?php

declare(strict_types=1);

/*
* CoreShop
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - CoreShop Commercial License (CCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) CoreShop GmbH (https://www.coreshop.com)
* @license https://www.coreshop.com/license GPLv3 and CCL
*
*/

namespace CoreShop\Bundle\CoreBundle\Command;

use CoreShop\Component\Address\Model\StateInterface;
use CoreShop\Component\Address\Repository\CountryRepositoryInterface;
use CoreShop\Component\Resource\Factory\FactoryInterface;
use CoreShop\Component\Resource\Repository\RepositoryInterface;
use Doctrine\ORM\EntityManagerInterface;
use Pimcore\Tool;
use Rinvex\Country\CountryLoader;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

final class SetupStatesCommand extends Command
{
public function __construct(
private CountryRepositoryInterface $countryRepository,
private RepositoryInterface $stateRepository,
private FactoryInterface $stateFactory,
private EntityManagerInterface $entityManager,
) {
parent::__construct();
}

protected function configure(): void
{
$this
->setName('coreshop:setup:states')
->setDescription('Create states/regions for specified countries.')
->addArgument(
'countries',
InputArgument::REQUIRED,
'Comma-separated list of country ISO codes (e.g., DE,US,FR)',
)
->addOption(
'activate-country',
null,
InputOption::VALUE_NONE,
'Also activate the country if not already active',
)
->setHelp(
<<<EOT
The <info>%command.name%</info> command creates states/regions for specified countries.

Examples:
<info>php bin/console %command.name% DE</info>
<info>php bin/console %command.name% DE,US,FR</info>
<info>php bin/console %command.name% DE --activate-country</info>
EOT
)
;
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);

$countriesArg = $input->getArgument('countries');
$activateCountry = $input->getOption('activate-country');
$countryCodes = array_map('strtoupper', array_map('trim', explode(',', $countriesArg)));

$languages = Tool::getValidLanguages();

$io->title('CoreShop States Setup');
$io->writeln(sprintf('Setting up states for countries: <info>%s</info>', implode(', ', $countryCodes)));

$createdStates = 0;
$skippedStates = 0;
$countriesProcessed = 0;
$activatedCountries = 0;

foreach ($countryCodes as $countryCode) {
$io->section(sprintf('Processing country: %s', $countryCode));

// Check if country exists in database
$country = $this->countryRepository->findByCode($countryCode);
if ($country === null) {
$io->warning(sprintf('Country with code "%s" not found in database. Run fixtures first or install CoreShop.', $countryCode));

continue;
}

// Load country data from Rinvex
try {
$rinvexCountry = CountryLoader::country($countryCode);
} catch (\Exception $e) {
$io->warning(sprintf('Country data not found for code "%s" in Rinvex data: %s', $countryCode, $e->getMessage()));

continue;
}

// Activate country if requested
if ($activateCountry && !$country->getActive()) {
$country->setActive(true);
$this->entityManager->persist($country);
$activatedCountries++;
$io->writeln(sprintf(' <comment>Activated country: %s</comment>', $countryCode));
}

// Get divisions (states/regions)
$divisions = $rinvexCountry->getDivisions();

if (!is_array($divisions) || empty($divisions)) {
$io->writeln(sprintf(' <comment>No divisions/states found for %s</comment>', $countryCode));
$countriesProcessed++;

continue;
}

foreach ($divisions as $isoCode => $division) {
if (!$division['name']) {
continue;
}

// Check if state already exists
$existingState = $this->stateRepository->findOneBy([
'isoCode' => $isoCode,
'country' => $country,
]);

if ($existingState !== null) {
$skippedStates++;
$io->writeln(sprintf(' <comment>Skipping existing state: %s (%s)</comment>', $division['name'], $isoCode), OutputInterface::VERBOSITY_VERBOSE);

continue;
}

/**
* @var StateInterface $state
*/
$state = $this->stateFactory->createNew();

foreach ($languages as $lang) {
$state->setName($division['name'], $lang);
}

$state->setIsoCode($isoCode);
$state->setCountry($country);
$state->setActive(true);

$this->entityManager->persist($state);
$createdStates++;

$io->writeln(sprintf(' <info>Created state: %s (%s)</info>', $division['name'], $isoCode), OutputInterface::VERBOSITY_VERBOSE);
}

$countriesProcessed++;
}

$this->entityManager->flush();

$io->success([
sprintf('Countries processed: %d', $countriesProcessed),
sprintf('States created: %d', $createdStates),
sprintf('States skipped (already exist): %d', $skippedStates),
sprintf('Countries activated: %d', $activatedCountries),
]);

return Command::SUCCESS;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,12 @@ services:
tags:
- { name: console.command, command: coreshop:migration:generate }

CoreShop\Bundle\CoreBundle\Command\SetupStatesCommand:
arguments:
- '@coreshop.repository.country'
- '@coreshop.repository.state'
- '@coreshop.factory.state'
- '@doctrine.orm.entity_manager'
tags:
- { name: console.command, command: coreshop:setup:states }

Loading