<?php declare(strict_types=1);
namespace Compra\FoundationSW6\Administration\Subscriber;
use Psr\Container\ContainerInterface;
use Shopware\Core\Framework\App\Event\AppInstalledEvent;
use Shopware\Core\Framework\App\Manifest\Manifest;
use Shopware\Core\Framework\App\Manifest\Xml\Module;
use Shopware\Core\Framework\Context;
use Shopware\Core\Defaults;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\System\Language\LanguageEntity;
use Shopware\Core\System\Locale\LocaleEntity;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Compra\FoundationSW6\Core\System\AppModuleService;
class AppSubscriber implements EventSubscriberInterface
{
/** @var ContainerInterface */
protected $container;
private $appRepository;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
$this->appRepository = $container->get('app.repository');
}
public static function getSubscribedEvents(): array
{
return [
AppInstalledEvent::class => 'onAppInstalled',
];
}
// adds variant details to product extensions for listing page and ajax loaded listings
public function onAppInstalled(AppInstalledEvent $event): void
{
$app = $event->getApp();
$manifest = $event->getManifest();
$context = $event->getContext();
$defaultLocale = $this->getDefaultLocale($context);
if(!($app->getAppSecret()) && strpos($app->getName(), AppModuleService::COMPRA_PLUGIN_PREFIX) !== false) {
$this->updateAppData($manifest, $app->getId(), $defaultLocale, $context);
}
}
protected function getDefaultLocale(Context $context): string
{
$criteria = new Criteria([Defaults::LANGUAGE_SYSTEM]);
$criteria->addAssociation('locale');
/** @var LanguageEntity $language */
$language = $this->container->get('language.repository')->search($criteria, $context)->first();
/** @var LocaleEntity $locale */
$locale = $language->getLocale();
return $locale->getCode();
}
protected function updateAppData(Manifest $manifest, string $id, string $defaultLocale, Context $context): void
{
$payload = [
'id' => $id,
'mainModule' => null,
'modules' => [],
];
// checks if any admin module in registered in the app manifest-file
if ($manifest->getAdmin() !== null) {
// checks if any main module is registered (a main module replaces the "config" window for the app with the given iframe)
if ($manifest->getAdmin()->getMainModule() !== null) {
// if configured, set the given source to the app entity
$payload['mainModule'] = [
'source' => $manifest->getAdmin()->getMainModule()->getSource(),
];
}
// loads all configured modules (menu entries) into the payload
$payload['modules'] = array_reduce(
$manifest->getAdmin()->getModules(),
static function (array $modules, Module $module) use ($defaultLocale) {
$modules[] = $module->toArray($defaultLocale);
return $modules;
},
[]
);
if(!empty($payload['modules'])) {
// checks if module sources are relative and adds the shop url as prefix to compile with the app module loader in vueJS
foreach($payload['modules'] as &$module) {
if($module['source'] && substr($module['source'][0], 0, 1) === "/") {
$module['source'] = $_SERVER['APP_URL'] . $module['source'];
}
}
}
}
// update general modle information
$this->appRepository->update([$payload], $context);
// update app secret key
$secret = AppModuleService::COMPRA_APP_SECRET;
$update = ['id' => $id, 'appSecret' => $secret];
$context->scope(Context::SYSTEM_SCOPE, function (Context $context) use ($update): void {
$this->appRepository->update([$update], $context);
});
}
}