<?php
declare(strict_types=1);
namespace EconsorCrowdfunding;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use Shopware\Core\Content\Media\DataAbstractionLayer\MediaFolderRepositoryDecorator;
use Shopware\Core\Defaults;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
use Shopware\Core\Framework\Plugin;
use Shopware\Core\Framework\Plugin\Context\InstallContext;
use Shopware\Core\Framework\Plugin\Context\UninstallContext;
use Shopware\Core\Framework\Uuid\Uuid;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Symfony\Component\Config\Definition\Exception\Exception;
/**
* Class EconsorCrowdfunding
* @package EconsorCrowdfunding
*/
class EconsorCrowdfunding extends Plugin
{
/**
* @param InstallContext $installContext
*/
public function install(InstallContext $installContext): void
{
parent::install($installContext);
$configService = $this->container->get(SystemConfigService::class);
$this->mediaFolderFunction(true, 'Econsor Crowdfunding Images', 'image');
$this->mediaFolderFunction(true, 'Econsor Crowdfunding Backgrounds', 'background');
$this->removeProducts();
$this->deleteMails();
$this->createProducts();
$this->createMails($installContext, $configService);
}
/**
* @param UninstallContext $context
*/
public function uninstall(UninstallContext $context): void
{
parent::uninstall($context);
$configService = $this->container->get(SystemConfigService::class);
$productRepository = $this->container->get('product.repository');
//$productRepository->delete([['id' => $configService->get('EconsorCrowdfunding.config.feeID')]], Context::createDefaultContext());
//$productRepository->delete([['id' => $configService->get('EconsorCrowdfunding.config.donationID')]], Context::createDefaultContext());
//$productRepository->delete([['id' => $configService->get('EconsorCrowdfunding.config.goodieID')]], Context::createDefaultContext());
$this->deleteMails();
if ($context->keepUserData()) {
return;
}
$this->removeMigrations();
$connection = $this->container->get(Connection::class);
$connection->executeQuery('DROP TABLE IF EXISTS `ec_crowdfunding_orderhistory`');
$connection->executeQuery('DROP TABLE IF EXISTS `ec_crowdfunding_order_bundles`');
$connection->executeQuery('DROP TABLE IF EXISTS `ec_crowdfunding_sponsor_translation`');
$connection->executeQuery('DROP TABLE IF EXISTS `product_sponsors`');
$connection->executeQuery('DROP TABLE IF EXISTS `ec_crowdfunding_goodie`');
$connection->executeQuery('DROP TABLE IF EXISTS `ec_crowdfunding_campaign_validation`');
$connection->executeQuery('DROP TABLE IF EXISTS `ec_crowdfunding_order_shirt_configuration`');
$connection->executeQuery('DROP TABLE IF EXISTS `ec_crowdfunding_campaign`');
$connection->executeQuery('DROP TABLE IF EXISTS `ec_crowdfunding_own_sponsor`');
$connection->executeQuery('DROP TABLE IF EXISTS `ec_crowdfunding_sponsor`');
$this->mediaFolderFunction(false, 'Econsor Crowdfunding Images', 'image');
$this->mediaFolderFunction(false, 'Econsor Crowdfunding Backgrounds', 'background');
}
//######################################################MAILS#######################################################
/**
* @param $configService
*/
private function deleteMails()
{
$ids = [
'econsor_crowdfunding_mail_success',
'econsor_crowdfunding_mail_failed',
'econsor_crowdfunding_mail_await_confirmation_admin',
'econsor_crowdfunding_mail_await_confirmation_trainer',
'econsor_crowdfunding_mail_await_confirmation_sponsor',
'econsor_crowdfunding_validate_campaign_trainer',
'econsor_crowdfunding_validate_campaign_confirmed',
'econsor_crowdfunding_validate_denied_confirmed',
'econsor_crowdfunding_validate_campaign_trainer_after_sponsor',
'econsor_crowdfunding_sponsor_confirmed',
'econsor_crowdfunding_notification_5_days_left',
'econsor_crowdfunding_notification_almost_there',
'econsor_crowdfunding_notification_halftime',
'econsor_crowdfunding_notification_goal_reached'
];
$mailTemplateTypeRepository = $this->container->get('mail_template_type.repository');
$mailTemplateRepository = $this->container->get('mail_template.repository');
$context = Context::createDefaultContext();
foreach ($ids as $id) {
try {
$c = new Criteria();
$c->addFilter(new EqualsFilter('technicalName', $id));
if ($mailTemplateTypeRepository->search($c, $context)->getEntities()->first()) {
$tplId = $mailTemplateTypeRepository->search($c, $context)->getEntities()->first()->getId();
$cc = new Criteria();
$cc->addFilter(new EqualsFilter('mailTemplateTypeId', $tplId));
$ids = $mailTemplateRepository->search($cc, $context)->getElements();
if ([] !== $ids) {
foreach ($ids as $id => $array) {
$mailTemplateRepository->delete([['id' => $id]], $context);
}
}
$mailTemplateTypeRepository->delete([['id' => $tplId]], $context);
}
} catch (\Exception $exception) {
}
continue;
}
}
/**
* @param $installContext
* @param $configService
*/
private function createMails($installContext, $configService)
{
$mailTemplateTypeRepository = $this->container->get('mail_template_type.repository');
$mailTemplateRepository = $this->container->get('mail_template.repository');
$templates = [
'campaignSuccessMail' => [
'type' => [
'name' => 'CrowdFundingSuccessMail',
'technicalName' => 'econsor_crowdfunding_mail_success',
'availableEntities' => []
],
'template' => [
'subject' => [
'en-GB' => 'Your Campaign was a success!',
'de-DE' => 'Deine Kampagne war erfolgreich!'
],
'contentPlain' => strip_tags(
file_get_contents(
__DIR__ . '/Resources/custom/mail_templates/crowdfund_campaign_success.html.twig'
)
),
'contentHtml' => file_get_contents(
__DIR__ . '/Resources/custom/mail_templates/crowdfund_campaign_success.html.twig'
)
]
],
'campaignFailedMail' => [
'type' => [
'name' => 'CrowdFundingFailedMail',
'technicalName' => 'econsor_crowdfunding_mail_failed',
'availableEntities' => []
],
'template' => [
'subject' => [
'en-GB' => "Your Campaign didn't quite make it!",
'de-DE' => 'Deine Kampagne hat es leider nicht geschafft!'
],
'contentPlain' => strip_tags(
file_get_contents(
__DIR__ . '/Resources/custom/mail_templates/crowdfund_campaign_failed.html.twig'
)
),
'contentHtml' => file_get_contents(
__DIR__ . '/Resources/custom/mail_templates/crowdfund_campaign_failed.html.twig'
)
]
],
'campaignAwaitConfirmationAdmin' => [
'type' => [
'name' => 'CrowdFundingAwaitConfirmationAdmin',
'technicalName' => 'econsor_crowdfunding_mail_await_confirmation_admin',
'availableEntities' => []
],
'template' => [
'subject' => [
'en-GB' => 'A new Campaign is awaiting confirmation',
'de-DE' => 'Eine neue Kampagne erwartet freigabe!'
],
'contentPlain' => strip_tags(
file_get_contents(
__DIR__ . '/Resources/custom/mail_templates/crowdfund_campaign_awaiting_confirmation_admin.html.twig'
)
),
'contentHtml' => file_get_contents(
__DIR__ . '/Resources/custom/mail_templates/crowdfund_campaign_awaiting_confirmation_admin.html.twig'
)
]
],
'campaignAwaitConfirmationTrainer' => [
'type' => [
'name' => 'CrowdFundingAwaitConfirmationTrainer',
'technicalName' => 'econsor_crowdfunding_mail_await_confirmation_trainer',
'availableEntities' => []
],
'template' => [
'subject' => [
'en-GB' => 'Your Campaign is awaiting confirmation!',
'de-DE' => 'Ihre Kampagne erwartet momentan noch freigabe!'
],
'contentPlain' => strip_tags(
file_get_contents(
__DIR__ . '/Resources/custom/mail_templates/crowdfund_campaign_awaiting_confirmation_trainer.html.twig'
)
),
'contentHtml' => file_get_contents(
__DIR__ . '/Resources/custom/mail_templates/crowdfund_campaign_awaiting_confirmation_trainer.html.twig'
)
]
],
'campaignAwaitConfirmationSponsor' => [
'type' => [
'name' => 'CrowdFundingAwaitConfirmationSponsor',
'technicalName' => 'econsor_crowdfunding_mail_await_confirmation_sponsor',
'availableEntities' => []
],
'template' => [
'subject' => [
'en-GB' => 'You were chosen as a sponsor!',
'de-DE' => 'Sie wurden als Sponsor angegeben!'
],
'contentPlain' => strip_tags(
file_get_contents(
__DIR__ . '/Resources/custom/mail_templates/crowdfund_campaign_awaiting_confirmation_sponsor.html.twig'
)
),
'contentHtml' => file_get_contents(
__DIR__ . '/Resources/custom/mail_templates/crowdfund_campaign_awaiting_confirmation_sponsor.html.twig'
)
]
],
'campaignValidateCampaignTrainer' => [
'type' => [
'name' => 'CrowdFundingValidateCampaignTrainer',
'technicalName' => 'econsor_crowdfunding_validate_campaign_trainer',
'availableEntities' => []
],
'template' => [
'subject' => [
'en-GB' => 'Your Campaign needs to be edited!',
'de-DE' => 'Ihre Kampagne muss noch bearbeitet werden!'
],
'contentPlain' => strip_tags(
file_get_contents(
__DIR__ . '/Resources/custom/mail_templates/crowdfund_campaign_confirm_campaign_trainer.html.twig'
)
),
'contentHtml' => file_get_contents(
__DIR__ . '/Resources/custom/mail_templates/crowdfund_campaign_confirm_campaign_trainer.html.twig'
)
]
],
'campaignConfirmedMail' => [
'type' => [
'name' => 'CrowdFundingCampaignConfirmed',
'technicalName' => 'econsor_crowdfunding_validate_campaign_confirmed',
'availableEntities' => []
],
'template' => [
'subject' => [
'en-GB' => 'Your Campaign was confirmed!',
'de-DE' => 'Ihre Kampagne wurde zugelassen!'
],
'contentPlain' => strip_tags(
file_get_contents(
__DIR__ . '/Resources/custom/mail_templates/crowdfund_campaign_confirmed_trainer.html.twig'
)
),
'contentHtml' => file_get_contents(
__DIR__ . '/Resources/custom/mail_templates/crowdfund_campaign_confirmed_trainer.html.twig'
)
]
],
'campaignDeniedMail' => [
'type' => [
'name' => 'CrowdFundingCampaigDenied',
'technicalName' => 'econsor_crowdfunding_validate_denied_confirmed',
'availableEntities' => []
],
'template' => [
'subject' => [
'en-GB' => 'Your Campaign was denied!',
'de-DE' => 'Ihre Kampagne wurde nicht zugelassen!'
],
'contentPlain' => strip_tags(
file_get_contents(
__DIR__ . '/Resources/custom/mail_templates/crowdfund_campaign_denied_trainer.html.twig'
)
),
'contentHtml' => file_get_contents(
__DIR__ . '/Resources/custom/mail_templates/crowdfund_campaign_denied_trainer.html.twig'
)
]
],
'campaignValidateCampaignTrainerAfterSponsor' => [
'type' => [
'name' => 'CrowdFundingValidateCampaignTrainerAfterSponsor',
'technicalName' => 'econsor_crowdfunding_validate_campaign_trainer_after_sponsor',
'availableEntities' => []
],
'template' => [
'subject' => [
'en-GB' => 'Your Campaign is awaiting confirmation!',
'de-DE' => 'Ihre Kampagne erwartet momentan noch freigabe!'
],
'contentPlain' => strip_tags(
file_get_contents(
__DIR__ . '/Resources/custom/mail_templates/crowdfund_campaign_confirm_campaign_trainer_after_sponsor.html.twig'
)
),
'contentHtml' => file_get_contents(
__DIR__ . '/Resources/custom/mail_templates/crowdfund_campaign_confirm_campaign_trainer_after_sponsor.html.twig'
)
]
],
'campaignSponsorConfirmed' => [
'type' => [
'name' => 'CrowdFundingSponsorConfirmed',
'technicalName' => 'econsor_crowdfunding_sponsor_confirmed',
'availableEntities' => []
],
'template' => [
'subject' => [
'en-GB' => 'You have confirmed your Sponsor Role!',
'de-DE' => 'Sie haben ihre Sponsorenrolle bestätigt!'
],
'contentPlain' => strip_tags(
file_get_contents(
__DIR__ . '/Resources/custom/mail_templates/crowdfund_campaign_sponsor_confirmed.html.twig'
)
),
'contentHtml' => file_get_contents(
__DIR__ . '/Resources/custom/mail_templates/crowdfund_campaign_sponsor_confirmed.html.twig'
)
]
],
'notification5DaysLeft' => [
'type' => [
'name' => 'CrowdFundingNotification5DaysLeft',
'technicalName' => 'econsor_crowdfunding_notification_5_days_left',
'availableEntities' => []
],
'template' => [
'subject' => [
'en-GB' => '5 Days left!',
'de-DE' => 'Noch 5 Tage!'
],
'contentPlain' => strip_tags(
file_get_contents(
__DIR__ . '/Resources/custom/mail_templates/crowdfund_notifications_5_days_left.html.twig'
)
),
'contentHtml' => file_get_contents(
__DIR__ . '/Resources/custom/mail_templates/crowdfund_notifications_5_days_left.html.twig'
)
]
],
'notificationAlmostThere' => [
'type' => [
'name' => 'CrowdFundingNotificationAlmostThere',
'technicalName' => 'econsor_crowdfunding_notification_almost_there',
'availableEntities' => []
],
'template' => [
'subject' => [
'en-GB' => 'Almost there!',
'de-DE' => 'Fast geschafft!'
],
'contentPlain' => strip_tags(
file_get_contents(
__DIR__ . '/Resources/custom/mail_templates/crowdfund_notifications_almost_there.html.twig'
)
),
'contentHtml' => file_get_contents(
__DIR__ . '/Resources/custom/mail_templates/crowdfund_notifications_almost_there.html.twig'
)
]
],
'notificationHalftime' => [
'type' => [
'name' => 'CrowdFundingNotificationHalftime',
'technicalName' => 'econsor_crowdfunding_notification_halftime',
'availableEntities' => []
],
'template' => [
'subject' => [
'en-GB' => 'Halftime!',
'de-DE' => 'Halbzeit!'
],
'contentPlain' => strip_tags(
file_get_contents(
__DIR__ . '/Resources/custom/mail_templates/crowdfund_notifications_halftime.html.twig'
)
),
'contentHtml' => file_get_contents(
__DIR__ . '/Resources/custom/mail_templates/crowdfund_notifications_halftime.html.twig'
)
]
],
'notificationGoalReached' => [
'type' => [
'name' => 'CrowdFundingNotificationGoalReached',
'technicalName' => 'econsor_crowdfunding_notification_goal_reached',
'availableEntities' => []
],
'template' => [
'subject' => [
'en-GB' => 'Goal reached!',
'de-DE' => 'Ziel erreicht!'
],
'contentPlain' => strip_tags(
file_get_contents(
__DIR__ . '/Resources/custom/mail_templates/crowdfund_notifications_reached_goal.html.twig'
)
),
'contentHtml' => file_get_contents(
__DIR__ . '/Resources/custom/mail_templates/crowdfund_notifications_reached_goal.html.twig'
)
]
]
];
try {
foreach ($templates as $configName => $data) {
$id = Uuid::randomHex();
$this->addMailType($data['type'], $id, $mailTemplateTypeRepository, $installContext->getContext());
$this->addMailTemplate($data['template'], $id, $mailTemplateRepository, $installContext->getContext());
$configService->set('EconsorCrowdfunding.config.' . $configName, $id);
}
} catch (Exception $exception) {
$this->deleteMails($configService);
throw new Exception('Mails couldnt be added, try again', 1);
}
}
/**
* @param $data
* @param $id
* @param $repo
* @param $context
*/
private function addMailType($data, $id, $repo, $context)
{
$mailTemplateType =
[
[
'id' => $id,
'name' => $data['name'],
'technicalName' => $data['technicalName'],
'availableEntities' => $data['availableEntities']
]
];
try {
$repo->create($mailTemplateType, $context);
} catch (UniqueConstraintViolationException $exception) {
}
}
/**
* @param $data
* @param $id
* @param $repo
* @param $context
*/
private function addMailTemplate($data, $id, $repo, $context)
{
$mailTemplate =
[
[
'id' => Uuid::randomHex(),
'mailTemplateTypeId' => $id,
'subject' => $data['subject'],
'contentPlain' => $data['contentPlain'],
'contentHtml' => $data['contentHtml']
]
];
try {
$repo->create($mailTemplate, $context);
} catch (UniqueConstraintViolationException $exception) {
}
}
//#####################################################PRODUCTS#####################################################
private function createProducts()
{
try {
$configService = $this->container->get(SystemConfigService::class);
$context = Context::createDefaultContext();
$productRepository = $this->container->get('product.repository');
$id = $this->generate(
[
'price' => 39,
'number' => 'CROWDFUNDING-FEE',
'description' => 'Crowdfunding Gebühr',
'name' => 'Crowdfunding Gebühr'
],
$context,
$productRepository
);
$configService->set('EconsorCrowdfunding.config.feeID', $id);
$id = $this->generate(
[
'price' => 0,
'number' => 'CROWDFUNDING-DONATION',
'description' => 'Crowdfunding Spende',
'name' => 'Crowdfunding Spende'
],
$context,
$productRepository
);
$configService->set('EconsorCrowdfunding.config.donationID', $id);
$id = $this->generate(
[
'price' => 0,
'number' => 'CROWDFUNDING-GOODIE',
'description' => 'Crowdfunding Goodie',
'name' => 'Crowdfunding Goodie'
],
$context,
$productRepository
);
$configService->set('EconsorCrowdfunding.config.goodieID', $id);
} catch (Exception $exception) {
$this->removeProducts();
throw new Exception('Products couldnt be added, try again', 1);
}
}
/**
* @param $params
* @param $context
* @param $productRepository
* @return string
*/
private function generate($params, $context, $productRepository): string
{
$id = Uuid::randomHex();
$taxRepository = $this->container->get('tax.repository');
$taxObj = $taxRepository->search(
(new Criteria())->addSorting(new FieldSorting('taxRate', FieldSorting::DESCENDING)),
$context
)->first();
$tax = $taxObj->getTaxRate();
$net = $params['price'] / (1 + ($tax / 100));
$data = [
'id' => $id,
'productNumber' => $params['number'],
'description' => $params['description'],
'stock' => 999999,
'name' => $params['name'],
'price' => [
[
'linked' => false,
'net' => (float)$net,
'gross' => (float)$params['price'],
'currencyId' => Defaults::CURRENCY,
]
],
'tax' => [
'id' => $taxObj->getId()
]
];
$productRepository->upsert([$data], $context);
$this->getVisibility($id);
return $id;
}
private function removeProducts()
{
$connection = $this->container->get(Connection::class);
$connection->executeQuery("DELETE FROM product WHERE product_number = 'CROWDFUNDING-GOODIE'");
$connection->executeQuery("DELETE FROM product WHERE product_number = 'CROWDFUNDING-FEE'");
$connection->executeQuery("DELETE FROM product WHERE product_number = 'CROWDFUNDING-DONATION'");
}
/**
* @param $id
*/
private function getVisibility($id)
{
$salesChannelRepository = $this->container->get('sales_channel.repository');
$visibilityRepository = $this->container->get('product_visibility.repository');
$context = Context::createDefaultContext();
$channels = $salesChannelRepository->search(new Criteria(), $context);
foreach ($channels as $index => $channel) {
$payload = [
'id' => Uuid::randomHex(),
'productId' => $id,
'productVersionId' => Defaults::LIVE_VERSION,
'salesChannelId' => $index,
'visibility' => 30
];
$visibilityRepository->upsert([$payload], $context);
}
}
//#######################################################REST#######################################################
/**
* @param $flag
* @param $name
* @param $folderType
*/
private function mediaFolderFunction($flag, $name, $folderType)
{
/** @var EntityRepositoryInterface $mediaFolderRepository */
$mediaFolderRepository = $this->container->get('media_folder.repository');
$configService = $this->container->get(SystemConfigService::class);
$c = new Criteria();
//$c->addFilter(new EqualsFilter('name', 'Econsor Crowdfunding Images'));
$c->addFilter(new EqualsFilter('name', $name));
$folder = $mediaFolderRepository->search($c, Context::createDefaultContext())->getEntities()->first();
if($flag)
{
//create
if($folder)
{
$configService->set('EconsorCrowdfunding.config.'.$folderType.'Folder', $folder->getId());
} else {
$id = Uuid::randomHex();
$mediaFolderRepository->create(
[
[
'name' => $name,
'configuration' => [
'id' => $id
],
'id' => $id
]
],
Context::createDefaultContext()
);
$configService->set('EconsorCrowdfunding.config.'.$folderType.'Folder', $id);
}
}
//delete
if($folder && !$flag)
{
$mediaFolderRepository = $this->container->get('media_folder.repository');
$mediaFolderRepository->delete(
[
[
'id' => $folder->getId()
]
],
Context::createDefaultContext()
);
}
}
}