From 2d1af0d11b4c80c66ead4e95ede1a685079ff878 Mon Sep 17 00:00:00 2001 From: Jordan Kniest Date: Mon, 3 Jun 2024 19:16:39 +0200 Subject: [PATCH] Refactor all utils classes --- CHANGELOG.md | 1 + _examples/CustomerFixture.php | 4 +-- src/FixtureHelper.php | 10 +++---- src/Utils/CategoryUtils.php | 2 +- src/Utils/CmsUtils.php | 29 +++++++++++++----- src/Utils/CustomerUtils.php | 36 ----------------------- src/Utils/DatabaseUtils.php | 10 +++++++ src/Utils/MediaUtils.php | 43 +++++++++++++++++++-------- src/Utils/PaymentMethodUtils.php | 30 ++++++++++++++----- src/Utils/SalesChannelUtils.php | 47 ++++++++++++++++++++++++----- src/Utils/SalutationUtils.php | 49 +++++++++++++++++++++++++++++++ src/Utils/ShippingMethodUtils.php | 30 ++++++++++++++----- 12 files changed, 205 insertions(+), 86 deletions(-) delete mode 100644 src/Utils/CustomerUtils.php create mode 100644 src/Utils/SalutationUtils.php diff --git a/CHANGELOG.md b/CHANGELOG.md index fc50155..83e14f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - CategoryUtils - Removed method `getFirst` on CategoryUtils - Removed method `getByName` on CategoryUtils +- Renamed `CategoryUtils` to `SalutationUtils` ## [2.4.0] - 2023-11-15 ### Added diff --git a/_examples/CustomerFixture.php b/_examples/CustomerFixture.php index 456cb64..6574c0d 100644 --- a/_examples/CustomerFixture.php +++ b/_examples/CustomerFixture.php @@ -32,7 +32,7 @@ public function load(FixtureBag $bag): void 'defaultPaymentMethodId' => $this->helper->PaymentMethod()->getInvoicePaymentMethod()->getId(), 'defaultBillingAddress' => [ 'id' => self::ADDRESS_ID, - 'salutationId' => $this->helper->Customer()->getNotSpecifiedSalutation()->getId(), + 'salutationId' => $this->helper->Salutation()->getNotSpecifiedSalutation()->getId(), 'firstName' => 'John', 'lastName' => 'Doe', 'zipcode' => '1234', @@ -41,7 +41,7 @@ public function load(FixtureBag $bag): void 'countryId' => $this->helper->SalesChannel()->getCountry('DE')->getId(), ], 'defaultShippingAddressId' => self::ADDRESS_ID, - 'salutationId' => $this->helper->Customer()->getNotSpecifiedSalutation()->getId(), + 'salutationId' => $this->helper->Salutation()->getNotSpecifiedSalutation()->getId(), 'customerNumber' => '1122', 'firstName' => 'John', 'lastName' => 'Doe', diff --git a/src/FixtureHelper.php b/src/FixtureHelper.php index b1a35e9..98d4bd7 100644 --- a/src/FixtureHelper.php +++ b/src/FixtureHelper.php @@ -6,11 +6,11 @@ use Basecom\FixturePlugin\Utils\CategoryUtils; use Basecom\FixturePlugin\Utils\CmsUtils; -use Basecom\FixturePlugin\Utils\CustomerUtils; use Basecom\FixturePlugin\Utils\DatabaseUtils; use Basecom\FixturePlugin\Utils\MediaUtils; use Basecom\FixturePlugin\Utils\PaymentMethodUtils; use Basecom\FixturePlugin\Utils\SalesChannelUtils; +use Basecom\FixturePlugin\Utils\SalutationUtils; use Basecom\FixturePlugin\Utils\ShippingMethodUtils; readonly class FixtureHelper @@ -22,7 +22,7 @@ public function __construct( private CmsUtils $cmsUtils, private PaymentMethodUtils $paymentMethodUtils, private ShippingMethodUtils $shippingMethodUtils, - private CustomerUtils $customerUtils, + private SalutationUtils $salutationUtils, private DatabaseUtils $databaseUtils, ) { } @@ -55,12 +55,12 @@ public function SalesChannel(): SalesChannelUtils } /** - * Use this to access the customer related features + * Use this to access the salutation related features * of the fixture helper class. */ - public function Customer(): CustomerUtils + public function Salutation(): SalutationUtils { - return $this->customerUtils; + return $this->salutationUtils; } /** diff --git a/src/Utils/CategoryUtils.php b/src/Utils/CategoryUtils.php index 8407bef..45f7f5d 100644 --- a/src/Utils/CategoryUtils.php +++ b/src/Utils/CategoryUtils.php @@ -35,7 +35,7 @@ public function __construct( */ public function getRootCategory(): ?CategoryEntity { - return once(function () { + return once(function (): ?CategoryEntity { $criteria = (new Criteria()) ->addFilter(new EqualsFilter('autoIncrement', 1)) ->addFilter(new EqualsFilter('level', 1)) diff --git a/src/Utils/CmsUtils.php b/src/Utils/CmsUtils.php index b3aaac0..17f3122 100644 --- a/src/Utils/CmsUtils.php +++ b/src/Utils/CmsUtils.php @@ -12,6 +12,15 @@ use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter; use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter; +/** + * This class provides utility methods to work with the shopware cms. It has build in caching to prevent + * multiple database queries for the same data within one command execution / request. + * + * This class is designed to be used through the FixtureHelper, using: + * ```php + * $this->helper->Cms()->……(); + * ``` + */ readonly class CmsUtils { /** @@ -24,15 +33,19 @@ public function __construct( public function getDefaultCategoryLayout(): ?CmsPageEntity { - $criteria = (new Criteria()) - ->addFilter(new EqualsFilter('locked', '1')) - ->addFilter(new EqualsAnyFilter('translations.name', ['Default category layout', 'Default listing layout'])) - ->setLimit(1); + return once(function (): ?CmsPageEntity { + $criteria = (new Criteria()) + ->addFilter(new EqualsFilter('locked', '1')) + ->addFilter(new EqualsAnyFilter('translations.name', ['Default category layout', 'Default listing layout'])) + ->setLimit(1); - $cmsPage = $this->cmsPageRepository - ->search($criteria, Context::createDefaultContext()) - ->first(); + $criteria->setTitle(sprintf('%s::%s()', __CLASS__, __FUNCTION__)); - return $cmsPage instanceof CmsPageEntity ? $cmsPage : null; + $cmsPage = $this->cmsPageRepository + ->search($criteria, Context::createDefaultContext()) + ->first(); + + return $cmsPage instanceof CmsPageEntity ? $cmsPage : null; + }); } } diff --git a/src/Utils/CustomerUtils.php b/src/Utils/CustomerUtils.php deleted file mode 100644 index 678283d..0000000 --- a/src/Utils/CustomerUtils.php +++ /dev/null @@ -1,36 +0,0 @@ - $salutationRepository - */ - public function __construct( - private EntityRepository $salutationRepository, - ) { - } - - public function getNotSpecifiedSalutation(): ?SalutationEntity - { - $criteria = (new Criteria())->addFilter( - new EqualsFilter('salutationKey', 'not_specified'), - )->setLimit(1); - - $salutation = $this->salutationRepository - ->search($criteria, Context::createDefaultContext()) - ->first(); - - return $salutation instanceof SalutationEntity ? $salutation : null; - } -} diff --git a/src/Utils/DatabaseUtils.php b/src/Utils/DatabaseUtils.php index e1a5bb7..8cc8796 100644 --- a/src/Utils/DatabaseUtils.php +++ b/src/Utils/DatabaseUtils.php @@ -8,6 +8,16 @@ use Shopware\Core\Framework\DataAbstractionLayer\DefinitionInstanceRegistry; use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria; +/** + * This class provides utility methods to directly interact with the database. It has build in + * caching to prevent multiple database queries for the same data within one command + * execution / request. + * + * This class is designed to be used through the FixtureHelper, using: + * ```php + * $this->helper->Database()->……(); + * ``` + */ readonly class DatabaseUtils { public function __construct( diff --git a/src/Utils/MediaUtils.php b/src/Utils/MediaUtils.php index 297c016..b72aae9 100644 --- a/src/Utils/MediaUtils.php +++ b/src/Utils/MediaUtils.php @@ -14,6 +14,15 @@ use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria; use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter; +/** + * This class provides utility methods to work with media assets. It has build in caching to prevent + * multiple database queries for the same data within one command execution / request. + * + * This class is designed to be used through the FixtureHelper, using: + * ```php + * $this->helper->Media()->……(); + * ``` + */ readonly class MediaUtils { /** @@ -30,31 +39,41 @@ public function __construct( /** * Copied from "vendor/shopware/core/Content/Media/MediaService.php". + * + * Extended it to include simple cache */ public function getDefaultFolder(string $folderName): ?MediaFolderEntity { - $criteria = (new Criteria()) - ->addFilter(new EqualsFilter('media_folder.defaultFolder.entity', $folderName)) - ->addAssociation('defaultFolder') - ->setLimit(1); + return once(function () use ($folderName): ?MediaFolderEntity { + $criteria = (new Criteria()) + ->addFilter(new EqualsFilter('media_folder.defaultFolder.entity', $folderName)) + ->addAssociation('defaultFolder') + ->setLimit(1); - $mediaFolder = $this->mediaFolderRepository - ->search($criteria, Context::createDefaultContext()) - ->first(); + $criteria->setTitle(sprintf('%s::%s()', __CLASS__, __FUNCTION__)); - return $mediaFolder instanceof MediaFolderEntity ? $mediaFolder : null; + $mediaFolder = $this->mediaFolderRepository + ->search($criteria, Context::createDefaultContext()) + ->first(); + + return $mediaFolder instanceof MediaFolderEntity ? $mediaFolder : null; + }); } + /** + * "Upload" a file within shopware. It takes a real file path ($filename) and uploads it as a full media. + */ public function upload(string $mediaId, string $folderId, string $filename, string $extension, string $contentType): void { $ctx = Context::createDefaultContext(); - $this->mediaRepository->upsert([ + $this->mediaRepository->upsert( [ - 'id' => $mediaId, - 'mediaFolderId' => $folderId, + [ + 'id' => $mediaId, + 'mediaFolderId' => $folderId, + ], ], - ], $ctx, ); diff --git a/src/Utils/PaymentMethodUtils.php b/src/Utils/PaymentMethodUtils.php index e980f07..20dbf15 100644 --- a/src/Utils/PaymentMethodUtils.php +++ b/src/Utils/PaymentMethodUtils.php @@ -12,6 +12,15 @@ use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria; use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter; +/** + * This class provides utility methods to work with payment methods. It has build in caching to prevent + * multiple database queries for the same data within one command execution / request. + * + * This class is designed to be used through the FixtureHelper, using: + * ```php + * $this->helper->PaymentMethod()->……(); + * ``` + */ readonly class PaymentMethodUtils { /** @@ -22,16 +31,23 @@ public function __construct( ) { } + /** + * Return the default invoice payment method of shopware. + */ public function getInvoicePaymentMethod(): ?PaymentMethodEntity { - $criteria = (new Criteria())->addFilter( - new EqualsFilter('handlerIdentifier', InvoicePayment::class), - )->setLimit(1); + return once(function (): ?PaymentMethodEntity { + $criteria = (new Criteria())->addFilter( + new EqualsFilter('handlerIdentifier', InvoicePayment::class), + )->setLimit(1); + + $criteria->setTitle(sprintf('%s::%s()', __CLASS__, __FUNCTION__)); - $paymentMethod = $this->paymentMethodRepository - ->search($criteria, Context::createDefaultContext()) - ->first(); + $paymentMethod = $this->paymentMethodRepository + ->search($criteria, Context::createDefaultContext()) + ->first(); - return $paymentMethod instanceof PaymentMethodEntity ? $paymentMethod : null; + return $paymentMethod instanceof PaymentMethodEntity ? $paymentMethod : null; + }); } } diff --git a/src/Utils/SalesChannelUtils.php b/src/Utils/SalesChannelUtils.php index 89f6086..6d3bddc 100644 --- a/src/Utils/SalesChannelUtils.php +++ b/src/Utils/SalesChannelUtils.php @@ -24,6 +24,15 @@ use Shopware\Core\System\Tax\TaxCollection; use Shopware\Core\System\Tax\TaxEntity; +/** + * This class provides utility methods to work with sales channels. It has build in caching to prevent + * multiple database queries for the same data within one command execution / request. + * + * This class is designed to be used through the FixtureHelper, using: + * ```php + * $this->helper->SalesChannel()->……(); + * ``` + */ readonly class SalesChannelUtils { /** @@ -46,16 +55,25 @@ public function __construct( ) { } + /** + * Return the first sales channel with type "Storefront" or null if non was found. + */ public function getStorefrontSalesChannel(): ?SalesChannelEntity { return $this->getSalesChannelByType(Defaults::SALES_CHANNEL_TYPE_STOREFRONT); } + /** + * Return the first sales channel with type "headless" or null if non was found. + */ public function getHeadlessSalesChannel(): ?SalesChannelEntity { return $this->getSalesChannelByType(Defaults::SALES_CHANNEL_TYPE_API); } + /** + * Return the first sales channel with type "Product Comparison" or null if non was found. + */ public function getProductComparisonSalesChannel(): ?SalesChannelEntity { return $this->getSalesChannelByType(Defaults::SALES_CHANNEL_TYPE_PRODUCT_COMPARISON); @@ -63,17 +81,22 @@ public function getProductComparisonSalesChannel(): ?SalesChannelEntity public function getSalesChannelByType(string $salesChannelType): ?SalesChannelEntity { - $criteria = (new Criteria()) - ->addFilter(new EqualsFilter('typeId', $salesChannelType)) - ->setLimit(1); + return once(function () use ($salesChannelType): ?SalesChannelEntity { + $criteria = (new Criteria()) + ->addFilter(new EqualsFilter('typeId', $salesChannelType)) + ->setLimit(1); - $salesChannel = $this->salesChannelRepository - ->search($criteria, Context::createDefaultContext()) - ->first(); + $criteria->setTitle(sprintf('%s::%s()', __CLASS__, __FUNCTION__)); + + $salesChannel = $this->salesChannelRepository + ->search($criteria, Context::createDefaultContext()) + ->first(); - return $salesChannel instanceof SalesChannelEntity ? $salesChannel : null; + return $salesChannel instanceof SalesChannelEntity ? $salesChannel : null; + }); } + // TODO: Move to CurrencyUtils public function getCurrencyEuro(): ?CurrencyEntity { $criteria = (new Criteria()) @@ -87,6 +110,7 @@ public function getCurrencyEuro(): ?CurrencyEntity return $currency instanceof CurrencyEntity ? $currency : null; } + // TODO: Move to LanguageAndLocaleUtils public function getLanguage(string $languageName): ?LanguageEntity { $criteria = (new Criteria())->addFilter( @@ -100,6 +124,7 @@ public function getLanguage(string $languageName): ?LanguageEntity return $language instanceof LanguageEntity ? $language : null; } + // TODO: Move to LanguageAndLocaleUtils public function getLocale(string $code): ?LocaleEntity { $criteria = (new Criteria())->addFilter( @@ -113,6 +138,7 @@ public function getLocale(string $code): ?LocaleEntity return $locale instanceof LocaleEntity ? $locale : null; } + // TODO: Move to LanguageAndLocaleUtils public function getCountry(string $countryIso): ?CountryEntity { $criteria = (new Criteria())->addFilter( @@ -120,12 +146,15 @@ public function getCountry(string $countryIso): ?CountryEntity )->setLimit(1); $country = $this->countryRepository - ->search($criteria, Context::createDefaultContext(), + ->search( + $criteria, + Context::createDefaultContext(), )->first(); return $country instanceof CountryEntity ? $country : null; } + // TODO: Move to LanguageAndLocaleUtils public function getSnippetSet(string $countryCodeIso): ?SnippetSetEntity { $criteria = (new Criteria())->addFilter( @@ -139,6 +168,7 @@ public function getSnippetSet(string $countryCodeIso): ?SnippetSetEntity return $snippetSet instanceof SnippetSetEntity ? $snippetSet : null; } + // TODO: Move to TaxUtils public function getTax19(): ?TaxEntity { $criteria = (new Criteria()) @@ -152,6 +182,7 @@ public function getTax19(): ?TaxEntity return $tax instanceof TaxEntity ? $tax : null; } + // TODO: Move to TaxUtils public function getTax(float $taxValue): ?TaxEntity { $criteria = (new Criteria()) diff --git a/src/Utils/SalutationUtils.php b/src/Utils/SalutationUtils.php new file mode 100644 index 0000000..aab9d00 --- /dev/null +++ b/src/Utils/SalutationUtils.php @@ -0,0 +1,49 @@ +helper->Salutation()->……(); + * ``` + */ +readonly class SalutationUtils +{ + /** + * @param EntityRepository $salutationRepository + */ + public function __construct( + private EntityRepository $salutationRepository, + ) { + } + + public function getNotSpecifiedSalutation(): ?SalutationEntity + { + return once(function (): ?SalutationEntity { + $criteria = (new Criteria())->addFilter( + new EqualsFilter('salutationKey', 'not_specified'), + )->setLimit(1); + + $criteria->setTitle(sprintf('%s::%s()', __CLASS__, __FUNCTION__)); + + $salutation = $this->salutationRepository + ->search($criteria, Context::createDefaultContext()) + ->first(); + + return $salutation instanceof SalutationEntity ? $salutation : null; + }); + } +} diff --git a/src/Utils/ShippingMethodUtils.php b/src/Utils/ShippingMethodUtils.php index 0ee6b19..0f18c8e 100644 --- a/src/Utils/ShippingMethodUtils.php +++ b/src/Utils/ShippingMethodUtils.php @@ -11,6 +11,15 @@ use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria; use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter; +/** + * This class provides utility methods to work with shipping methods. It has build in caching + * to prevent multiple database queries for the same data within one command execution / request. + * + * This class is designed to be used through the FixtureHelper, using: + * ```php + * $this->helper->ShippingMethod()->……(); + * ``` + */ readonly class ShippingMethodUtils { /** @@ -21,16 +30,23 @@ public function __construct( ) { } + /** + * Returns the first active shipping method or null if none exists. + */ public function getFirstShippingMethod(): ?ShippingMethodEntity { - $criteria = (new Criteria())->addFilter( - new EqualsFilter('active', '1'), - )->setLimit(1); + return once(function (): ?ShippingMethodEntity { + $criteria = (new Criteria())->addFilter( + new EqualsFilter('active', '1'), + )->setLimit(1); + + $criteria->setTitle(sprintf('%s::%s()', __CLASS__, __FUNCTION__)); - $shippingMethod = $this->shippingMethodRepository - ->search($criteria, Context::createDefaultContext()) - ->first(); + $shippingMethod = $this->shippingMethodRepository + ->search($criteria, Context::createDefaultContext()) + ->first(); - return $shippingMethod instanceof ShippingMethodEntity ? $shippingMethod : null; + return $shippingMethod instanceof ShippingMethodEntity ? $shippingMethod : null; + }); } }