Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
ebe6c14
ECTO-2233 - added extenison-store-channel service to handle communica…
FloBWer Oct 22, 2025
84bd217
ECTO-2203 - add changes for checkout out of the evaluation to the fea…
FloBWer Oct 29, 2025
e1e725b
ECTO-2282 - make iframe url configurable (#126)
FloBWer Dec 1, 2025
13ee3ca
ECTO-2328 - changed language handover (#128)
FloBWer Dec 4, 2025
34483e5
ECTO-2339 - added approach for deep lining into the iframe store (#129)
FloBWer Jan 5, 2026
0a6ed17
ECTO-2406 - added post message function for copy to clipboard (#130)
FloBWer Feb 13, 2026
016c305
ECTO-2395 - implemented rough woring checkout with sample modal (#131)
FloBWer Feb 23, 2026
776f99e
ECTO-2396 - add checkout process implementation (#132)
kaigossel Mar 16, 2026
52678e0
ECTO-2581 - Add tracking for extension store checkout (#144)
qysp Apr 27, 2026
4b473cb
ODLY-5579 - Fix SW Admin modal footers not being visible (#146)
qysp Apr 29, 2026
6d6cf8c
ECTO-2474 - update query params regarding to search filter and pagina…
FloBWer Apr 30, 2026
4c5f9be
ECTO-2521 - added error messages of api to the checkout (#152)
FloBWer May 7, 2026
1938993
ECTO-2573 - add licenseHost for SkyBridgeStore tracking (#153)
mappinnn May 8, 2026
9233538
ECTO-2638 - Provide the entire user info state to the app (#155)
qysp May 19, 2026
5c4fe31
ECTO-2554 - Make extension installation after checkout optional (#156)
qysp May 20, 2026
8c41709
ECTO-2635 - always push router updates, publish popstate router state…
kaigossel May 26, 2026
a319f0e
Merge origin/trunk into epic/ECTO-2267 (#160)
qysp May 27, 2026
85bf1b3
ECTO-2659 - Refactor iframe rendering (#159)
qysp May 28, 2026
f19f83f
ECTO-2672 - Remove unused components, snippets, endpoints etc. (#161)
qysp Jun 3, 2026
92bde35
ECTO-2686 - added licenseHost to the handshake object (#171)
FloBWer Jun 18, 2026
bbc6b77
ECTO-2679 - Support deep linking to PDP by internal ID or technical n…
qysp Jun 18, 2026
f411d54
ECTO-2666 - Change the default iframe URL to production (#174)
qysp Jun 22, 2026
d7dd7a7
ECTO-2679 - Regard the state on router updates (#175)
qysp Jun 22, 2026
a7847f3
ECTO-2704 - Prevent automatic installation of incompatible extensions…
qysp Jun 26, 2026
6f1ab70
ECTO-2707 - Add installation in progress hint in checkout modal (#179)
qysp Jun 26, 2026
cccb40c
ECTO-2706 - include installed extension versions in store context (#180)
mappinnn Jun 30, 2026
e8e1828
ECTO-2707 - Fix installation in progress hint in checkout modal (#182)
qysp Jun 30, 2026
6a96cb4
ECTO-2702 - only add licensed extensions as owned on handshake (#183)
kaigossel Jul 6, 2026
35d00ca
ECTO-2774 - publish router sync when navigating back to main route (#…
kaigossel Jul 29, 2026
4197269
ECTO-2770 - Reload page after successful extension installation (#190)
qysp Jul 29, 2026
0058e88
ECTO-2770 - ECTO-2770 - Report the real purchase result when the moda…
qysp Aug 3, 2026
474232b
ECTO-2855 - detect demo shops by demo shop bundle (#196)
mappinnn Aug 6, 2026
32a5ccd
ECTO-2723 - Restrict demo shops from checking out in-app purchases (#…
qysp Aug 7, 2026
ee27026
ECTO-2760 - merge trunk, handle extended routeTo action data from ifr…
kaigossel Aug 14, 2026
f94f37b
Merge origin/trunk into epic/ECTO-2267 (#208)
kaigossel Sep 7, 2026
1a91355
ECTO-2922 - Show test license checkout for demo shops (#207)
qysp Sep 7, 2026
3bf13b3
Merge origin/trunk into epic/ECTO-2267
kaigossel Sep 11, 2026
c8e197b
ECTO-2761 - add missing snippets, bump release version (#211)
kaigossel Sep 16, 2026
60405f9
ECTO-2761 - fix client exception body parsing (#212)
qysp Sep 16, 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 composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "swag/swag-extension-store",
"version": "4.2.3",
"version": "7.0.0",
"description": "SWAG Extension Store",
"type": "shopware-platform-plugin",
"license": "MIT",
Expand Down
74 changes: 0 additions & 74 deletions src/Controller/DataController.php

This file was deleted.

6 changes: 3 additions & 3 deletions src/Controller/LicenseController.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,15 @@ public function createCart(Request $request, Context $context): JsonResponse
$extensionId = $request->request->get('extensionId');
$variantId = $request->request->get('variantId');

if (!is_numeric($extensionId)) {
if (!\is_int($extensionId) && !\is_string($extensionId)) {
throw ExtensionStoreException::invalidExtensionId();
}

if (!is_numeric($variantId)) {
if (!\is_int($variantId) && !\is_string($variantId)) {
throw ExtensionStoreException::invalidVariantId();
}

$cart = $this->licenseService->createCart((int) $extensionId, (int) $variantId, $context);
$cart = $this->licenseService->createCart($extensionId, $variantId, $context);

return new JsonResponse($cart);
}
Expand Down
32 changes: 28 additions & 4 deletions src/Exception/ExtensionStoreApiException.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ class ExtensionStoreApiException extends StoreApiException
{
protected string $apiCode;

protected string $description;

public function __construct(ClientException $exception)
{
parent::__construct($exception);

try {
$data = json_decode($exception->getResponse()->getBody()->getContents(), true, 512, \JSON_THROW_ON_ERROR);
} catch (\JsonException) {
}
$data = $this->getData($exception);
$this->apiCode = $data['code'] ?? '';
$this->description = $data['description'] ?? '';
}

public function getErrors(bool $withTrace = false): \Generator
Expand All @@ -29,7 +29,31 @@ public function getErrors(bool $withTrace = false): \Generator
yield [
...$error,
'apiCode' => $this->apiCode,
'description' => $this->description,
];
}
}

/**
* @return array<array-key, mixed>
*/
private function getData(ClientException $exception): array
{
$body = $exception->getResponse()->getBody();

// The parent constructor already read the body to its end and left the stream at EOF,
// so reading it again without rewinding yields an empty string.
if ($body->isSeekable()) {
$body->rewind();
}

try {
$data = json_decode($body->getContents(), true, 512, \JSON_THROW_ON_ERROR);
} catch (\JsonException) {
return [];
}

// A body may be valid JSON without being an object, e.g. a bare string or number.
return \is_array($data) ? $data : [];
}
}
41 changes: 41 additions & 0 deletions src/Migration/Migration1779864357StoreIFrameUrlConfig.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php declare(strict_types=1);

namespace SwagExtensionStore\Migration;

use Doctrine\DBAL\Connection;
use Shopware\Core\Defaults;
use Shopware\Core\Framework\Log\Package;
use Shopware\Core\Framework\Migration\MigrationStep;
use Shopware\Core\Framework\Uuid\Uuid;

/**
* @internal
*/
#[Package('checkout')]
class Migration1779864357StoreIFrameUrlConfig extends MigrationStep
{
public function getCreationTimestamp(): int
{
return 1779864357;
}

public function update(Connection $connection): void
{
$configurationKey = 'SwagExtensionStore.config.iframeUrl';
$configurationExists = $connection->fetchOne(
'SELECT 1 FROM system_config WHERE configuration_key = :configurationKey',
['configurationKey' => $configurationKey],
);

if ($configurationExists !== false) {
return;
}

$connection->insert('system_config', [
'id' => Uuid::randomBytes(),
'configuration_key' => $configurationKey,
'configuration_value' => '{"_value": "https://sky-bridge-store.production.shopware.in"}',
Comment thread
cyl3x marked this conversation as resolved.
'created_at' => (new \DateTimeImmutable())->format(Defaults::STORAGE_DATE_TIME_FORMAT),
]);
}
}
1 change: 1 addition & 0 deletions src/Resources/app/administration/eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ export default tseslint.config(
'stylistic/quote-props': ['error', 'as-needed'],
'stylistic/no-extra-semi': ['error'],
'stylistic/comma-dangle': ['error', 'always-multiline'],
'stylistic/quotes': ['error', 'single'],
/* stylistic rules */

/* typescript rules */
Expand Down
1 change: 1 addition & 0 deletions src/Resources/app/administration/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ module.exports = {
'^@shopware-ag/meteor-component-library$': `${process.env.ADMIN_PATH}/node_modules/@shopware-ag/meteor-component-library/dist/common/index.js`,
vue$: `${process.env.ADMIN_PATH}/node_modules/vue/dist/vue.cjs.js`,
'^@vue/test-utils$': `${process.env.ADMIN_PATH}/node_modules/@vue/test-utils/dist/vue-test-utils.cjs.js`,
'^lodash-es/(.*)$': 'lodash/$1',
},

testEnvironmentOptions: {
Expand Down
66 changes: 66 additions & 0 deletions src/Resources/app/administration/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/Resources/app/administration/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,8 @@
},
"optionalDependencies": {
"administration": "^6.x"
},
"dependencies": {
"@shopware-ag/meteor-admin-sdk": "^6.8.0"
Comment thread
mstegmeyer marked this conversation as resolved.
}
}
7 changes: 7 additions & 0 deletions src/Resources/app/administration/src/global.types.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import type { PropType as TPropType } from 'vue';
import type InAppPurchasesService from './module/sw-in-app-purchases/service/in-app-purchases.service';
import type { AxiosError } from 'axios';
import type ExtensionStorePreferencesService
from 'SwagExtensionStore/module/sw-extension-store/service/extension-store-preferences.service';
import type {
ExtensionStoreChannelService,
} from 'SwagExtensionStore/module/sw-extension-store/service/extension-store-channel.service';

declare global {
type PropType<T> = TPropType<T>;

interface ServiceContainer {
inAppPurchasesService: InAppPurchasesService;
extensionStoreChannelService: ExtensionStoreChannelService;
extensionStorePreferencesService: ExtensionStorePreferencesService;
}

type ErrorResponse = AxiosError<{ errors: Array<ShopwareHttpError & { apiCode: string }> }>;
Expand Down
Loading
Loading