├── .editorconfig ├── .github ├── oxid-esales │ └── graphql-storefront.yaml └── workflows │ ├── dispatch_module.yaml │ ├── schedule.yaml │ ├── schema_trigger.yaml │ └── trigger.yaml ├── .gitignore ├── .gitmodules ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── assets └── logo.png ├── composer.json ├── dependencies.yaml ├── deptrac.yaml ├── metadata.php ├── migration ├── data │ ├── .gitkeep │ ├── Version20201006091606.php │ └── Version20201006152500.php └── migrations.yml ├── recipes └── setup-development.sh ├── services.yaml ├── sonar-project.properties ├── src ├── Action │ ├── Controller │ │ └── Action.php │ ├── DataType │ │ ├── Action.php │ │ └── ActionFilterList.php │ ├── Exception │ │ └── ActionNotFound.php │ └── Service │ │ └── Action.php ├── Address │ ├── Controller │ │ ├── DeliveryAddress.php │ │ └── InvoiceAddress.php │ ├── DataType │ │ ├── AbstractAddress.php │ │ ├── AddressFilterList.php │ │ ├── DeliveryAddress.php │ │ ├── DeliveryProvider.php │ │ └── InvoiceAddress.php │ ├── Exception │ │ ├── AddressMissingFields.php │ │ └── DeliveryAddressNotFound.php │ ├── Infrastructure │ │ ├── DeliveryAddressFactory.php │ │ └── InvoiceAddressFactory.php │ └── Service │ │ ├── AddressRelations.php │ │ ├── DeliveryAddress.php │ │ ├── DeliveryAddressInput.php │ │ ├── DeliveryAddressRelations.php │ │ ├── InvoiceAddress.php │ │ ├── InvoiceAddressInput.php │ │ └── InvoiceAddressRelations.php ├── Attribute │ ├── Controller │ │ └── Attribute.php │ ├── DataType │ │ ├── Attribute.php │ │ └── AttributeFilterList.php │ ├── Exception │ │ └── AttributeNotFound.php │ └── Service │ │ └── Attribute.php ├── Banner │ ├── Controller │ │ └── Banner.php │ ├── DataType │ │ └── Banner.php │ ├── Exception │ │ └── BannerNotFound.php │ ├── Infrastructure │ │ └── Banner.php │ └── Service │ │ ├── Banner.php │ │ └── RelationService.php ├── Basket │ ├── Controller │ │ └── Basket.php │ ├── DataType │ │ ├── AbstractBasket.php │ │ ├── Basket.php │ │ ├── BasketByTitleAndUserIdFilterList.php │ │ ├── BasketCost.php │ │ ├── BasketItem.php │ │ ├── BasketItemFilterList.php │ │ ├── BasketOwner.php │ │ ├── BasketProductBruttoSum.php │ │ ├── BasketProductVats.php │ │ ├── BasketVoucherFilterList.php │ │ ├── PublicBasket.php │ │ └── Sorting.php │ ├── Event │ │ ├── AbstractItemEvent.php │ │ ├── AfterAddItem.php │ │ ├── AfterRemoveItem.php │ │ ├── BasketAuthorization.php │ │ ├── BasketModifyInterface.php │ │ ├── BeforeAddItem.php │ │ ├── BeforeBasketDeliveryMethods.php │ │ ├── BeforeBasketModify.php │ │ ├── BeforeBasketPayments.php │ │ ├── BeforeBasketRemove.php │ │ ├── BeforeBasketRemoveOnPlaceOrder.php │ │ ├── BeforePlaceOrder.php │ │ └── BeforeRemoveItem.php │ ├── Exception │ │ ├── BasketAccessForbidden.php │ │ ├── BasketExists.php │ │ ├── BasketForUserNotFound.php │ │ ├── BasketItemAmountLimitedStock.php │ │ ├── BasketItemNotFound.php │ │ ├── BasketNotFound.php │ │ └── PlaceOrder.php │ ├── Infrastructure │ │ ├── Basket.php │ │ ├── BasketCost.php │ │ ├── BasketFactory.php │ │ ├── BasketProduct.php │ │ ├── Payment.php │ │ └── Repository.php │ ├── Service │ │ ├── Basket.php │ │ ├── BasketCostRelations.php │ │ ├── BasketFinder.php │ │ ├── BasketInput.php │ │ ├── BasketItem.php │ │ ├── BasketItemRelationService.php │ │ ├── BasketPaymentService.php │ │ ├── BasketProductBruttoSumRelations.php │ │ ├── BasketRelationService.php │ │ ├── BasketVoucher.php │ │ ├── PlaceOrder.php │ │ └── PublicBasketRelationService.php │ └── Subscriber │ │ └── BasketAuthorization.php ├── Category │ ├── Controller │ │ └── Category.php │ ├── DataType │ │ ├── Category.php │ │ ├── CategoryAttribute.php │ │ ├── CategoryFilterList.php │ │ ├── CategoryIDFilter.php │ │ └── Sorting.php │ ├── Exception │ │ └── CategoryNotFound.php │ ├── Infrastructure │ │ └── Category.php │ └── Service │ │ ├── Category.php │ │ └── RelationService.php ├── Contact │ ├── Controller │ │ └── Contact.php │ ├── DataType │ │ └── ContactRequest.php │ ├── Exception │ │ └── ContactRequestFieldsValidationError.php │ ├── Infrastructure │ │ └── Contact.php │ └── Service │ │ ├── ContactInfrastructureAwareService.php │ │ ├── ContactRequest.php │ │ └── ContactRequestInput.php ├── Content │ ├── Controller │ │ └── Content.php │ ├── DataType │ │ ├── Content.php │ │ └── ContentFilterList.php │ ├── Exception │ │ └── ContentNotFound.php │ └── Service │ │ ├── Content.php │ │ └── RelationService.php ├── Country │ ├── Controller │ │ └── Country.php │ ├── DataType │ │ ├── Country.php │ │ ├── CountryFilterList.php │ │ ├── CountrySorting.php │ │ ├── State.php │ │ ├── StateFilterList.php │ │ └── StateSorting.php │ ├── Exception │ │ ├── CountryNotFound.php │ │ └── StateNotFound.php │ └── Service │ │ ├── Country.php │ │ ├── RelationService.php │ │ └── State.php ├── Currency │ ├── Controller │ │ └── Currency.php │ ├── DataType │ │ └── Currency.php │ ├── Exception │ │ └── CurrencyNotFound.php │ ├── Infrastructure │ │ └── Repository.php │ └── Service │ │ └── Currency.php ├── Customer │ ├── Controller │ │ ├── Customer.php │ │ └── Password.php │ ├── DataType │ │ └── Customer.php │ ├── Exception │ │ ├── CustomerEmailNotFound.php │ │ ├── CustomerExists.php │ │ ├── CustomerNotDeletable.php │ │ ├── CustomerNotFound.php │ │ ├── CustomerNotFoundByUpdateHash.php │ │ ├── InvalidEmail.php │ │ ├── PasswordMismatch.php │ │ └── PasswordValidationException.php │ ├── Infrastructure │ │ ├── Customer.php │ │ ├── CustomerRegisterFactory.php │ │ ├── Password.php │ │ ├── PasswordInterface.php │ │ ├── Repository.php │ │ └── RepositoryInterface.php │ ├── Service │ │ ├── Customer.php │ │ ├── CustomerInterface.php │ │ ├── CustomerRegisterInput.php │ │ ├── Password.php │ │ ├── PasswordInterface.php │ │ └── RelationService.php │ └── services.yaml ├── DeliveryMethod │ ├── DataType │ │ ├── BasketDeliveryMethod.php │ │ └── DeliveryMethod.php │ ├── Exception │ │ ├── DeliveryMethodNotFound.php │ │ ├── MissingDeliveryMethod.php │ │ └── UnavailableDeliveryMethod.php │ └── Service │ │ ├── BasketDeliveryMethodRelationService.php │ │ └── DeliveryMethod.php ├── File │ ├── DataType │ │ └── File.php │ ├── Exception │ │ └── FileNotFound.php │ └── Service │ │ ├── File.php │ │ └── FileRelations.php ├── Framework │ └── ModuleSetup.php ├── Link │ ├── Controller │ │ └── Link.php │ ├── DataType │ │ ├── Link.php │ │ └── LinkFilterList.php │ ├── Exception │ │ └── LinkNotFound.php │ └── Service │ │ └── Link.php ├── Manufacturer │ ├── Controller │ │ └── Manufacturer.php │ ├── DataType │ │ ├── Manufacturer.php │ │ ├── ManufacturerFilterList.php │ │ ├── ManufacturerImage.php │ │ └── Sorting.php │ ├── Exception │ │ └── ManufacturerNotFound.php │ └── Service │ │ ├── Manufacturer.php │ │ └── RelationService.php ├── NewsletterStatus │ ├── Controller │ │ └── NewsletterStatus.php │ ├── DataType │ │ ├── NewsletterStatus.php │ │ ├── NewsletterStatusSubscribe.php │ │ ├── NewsletterStatusUnsubscribe.php │ │ └── Subscriber.php │ ├── Exception │ │ ├── NewsletterStatusForUserNotFound.php │ │ ├── NewsletterStatusNotFound.php │ │ └── SubscriberNotFound.php │ ├── Infrastructure │ │ ├── NewsletterStatus.php │ │ └── Repository.php │ └── Service │ │ ├── AbstractNewsletterInput.php │ │ ├── NewsletterOptInInput.php │ │ ├── NewsletterStatus.php │ │ ├── NewsletterSubscribeInput.php │ │ ├── NewsletterUnsubscribeInput.php │ │ └── Subscriber.php ├── Order │ ├── DataType │ │ ├── AbstractOrderDataType.php │ │ ├── Order.php │ │ ├── OrderCost.php │ │ ├── OrderDelivery.php │ │ ├── OrderDeliveryAddress.php │ │ ├── OrderFile.php │ │ ├── OrderInvoiceAddress.php │ │ ├── OrderItem.php │ │ ├── OrderPayment.php │ │ ├── OrderPaymentValue.php │ │ ├── OrderProductBruttoSum.php │ │ └── OrderProductVats.php │ ├── Infrastructure │ │ ├── Order.php │ │ ├── OrderCost.php │ │ ├── OrderDelivery.php │ │ ├── OrderPayment.php │ │ └── OrderProduct.php │ └── Service │ │ ├── OrderCostRelations.php │ │ ├── OrderDeliveryAddressRelations.php │ │ ├── OrderDeliveryRelations.php │ │ ├── OrderFileRelations.php │ │ ├── OrderInvoiceAddressRelations.php │ │ ├── OrderItemRelations.php │ │ ├── OrderPaymentRelations.php │ │ ├── OrderProductGrossRelations.php │ │ └── OrderRelations.php ├── Payment │ ├── DataType │ │ ├── BasketPayment.php │ │ └── Payment.php │ ├── Exception │ │ ├── MissingPayment.php │ │ ├── PaymentNotFound.php │ │ ├── PaymentValidationFailed.php │ │ └── UnavailablePayment.php │ └── Service │ │ └── Payment.php ├── Product │ ├── Controller │ │ └── Product.php │ ├── DataType │ │ ├── Product.php │ │ ├── ProductAttribute.php │ │ ├── ProductDeliveryTime.php │ │ ├── ProductDimensions.php │ │ ├── ProductFilterList.php │ │ ├── ProductImage.php │ │ ├── ProductImageGallery.php │ │ ├── ProductRating.php │ │ ├── ProductRatingFilterList.php │ │ ├── ProductScalePrice.php │ │ ├── ProductStock.php │ │ ├── ProductUnit.php │ │ ├── Selection.php │ │ ├── SelectionList.php │ │ ├── Sorting.php │ │ ├── VariantSelectionList.php │ │ └── VariantSelections.php │ ├── Exception │ │ ├── ProductNotFound.php │ │ ├── ProductNotOrderable.php │ │ └── ProductVariant.php │ ├── Infrastructure │ │ └── Product.php │ └── Service │ │ ├── Product.php │ │ ├── ProductRatingRelationService.php │ │ └── RelationService.php ├── Promotion │ ├── Controller │ │ └── Promotion.php │ ├── DataType │ │ └── Promotion.php │ ├── Exception │ │ └── PromotionNotFound.php │ ├── Infrastructure │ │ └── Promotion.php │ └── Service │ │ └── Promotion.php ├── Review │ ├── Controller │ │ └── Review.php │ ├── DataType │ │ ├── Review.php │ │ ├── ReviewFilterList.php │ │ └── Reviewer.php │ ├── Exception │ │ ├── RatingOutOfBounds.php │ │ ├── ReviewAlreadyExists.php │ │ ├── ReviewInputInvalid.php │ │ ├── ReviewNotFound.php │ │ └── ReviewerNotFound.php │ ├── Infrastructure │ │ ├── Repository.php │ │ ├── Review.php │ │ └── ReviewFactory.php │ └── Service │ │ ├── ActivityService.php │ │ ├── RelationService.php │ │ ├── Review.php │ │ ├── ReviewInput.php │ │ └── Reviewer.php ├── Shared │ ├── DataType │ │ ├── FilterList.php │ │ ├── Language.php │ │ ├── Price.php │ │ ├── ProductVat.php │ │ ├── ProductVatsInterface.php │ │ └── Seo.php │ ├── Exception │ │ ├── GraphQLServiceNotFound.php │ │ └── Repository.php │ ├── Infrastructure │ │ ├── AbstractCost.php │ │ ├── ActiveStatus.php │ │ ├── Basket.php │ │ ├── LanguageInfrastructure.php │ │ ├── ListConfiguration.php │ │ ├── OxNewFactory.php │ │ ├── OxNewFactoryInterface.php │ │ ├── Repository.php │ │ └── RepositoryInterface.php │ ├── Service │ │ ├── AbstractActiveFilterService.php │ │ ├── LanguageRelationService.php │ │ ├── NamespaceMapper.php │ │ ├── PermissionProvider.php │ │ └── PriceRelationService.php │ ├── Shop │ │ ├── Basket.php │ │ ├── Language.php │ │ ├── User.php │ │ └── Voucher.php │ └── Subscriber │ │ └── BeforeModuleDeactivation.php ├── Translation │ ├── Controller │ │ └── Translation.php │ ├── DataType │ │ └── Translation.php │ ├── Exception │ │ └── TranslationNotFound.php │ ├── Infrastructure │ │ └── Translation.php │ └── Service │ │ └── Translation.php ├── Vendor │ ├── Controller │ │ └── Vendor.php │ ├── DataType │ │ ├── Sorting.php │ │ ├── Vendor.php │ │ └── VendorFilterList.php │ ├── Exception │ │ └── VendorNotFound.php │ └── Service │ │ ├── RelationService.php │ │ └── Vendor.php ├── Voucher │ ├── DataType │ │ ├── Sorting.php │ │ ├── Voucher.php │ │ └── VoucherSeries.php │ ├── Exception │ │ ├── SeriesNotConfigured.php │ │ ├── SeriesNotFound.php │ │ ├── VoucherNotApplied.php │ │ ├── VoucherNotFound.php │ │ ├── VoucherNotUsable.php │ │ └── VoucherNumberNotFound.php │ ├── Infrastructure │ │ ├── Repository.php │ │ └── Voucher.php │ └── Service │ │ ├── Voucher.php │ │ ├── VoucherRelationService.php │ │ └── VoucherSeries.php └── WishedPrice │ ├── Controller │ └── WishedPrice.php │ ├── DataType │ ├── Inquirer.php │ ├── WishedPrice.php │ └── WishedPriceFilterList.php │ ├── Exception │ ├── InquirerNotFound.php │ ├── NotificationSendFailure.php │ ├── WishedPriceNotFound.php │ └── WishedPriceOutOfBounds.php │ ├── Infrastructure │ ├── PriceFactory.php │ ├── WishedPriceFactory.php │ └── WishedPriceNotification.php │ └── Service │ ├── Inquirer.php │ ├── RelationService.php │ ├── WishedPrice.php │ └── WishedPriceInput.php └── tests ├── Codeception ├── Acceptance.suite.yml ├── Acceptance │ ├── Action │ │ └── ActionMultishopCest.php │ ├── Address │ │ ├── DeliveryAddressCest.php │ │ ├── DeliveryAddressMultishopCest.php │ │ ├── DeliveryAddressRelationsCest.php │ │ ├── DeliveryAddressValidateStateCest.php │ │ ├── InvoiceAddressCest.php │ │ ├── InvoiceAddressMultiShopCest.php │ │ └── InvoiceAddressRelationsCest.php │ ├── Attribute │ │ └── AttributeMultishopCest.php │ ├── Banner │ │ └── BannerMultishopCest.php │ ├── BaseCest.php │ ├── Basket │ │ ├── BasketAddItemCest.php │ │ ├── BasketAddItemMultishopCest.php │ │ ├── BasketBaseCest.php │ │ ├── BasketCest.php │ │ ├── BasketDeliveryAddressCest.php │ │ ├── BasketDeliveryAddressMultishopCest.php │ │ ├── BasketDeliveryMethodCest.php │ │ ├── BasketMakePrivateCest.php │ │ ├── BasketMakePublicCest.php │ │ ├── BasketMultishopCest.php │ │ ├── BasketOwnerRelationCest.php │ │ ├── BasketPaymentCest.php │ │ ├── BasketRemoveCest.php │ │ ├── BasketRemoveItemCest.php │ │ ├── BasketRemoveMultishopCest.php │ │ ├── BasketSetDeliveryMethodMutationCest.php │ │ ├── BasketSetPaymentMutationCest.php │ │ ├── BasketVoucherCest.php │ │ ├── BasketsCest.php │ │ ├── BasketsMultishopCest.php │ │ ├── PlaceOrderBaseCest.php │ │ ├── PlaceOrderCest.php │ │ └── PlaceOrderWithVouchersCest.php │ ├── Category │ │ └── CategoryCest.php │ ├── Contact │ │ └── ContactCest.php │ ├── Content │ │ ├── ContentCest.php │ │ └── ContentMultishopCest.php │ ├── Country │ │ ├── CountryCest.php │ │ └── CountryEnterpriseCest.php │ ├── Currency │ │ └── CurrencyMultishopCest.php │ ├── Customer │ │ ├── CustomerBaseCest.php │ │ ├── CustomerCest.php │ │ ├── CustomerDeleteCest.php │ │ ├── CustomerDeleteMultiShopCest.php │ │ ├── CustomerMultiShopCest.php │ │ ├── PasswordAuthorizedCustomerCest.php │ │ ├── PasswordCest.php │ │ └── RelationServiceCest.php │ ├── Manufacturer │ │ └── ManufacturerMultishopCest.php │ ├── MultishopBaseCest.php │ ├── NewsletterStatus │ │ ├── NewsletterStatusCest.php │ │ ├── NewsletterStatusMultiShopCest.php │ │ ├── NewsletterStatusSubscribeCest.php │ │ └── NewsletterStatusSubscribeMultiShopCest.php │ ├── NoSessionUsageCest.php │ ├── NoSessionUsageMultishopCest.php │ ├── Order │ │ ├── CustomerOrderFilesCest.php │ │ ├── CustomerOrderFilesMultiShopCest.php │ │ ├── CustomerOrderHistoryCest.php │ │ ├── CustomerOrderHistoryMultiShopCest.php │ │ ├── CustomerOrderItemsCest.php │ │ ├── CustomerOrderItemsMultiShopCest.php │ │ ├── CustomerOrderPaymentCest.php │ │ └── CustomerOrderPaymentMultiShopCest.php │ ├── Product │ │ ├── ProductMultishopCest.php │ │ ├── ProductRelationsCest.php │ │ └── VariantSelectionsCest.php │ ├── Promotion │ │ ├── PromotionCest.php │ │ └── PromotionMultishopCest.php │ ├── Review │ │ ├── ReviewCest.php │ │ └── ReviewMultiShopCest.php │ ├── Translation │ │ └── TranslationCest.php │ ├── Vendor │ │ └── VendorMultishopCest.php │ ├── Voucher │ │ ├── VoucherCest.php │ │ └── VoucherMultiShopCest.php │ ├── WishedPrice │ │ ├── WishedPriceCest.php │ │ └── WishedPriceMultiShopCest.php │ └── _bootstrap.php ├── Config │ └── params.php ├── Data │ └── testdata.sql ├── Support │ ├── AcceptanceTester.php │ └── _generated │ │ └── .gitignore └── _output │ └── .gitignore ├── Fixtures ├── integrationtest_ce.sql ├── integrationtest_ee.sql ├── out │ └── pictures │ │ └── master │ │ └── manufacturer │ │ ├── icon │ │ └── oreilly_1_alt_icon.png │ │ ├── picture │ │ └── oreilly_1_picture.png │ │ ├── promo_icon │ │ └── oreilly_1_promo.png │ │ └── thumb │ │ └── oreilly_1_thumbnail.png ├── remove_subshop.sql ├── testdemodata_ce.sql └── testdemodata_ee.sql ├── Integration ├── Address │ ├── DeliveryAddressTest.php │ ├── InvoiceAddressModelStub.php │ └── InvoiceAddressTest.php ├── BaseTestCase.php ├── Basket │ ├── BasketRepositoryTest.php │ └── ShopBasketTest.php ├── Contact │ └── Infrastructure │ │ └── ContactTest.php ├── Controller │ ├── ActionMultiLanguageTest.php │ ├── ActionTest.php │ ├── AttributeTest.php │ ├── BannerMultiLanguageTest.php │ ├── BannerTest.php │ ├── ContentMultiLanguageTest.php │ ├── ContentTest.php │ ├── CurrencyTest.php │ ├── ManufacturerMultiLanguageTest.php │ ├── ManufacturerTest.php │ ├── ManufacturerWithTokenTest.php │ ├── ProductMultiLanguageTest.php │ ├── ProductTest.php │ ├── ProductWithTokenTest.php │ ├── PromotionMultiLanguageTest.php │ ├── ReviewMultiLanguageTest.php │ ├── ReviewTest.php │ ├── VendorMultiLanguageTest.php │ └── VendorTest.php ├── Customer │ ├── Controller │ │ └── PasswordControllerTest.php │ ├── DependencyInjectionTest.php │ ├── Infrastructure │ │ └── RepositoryTest.php │ └── Service │ │ └── CustomerServiceTest.php ├── DataType │ ├── CategoryAttributeTest.php │ ├── ContentRelationServiceTest.php │ ├── CurrencyTest.php │ ├── ProductAttributeTest.php │ ├── ProductImageGalleryTest.php │ ├── ProductRelationServiceTest.php │ └── SeoTest.php ├── DemoData.php ├── EnterpriseTestCase.php ├── ImageUrlAssertionTrait.php ├── MultiLanguageTestCase.php ├── Service │ ├── BasketServiceTest.php │ └── PriceRelationTest.php └── Shared │ ├── Infrastructure │ └── RepositoryTest.php │ └── Subscriber │ └── BeforeModuleDeactivationTest.php ├── PhpMd ├── exclude-ruleset.xml └── standard.xml ├── PhpStan ├── phpstan-bootstrap.php ├── phpstan.neon └── stubs │ ├── EshopArticle.stub │ ├── EshopArticleList.stub │ ├── EshopBasket.stub │ ├── EshopDiscount.stub │ ├── EshopRegistry.stub │ ├── EshopUser.stub │ └── EshopVoucher.stub ├── Unit ├── Basket │ └── Event │ │ ├── AbstractItemEventTest.php │ │ ├── AfterAddItemTest.php │ │ ├── AfterRemoveItemTest.php │ │ ├── BasketAuthorizationTest.php │ │ ├── BeforeAddItemTest.php │ │ ├── BeforeBasketDeliveryMethodsTest.php │ │ ├── BeforeBasketModifyTest.php │ │ ├── BeforeBasketPaymentsTest.php │ │ ├── BeforeBasketRemoveOnPlaceOrderTest.php │ │ ├── BeforePlaceOrderTest.php │ │ └── BeforeRemoveItemTest.php ├── Controller │ └── CurrencyTest.php ├── Country │ └── DataType │ │ ├── StateModelStub.php │ │ └── StateTest.php ├── Customer │ ├── Controller │ │ └── PasswordControllerTest.php │ ├── Exception │ │ └── ExceptionsTest.php │ ├── Infrastructure │ │ ├── PasswordInfrastructureTest.php │ │ └── RepositoryTest.php │ └── Service │ │ └── PasswordServiceTest.php ├── DataType │ ├── BannerTest.php │ ├── CategoryAttributeTest.php │ ├── CategoryStub.php │ ├── CategoryTest.php │ ├── NoEshopUrlContractModelStub.php │ ├── ProductFilterListTest.php │ ├── ProductImageTest.php │ ├── ProductRelationServiceTest.php │ ├── ProductScalePriceModelStub.php │ ├── ProductScalePriceTest.php │ └── SeoTest.php ├── Delivery │ └── DataType │ │ ├── DeliveryAddressModelStub.php │ │ └── DeliveryAddressTest.php ├── Exception │ ├── AttributeNotFoundTest.php │ ├── CategoryNotFoundTest.php │ ├── ManufacturerNotFoundTest.php │ └── VendorNotFoundTest.php ├── Shared │ ├── Infrastructure │ │ └── RepositoryTest.php │ └── Service │ │ └── NamespaceMapperTest.php └── travis_dummy ├── codeception.yml ├── phpcs.xml └── phpunit.xml /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Unix-style newlines with a newline ending every file 7 | [*] 8 | end_of_line = lf 9 | insert_final_newline = true 10 | charset = utf-8 11 | indent_style = space 12 | indent_size = 4 13 | trim_trailing_whitespace = true 14 | 15 | # Unix-style newlines with a newline ending every file 16 | [*.yaml] 17 | indent_size = 2 18 | 19 | # Tab indentation (no size specified) 20 | [Makefile] 21 | indent_style = tab 22 | -------------------------------------------------------------------------------- /.github/workflows/schema_trigger.yaml: -------------------------------------------------------------------------------- 1 | name: Trigger schema workflow 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v4.1.*' 7 | 8 | jobs: 9 | documentation_schema: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Trigger schema generation in documentation 13 | uses: convictional/trigger-workflow-and-wait@v1.6.5 14 | with: 15 | owner: oxid-esales 16 | repo: oxapi-documentation 17 | github_user: ${{ secrets.CI_USER }} 18 | github_token: ${{ secrets.GH_CI_JENKINS_TOKEN }} 19 | workflow_file_name: schema.yaml 20 | ref: "11.0-en" 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .php_cs.cache 3 | tests/.phpunit.result.cache 4 | .deptrac.cache 5 | composer.lock 6 | /vendor/ 7 | tests/reports/ 8 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "recipes/parts"] 2 | path = recipes/parts 3 | url = https://github.com/OXID-eSales/docker-eshop-sdk-recipe-parts 4 | -------------------------------------------------------------------------------- /assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OXID-eSales/graphql-storefront-module/9f37f95b5885a321b5d62b26bb75552b093e40d7/assets/logo.png -------------------------------------------------------------------------------- /dependencies.yaml: -------------------------------------------------------------------------------- 1 | modules: 2 | - oe_graphql_base 3 | -------------------------------------------------------------------------------- /deptrac.yaml: -------------------------------------------------------------------------------- 1 | deptrac: 2 | paths: 3 | - ./src/ 4 | - ./vendor/oxid-esales/oxideshop-ce/source/ 5 | - ./vendor/oxid-esales/oxideshop-unified-namespace-generator/ 6 | layers: 7 | - name: Controller 8 | collectors: 9 | - type: class 10 | value: .*GraphQL.*Controller\\.* 11 | - name: Service 12 | collectors: 13 | - type: class 14 | value: .*GraphQL.*Service\\.* 15 | - name: Infrastructure 16 | collectors: 17 | - type: class 18 | value: .*GraphQL.*Repository\\.* 19 | - type: class 20 | value: .*GraphQL.*Infrastructure\\.* 21 | - name: Core 22 | collectors: 23 | - type: directory 24 | value: .*vendor/oxid-esales/oxideshop-ce/source/.* 25 | - type: directory 26 | value: .*vendor/oxid-esales/oxideshop-unified-namespace-generator/.* 27 | ruleset: 28 | Controller: 29 | - Service 30 | Service: 31 | - Infrastructure 32 | Infrastructure: 33 | - Core 34 | Core: ~ 35 | -------------------------------------------------------------------------------- /metadata.php: -------------------------------------------------------------------------------- 1 | 'oe_graphql_storefront', 18 | 'title' => 'GraphQL Storefront', 19 | 'description' => 'OXID GraphQL Storefront', 20 | 'thumbnail' => 'logo.png', 21 | 'version' => '4.1.0', 22 | 'author' => 'OXID eSales', 23 | 'url' => 'https://github.com/OXID-eSales/graphql-storefront-module', 24 | 'email' => 'info@oxid-esales.com', 25 | 'extend' => [ 26 | \OxidEsales\Eshop\Application\Model\User::class => \OxidEsales\GraphQL\Storefront\Shared\Shop\User::class, 27 | \OxidEsales\Eshop\Application\Model\Basket::class => \OxidEsales\GraphQL\Storefront\Shared\Shop\Basket::class, 28 | \OxidEsales\Eshop\Application\Model\Voucher::class => \OxidEsales\GraphQL\Storefront\Shared\Shop\Voucher::class, 29 | \OxidEsales\Eshop\Core\Language::class => \OxidEsales\GraphQL\Storefront\Shared\Shop\Language::class, 30 | ], 31 | 'controllers' => [ 32 | ], 33 | 'templates' => [ 34 | ], 35 | 'blocks' => [ 36 | ], 37 | 'settings' => [ 38 | ], 39 | ]; 40 | -------------------------------------------------------------------------------- /migration/data/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OXID-eSales/graphql-storefront-module/9f37f95b5885a321b5d62b26bb75552b093e40d7/migration/data/.gitkeep -------------------------------------------------------------------------------- /migration/data/Version20201006091606.php: -------------------------------------------------------------------------------- 1 | addSql("ALTER TABLE `oxvouchers` 20 | ADD COLUMN `OEGQL_BASKETID` char(32) 21 | character set latin1 collate latin1_general_ci NOT NULL DEFAULT '' 22 | COMMENT 'Relation to oxuserbasket';"); 23 | } 24 | 25 | public function down(Schema $schema): void 26 | { 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /migration/data/Version20201006152500.php: -------------------------------------------------------------------------------- 1 | addSql("ALTER TABLE `oxuserbaskets` 20 | ADD COLUMN `OEGQL_PAYMENTID` char(32) 21 | character set latin1 collate latin1_general_ci DEFAULT NULL 22 | COMMENT 'Relation to oxpayments.oxid', 23 | ADD COLUMN `OEGQL_DELADDRESSID` char(32) 24 | character set latin1 collate latin1_general_ci DEFAULT NULL 25 | COMMENT 'Relation to oxaddress.oxid, if empty the invoice address from oxuser table is used', 26 | ADD COLUMN `OEGQL_DELIVERYMETHODID` char(32) 27 | character set latin1 collate latin1_general_ci DEFAULT NULL 28 | COMMENT 'Relation to oxdeliveryset.oxid';"); 29 | } 30 | 31 | public function down(Schema $schema): void 32 | { 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /migration/migrations.yml: -------------------------------------------------------------------------------- 1 | table_storage: 2 | table_name: oxmigrations_graphql_storefront 3 | migrations_paths: 4 | 'OxidEsales\GraphQL\Storefront\Migrations': data 5 | -------------------------------------------------------------------------------- /sonar-project.properties: -------------------------------------------------------------------------------- 1 | sonar.organization=oxid-esales 2 | sonar.projectKey=OXID-eSales_graphql-storefront-module 3 | sonar.sources=. 4 | sonar.exclusions=tests/**, vendor/** 5 | sonar.php.coverage.reportPaths=./coverage.xml,./clover.xml 6 | -------------------------------------------------------------------------------- /src/Action/Controller/Action.php: -------------------------------------------------------------------------------- 1 | actionService = $actionService; 27 | } 28 | 29 | /** 30 | * @Query() 31 | */ 32 | public function action(ID $actionId): ActionDataType 33 | { 34 | return $this->actionService->action($actionId); 35 | } 36 | 37 | /** 38 | * @Query() 39 | * 40 | * @return ActionDataType[] 41 | */ 42 | public function actions(?ActionFilterList $filter = null): array 43 | { 44 | return $this->actionService->actions( 45 | $filter ?? new ActionFilterList() 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Action/Exception/ActionNotFound.php: -------------------------------------------------------------------------------- 1 | userId = $userId; 23 | parent::__construct(); 24 | } 25 | 26 | public function withUserFilter(StringFilter $user): self 27 | { 28 | $filter = clone $this; 29 | $filter->userId = $user; 30 | 31 | return $filter; 32 | } 33 | 34 | /** 35 | * @return array{ 36 | * oxuserid: ?StringFilter 37 | * } 38 | */ 39 | public function getFilters(): array 40 | { 41 | return [ 42 | 'oxuserid' => $this->userId, 43 | ]; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Address/Exception/AddressMissingFields.php: -------------------------------------------------------------------------------- 1 | attribute = $attribute; 28 | } 29 | 30 | public function getEshopModel(): EshopAttributeModel 31 | { 32 | return $this->attribute; 33 | } 34 | 35 | /** 36 | * @Field() 37 | */ 38 | public function getTitle(): string 39 | { 40 | return (string)($this->attribute->getRawFieldData('oxtitle') ?? $this->attribute->getTitle()); 41 | } 42 | 43 | public static function getModelClass(): string 44 | { 45 | return EshopAttributeModel::class; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Attribute/DataType/AttributeFilterList.php: -------------------------------------------------------------------------------- 1 | title = $title; 25 | $this->active = null; 26 | } 27 | 28 | /** 29 | * @return array{ 30 | * oxtitle: null|StringFilter 31 | * } 32 | */ 33 | public function getFilters(): array 34 | { 35 | return [ 36 | 'oxtitle' => $this->title, 37 | ]; 38 | } 39 | 40 | /** 41 | * @Factory(name="AttributeFilterList", default=true) 42 | */ 43 | public static function createAttributeFilterList( 44 | ?StringFilter $title = null 45 | ): self { 46 | return new self( 47 | $title 48 | ); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Attribute/Exception/AttributeNotFound.php: -------------------------------------------------------------------------------- 1 | bannerService = $bannerService; 28 | } 29 | 30 | /** 31 | * @Query() 32 | * 33 | * @throws BannerNotFound 34 | * @throws InvalidLogin 35 | */ 36 | public function banner(ID $bannerId): BannerDataType 37 | { 38 | return $this->bannerService->banner($bannerId); 39 | } 40 | 41 | /** 42 | * @Query() 43 | * 44 | * @return BannerDataType[] 45 | */ 46 | public function banners(): array 47 | { 48 | return $this->bannerService->banners(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Banner/Exception/BannerNotFound.php: -------------------------------------------------------------------------------- 1 | basket = $basket; 29 | $this->user = $user; 30 | parent::__construct(); 31 | } 32 | 33 | /** 34 | * @return array{ 35 | * oxtitle: ?StringFilter, 36 | * oxuserid: ?IDFilter 37 | * } 38 | */ 39 | public function getFilters(): array 40 | { 41 | return [ 42 | 'oxtitle' => $this->basket, 43 | 'oxuserid' => $this->user, 44 | ]; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Basket/DataType/BasketCost.php: -------------------------------------------------------------------------------- 1 | basket = $basket; 27 | } 28 | 29 | public function getEshopModel(): EshopBasketModel 30 | { 31 | return $this->basket; 32 | } 33 | 34 | /** 35 | * @Field() 36 | */ 37 | public function getVoucher(): float 38 | { 39 | return (float)$this->basket->getVoucherDiscount()->getPrice(); 40 | } 41 | 42 | /** 43 | * @Field() 44 | */ 45 | public function getDiscount(): float 46 | { 47 | return (float)$this->basket->getTotalDiscountSum(); 48 | } 49 | 50 | /** 51 | * @Field() 52 | */ 53 | public function getTotal(): float 54 | { 55 | return (float)$this->basket->getPrice()->getBruttoPrice(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Basket/DataType/BasketItemFilterList.php: -------------------------------------------------------------------------------- 1 | basket = $basket; 24 | parent::__construct(); 25 | } 26 | 27 | /** 28 | * @return array{ 29 | * oxbasketid: ?IDFilter, 30 | * } 31 | */ 32 | public function getFilters(): array 33 | { 34 | return [ 35 | 'oxbasketid' => $this->basket, 36 | ]; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Basket/DataType/BasketProductBruttoSum.php: -------------------------------------------------------------------------------- 1 | basket = $basket; 28 | } 29 | 30 | public function getEshopModel(): EshopBasketModel 31 | { 32 | return $this->basket; 33 | } 34 | 35 | /** 36 | * @Field() 37 | */ 38 | public function getSum(): float 39 | { 40 | return (float)$this->basket->getBruttoSum(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Basket/DataType/BasketProductVats.php: -------------------------------------------------------------------------------- 1 | basket = $basket; 24 | parent::__construct(); 25 | } 26 | 27 | /** 28 | * @return array{ 29 | * oegql_basketid: ?IDFilter, 30 | * } 31 | */ 32 | public function getFilters(): array 33 | { 34 | return [ 35 | 'oegql_basketid' => $this->basket, 36 | ]; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Basket/DataType/PublicBasket.php: -------------------------------------------------------------------------------- 1 | basketId = $basketId; 28 | $this->amount = $amount; 29 | } 30 | 31 | public function getBasketId(): ID 32 | { 33 | return $this->basketId; 34 | } 35 | 36 | public function getAmount(): float 37 | { 38 | return $this->amount; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Basket/Event/AfterAddItem.php: -------------------------------------------------------------------------------- 1 | productId = $productId; 25 | parent::__construct($basketId, $amount); 26 | } 27 | 28 | public function getProductId(): ID 29 | { 30 | return $this->productId; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Basket/Event/AfterRemoveItem.php: -------------------------------------------------------------------------------- 1 | basketItemId = $basketItemId; 25 | parent::__construct($basketId, $amount); 26 | } 27 | 28 | public function getBasketItemId(): ID 29 | { 30 | return $this->basketItemId; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Basket/Event/BasketAuthorization.php: -------------------------------------------------------------------------------- 1 | basket = $basket; 30 | $this->customerId = $customerId; 31 | } 32 | 33 | public function getBasket(): Basket 34 | { 35 | return $this->basket; 36 | } 37 | 38 | public function getCustomerId(): ID 39 | { 40 | return $this->customerId; 41 | } 42 | 43 | public function setAuthorized(bool $authorized): void 44 | { 45 | $this->authorized = $authorized; 46 | } 47 | 48 | public function getAuthorized(): bool 49 | { 50 | return $this->authorized; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Basket/Event/BasketModifyInterface.php: -------------------------------------------------------------------------------- 1 | productId = $productId; 25 | parent::__construct($basketId, $amount); 26 | } 27 | 28 | public function getProductId(): ID 29 | { 30 | return $this->productId; 31 | } 32 | 33 | public function setAmount(float $amount): void 34 | { 35 | $this->amount = $amount; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Basket/Event/BeforeBasketModify.php: -------------------------------------------------------------------------------- 1 | basketId = $basketId; 36 | $this->type = $type; 37 | } 38 | 39 | public function getBasketId(): ID 40 | { 41 | return $this->basketId; 42 | } 43 | 44 | public function getEventType(): int 45 | { 46 | return $this->type; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Basket/Event/BeforeBasketPayments.php: -------------------------------------------------------------------------------- 1 | basketId = $basketId; 31 | } 32 | 33 | public function getBasketId(): ID 34 | { 35 | return $this->basketId; 36 | } 37 | 38 | /** 39 | * @return null|BasketPayment[] 40 | */ 41 | public function getPayments(): ?array 42 | { 43 | return $this->payments; 44 | } 45 | 46 | /** 47 | * @param null|BasketPayment[] $payments 48 | */ 49 | public function setPayments(?array $payments = null): void 50 | { 51 | $this->payments = $payments; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Basket/Event/BeforeBasketRemove.php: -------------------------------------------------------------------------------- 1 | basketId = $basketId; 23 | } 24 | 25 | public function getBasketId(): ID 26 | { 27 | return $this->basketId; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Basket/Event/BeforeBasketRemoveOnPlaceOrder.php: -------------------------------------------------------------------------------- 1 | basketId = $basketId; 29 | } 30 | 31 | public function getBasketId(): ID 32 | { 33 | return $this->basketId; 34 | } 35 | 36 | public function getPreserveBasketAfterOrder(): bool 37 | { 38 | return $this->preserveBasketAfterOrder; 39 | } 40 | 41 | public function setPreserveBasketAfterOrder(bool $preserveBasketAfterOrder = false): void 42 | { 43 | $this->preserveBasketAfterOrder = $preserveBasketAfterOrder; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Basket/Event/BeforePlaceOrder.php: -------------------------------------------------------------------------------- 1 | basketId = $basketId; 26 | } 27 | 28 | public function getBasketId(): ID 29 | { 30 | return $this->basketId; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Basket/Event/BeforeRemoveItem.php: -------------------------------------------------------------------------------- 1 | basketItemId = $basketItemId; 25 | parent::__construct($basketId, $amount); 26 | } 27 | 28 | public function getBasketItemId(): ID 29 | { 30 | return $this->basketItemId; 31 | } 32 | 33 | public function setAmount(float $amount): void 34 | { 35 | $this->amount = $amount; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Basket/Exception/BasketAccessForbidden.php: -------------------------------------------------------------------------------- 1 | assign([ 22 | 'OXUSERID' => $userId, 23 | 'OXTITLE' => $title, 24 | 'OXPUBLIC' => $public, 25 | ]); 26 | 27 | return new BasketDataType($model); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Basket/Infrastructure/BasketProduct.php: -------------------------------------------------------------------------------- 1 | getEshopModel(); 25 | 26 | $productVats = []; 27 | $vats = $basket->getProductVats(false); 28 | 29 | foreach ($vats as $vatRate => $vatPrice) { 30 | $productVats[] = new BasketProductVats((float)$vatRate, (float)$vatPrice); 31 | } 32 | 33 | return $productVats; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Basket/Infrastructure/Payment.php: -------------------------------------------------------------------------------- 1 | getEshopModel(); 23 | 24 | /** @phpstan-ignore-next-line */ 25 | $paymentModel->calculate($basketModel); 26 | 27 | /** @var \OxidEsales\Eshop\Core\Price $price */ 28 | $price = $paymentModel->getPrice(); 29 | 30 | return new Price( 31 | $price 32 | ); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Basket/Service/BasketPaymentService.php: -------------------------------------------------------------------------------- 1 | paymentInfrastructure = $paymentInfrastructure; 30 | } 31 | 32 | /** 33 | * @Field() 34 | */ 35 | public function cost(BasketPayment $basketPayment): Price 36 | { 37 | return $this->paymentInfrastructure->getPaymentCost( 38 | $basketPayment, 39 | $basketPayment->getBasketModel() 40 | ); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Basket/Service/BasketProductBruttoSumRelations.php: -------------------------------------------------------------------------------- 1 | basketProductInfrastructure = $basketProductInfrastructure; 30 | } 31 | 32 | /** 33 | * @Field() 34 | * 35 | * @return BasketProductVats[] 36 | */ 37 | public function getVats(BasketProductBruttoSum $basketProductGross): array 38 | { 39 | return $this->basketProductInfrastructure->getVats($basketProductGross); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Basket/Subscriber/BasketAuthorization.php: -------------------------------------------------------------------------------- 1 | getBasket(); 20 | $userId = $event->getCustomerId(); 21 | 22 | if ($basket->getUserId()->val() === $userId->val()) { 23 | $event->setAuthorized(true); 24 | } 25 | 26 | return $event; 27 | } 28 | 29 | public static function getSubscribedEvents() 30 | { 31 | return [ 32 | 'OxidEsales\GraphQL\Storefront\Basket\Event\BasketAuthorization' => 'handleAuthorization', 33 | ]; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Category/DataType/Sorting.php: -------------------------------------------------------------------------------- 1 | $position, 41 | 'oxtitle' => $title, 42 | ]); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Category/Exception/CategoryNotFound.php: -------------------------------------------------------------------------------- 1 | contactRequestService = $contactRequestService; 27 | } 28 | 29 | /** 30 | * @Mutation() 31 | */ 32 | public function contactRequest(ContactRequest $request): bool 33 | { 34 | return $this->contactRequestService->sendContactRequest($request); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Contact/Exception/ContactRequestFieldsValidationError.php: -------------------------------------------------------------------------------- 1 | contactInfrastructure = $contactInfrastructure; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Contact/Service/ContactRequest.php: -------------------------------------------------------------------------------- 1 | contactInfrastructure->sendRequest($contactRequest); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Contact/Service/ContactRequestInput.php: -------------------------------------------------------------------------------- 1 | contactInfrastructure->assertValidContactRequest($contactRequest); 38 | 39 | return $contactRequest; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Content/Controller/Content.php: -------------------------------------------------------------------------------- 1 | contentService = $contentService; 27 | } 28 | 29 | /** 30 | * @Query() 31 | */ 32 | public function content(ID $contentId): ContentDataType 33 | { 34 | return $this->contentService->content($contentId); 35 | } 36 | 37 | /** 38 | * @Query() 39 | * 40 | * @return ContentDataType[] 41 | */ 42 | public function contents(?ContentFilterList $filter = null): array 43 | { 44 | return $this->contentService->contents( 45 | $filter ?? new ContentFilterList() 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Content/Exception/ContentNotFound.php: -------------------------------------------------------------------------------- 1 | title = $title; 25 | parent::__construct(); 26 | } 27 | 28 | /** 29 | * @return array{ 30 | * oxtitle: ?StringFilter 31 | * } 32 | */ 33 | public function getFilters(): array 34 | { 35 | return [ 36 | 'oxtitle' => $this->title, 37 | ]; 38 | } 39 | 40 | /** 41 | * @Factory(name="CountryFilterList", default=true) 42 | */ 43 | public static function createCountryFilterList( 44 | ?StringFilter $title = null 45 | ): self { 46 | return new self( 47 | $title 48 | ); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Country/DataType/CountrySorting.php: -------------------------------------------------------------------------------- 1 | $position, 41 | 'oxtitle' => $title, 42 | ]); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Country/DataType/StateFilterList.php: -------------------------------------------------------------------------------- 1 | country = $country; 25 | parent::__construct(); 26 | } 27 | 28 | /** 29 | * @return array{ 30 | * oxcountryid : ?IDFilter 31 | * } 32 | */ 33 | public function getFilters(): array 34 | { 35 | return [ 36 | 'oxcountryid' => $this->country, 37 | ]; 38 | } 39 | 40 | /** 41 | * @Factory(name="StateFilterList", default=true) 42 | */ 43 | public static function createStateFilterList( 44 | ?IDFilter $country = null 45 | ): self { 46 | return new self($country); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Country/DataType/StateSorting.php: -------------------------------------------------------------------------------- 1 | $title, 25 | ]); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Country/Exception/CountryNotFound.php: -------------------------------------------------------------------------------- 1 | currencyService = $currencyService; 25 | } 26 | 27 | /** 28 | * If `name` is ommited, gives you the currently active currency 29 | * 30 | * @Query() 31 | */ 32 | public function currency(?string $name = null): CurrencyDataType 33 | { 34 | return $this->currencyService->getByName($name); 35 | } 36 | 37 | /** 38 | * @Query() 39 | * 40 | * @return CurrencyDataType[] 41 | */ 42 | public function currencies(): array 43 | { 44 | return $this->currencyService->getAll(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Currency/Exception/CurrencyNotFound.php: -------------------------------------------------------------------------------- 1 | currencyRepository = $currencyRepository; 25 | } 26 | 27 | /** 28 | * @throws CurrencyNotFound 29 | */ 30 | public function getByName(?string $name = null): CurrencyDataType 31 | { 32 | return $name ? $this->currencyRepository->getByName($name) : $this->currencyRepository->getActiveCurrency(); 33 | } 34 | 35 | /** 36 | * @return CurrencyDataType[] 37 | */ 38 | public function getAll(): array 39 | { 40 | return $this->currencyRepository->getAll(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Customer/Exception/CustomerEmailNotFound.php: -------------------------------------------------------------------------------- 1 | assign([ 23 | 'OXUSERNAME' => $email, 24 | ]); 25 | 26 | if ($birthdate) { 27 | $customerModel->assign([ 28 | 'OXBIRTHDATE' => $birthdate->format('Y-m-d 00:00:00'), 29 | ]); 30 | } 31 | 32 | $customerModel->setPassword($password); 33 | 34 | return new Customer($customerModel); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Customer/Infrastructure/PasswordInterface.php: -------------------------------------------------------------------------------- 1 | basketModel = $basketModel; 34 | 35 | parent::__construct($deliverySetModel, $paymentTypes); 36 | } 37 | 38 | public function getBasketModel(): EshopBasketModel 39 | { 40 | return $this->basketModel; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/DeliveryMethod/Exception/DeliveryMethodNotFound.php: -------------------------------------------------------------------------------- 1 | basketInfrastructure = $basketInfrastructure; 29 | } 30 | 31 | /** 32 | * @Field() 33 | */ 34 | public function cost(BasketDeliveryMethod $basketDeliveryMethod): Price 35 | { 36 | return $this->basketInfrastructure->getDeliveryPrice($basketDeliveryMethod); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/File/Exception/FileNotFound.php: -------------------------------------------------------------------------------- 1 | repository = $repository; 26 | } 27 | 28 | /** 29 | * @throws FileNotFound 30 | */ 31 | public function file(string $id): FileDataType 32 | { 33 | try { 34 | /** @var FileDataType $file */ 35 | $file = $this->repository->getById( 36 | $id, 37 | FileDataType::class 38 | ); 39 | } catch (NotFound $e) { 40 | throw new FileNotFound($id); 41 | } 42 | 43 | return $file; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/File/Service/FileRelations.php: -------------------------------------------------------------------------------- 1 | productService = $productService; 31 | } 32 | 33 | /** 34 | * @Field() 35 | */ 36 | public function getProduct(File $file): Product 37 | { 38 | return $this->productService->product( 39 | new ID($file->productId()) 40 | ); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Framework/ModuleSetup.php: -------------------------------------------------------------------------------- 1 | linkService = $linkService; 27 | } 28 | 29 | /** 30 | * @Query() 31 | */ 32 | public function link(ID $linkId): LinkDataType 33 | { 34 | return $this->linkService->link($linkId); 35 | } 36 | 37 | /** 38 | * @Query() 39 | * 40 | * @return LinkDataType[] 41 | */ 42 | public function links(?LinkFilterList $filter = null): array 43 | { 44 | return $this->linkService->links( 45 | $filter ?? new LinkFilterList() 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Link/Exception/LinkNotFound.php: -------------------------------------------------------------------------------- 1 | $title, 25 | ]); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Manufacturer/Exception/ManufacturerNotFound.php: -------------------------------------------------------------------------------- 1 | legacyService = $legacyService; 23 | } 24 | 25 | protected function assertValidEmail(string $email): bool 26 | { 27 | if (!$this->legacyService->isValidEmail($email)) { 28 | throw InvalidEmail::byString($email); 29 | } 30 | 31 | return true; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/NewsletterStatus/Service/NewsletterUnsubscribeInput.php: -------------------------------------------------------------------------------- 1 | newsletterStatusRepository = $newsletterStatusRepository; 27 | 28 | parent::__construct($legacyService); 29 | } 30 | 31 | /** 32 | * @Factory 33 | */ 34 | public function fromUserInput(string $email): NewsletterStatusUnsubscribe 35 | { 36 | $this->assertValidEmail($email); 37 | 38 | return $this->newsletterStatusRepository->getUnsubscribeByEmail($email); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Order/DataType/AbstractOrderDataType.php: -------------------------------------------------------------------------------- 1 | order = $order; 22 | } 23 | 24 | public function getEshopModel(): EshopOrderModel 25 | { 26 | return $this->order; 27 | } 28 | 29 | public static function getModelClass(): string 30 | { 31 | return EshopOrderModel::class; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Order/DataType/OrderCost.php: -------------------------------------------------------------------------------- 1 | order->getRawFieldData('oxtotalordersum'); 26 | } 27 | 28 | /** 29 | * @Field() 30 | */ 31 | public function getVoucher(): float 32 | { 33 | return (float)$this->order->getRawFieldData('oxvoucherdiscount'); 34 | } 35 | 36 | /** 37 | * @Field() 38 | */ 39 | public function getDiscount(): float 40 | { 41 | return (float)$this->order->getRawFieldData('oxdiscount'); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Order/DataType/OrderDelivery.php: -------------------------------------------------------------------------------- 1 | order->getTrackCode(); 28 | } 29 | 30 | /** 31 | * @Field() 32 | */ 33 | public function getTrackingURL(): string 34 | { 35 | return (string)$this->order->getShipmentTrackingUrl(); 36 | } 37 | 38 | /** 39 | * @Field() 40 | */ 41 | public function getDispatched(): ?DateTimeInterface 42 | { 43 | return DateTimeImmutableFactory::fromString( 44 | (string)$this->order->getRawFieldData('oxsenddate') 45 | ); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Order/DataType/OrderDeliveryAddress.php: -------------------------------------------------------------------------------- 1 | order = $order; 26 | parent::__construct('oxdel'); 27 | } 28 | 29 | public function getEshopModel(): EshopOrderModel 30 | { 31 | return $this->order; 32 | } 33 | 34 | public static function getModelClass(): string 35 | { 36 | return EshopOrderModel::class; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Order/DataType/OrderPaymentValue.php: -------------------------------------------------------------------------------- 1 | paymentValue = $paymentValue; 27 | } 28 | 29 | /** 30 | * @Field() 31 | */ 32 | public function getKey(): string 33 | { 34 | return (string)$this->paymentValue->name; 35 | } 36 | 37 | /** 38 | * @Field() 39 | */ 40 | public function getValue(): string 41 | { 42 | return (string)$this->paymentValue->value; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Order/DataType/OrderProductBruttoSum.php: -------------------------------------------------------------------------------- 1 | order->getRawFieldData('oxtotalbrutsum')); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Order/DataType/OrderProductVats.php: -------------------------------------------------------------------------------- 1 | getEshopModel()->getDelSet(); 22 | 23 | return new DeliveryProvider($deliverySet); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Order/Infrastructure/OrderPayment.php: -------------------------------------------------------------------------------- 1 | getEshopModel(); 24 | 25 | foreach ($payment->getDynValues() as $paymentValue) { 26 | $values[] = new OrderPaymentValue($paymentValue); 27 | } 28 | 29 | return $values; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Order/Infrastructure/OrderProduct.php: -------------------------------------------------------------------------------- 1 | getEshopModel(); 25 | 26 | $productVats = []; 27 | $vats = $order->getProductVats(false); 28 | 29 | foreach ($vats as $vatRate => $vatPrice) { 30 | $productVats[] = new OrderProductVats((float)$vatRate, (float)$vatPrice); 31 | } 32 | 33 | return $productVats; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Order/Service/OrderDeliveryAddressRelations.php: -------------------------------------------------------------------------------- 1 | orderDeliveryInfrastructure = $orderDeliveryInfrastructure; 29 | } 30 | 31 | /** 32 | * @Field() 33 | */ 34 | public function getProvider(OrderDelivery $orderDelivery): DeliveryProvider 35 | { 36 | return $this->orderDeliveryInfrastructure->getDeliveryProvider($orderDelivery); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Order/Service/OrderFileRelations.php: -------------------------------------------------------------------------------- 1 | fileService = $fileService; 31 | } 32 | 33 | /** 34 | * @Field() 35 | */ 36 | public function file(OrderFile $orderFile): ?FileDataType 37 | { 38 | try { 39 | return $this->fileService->file((string)$orderFile->fileId()); 40 | } catch (FileNotFound $e) { 41 | return null; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Order/Service/OrderInvoiceAddressRelations.php: -------------------------------------------------------------------------------- 1 | orderProductInfrastructure = $orderProductInfrastructure; 30 | } 31 | 32 | /** 33 | * @Field() 34 | * 35 | * @return OrderProductVats[] 36 | */ 37 | public function getVats(OrderProductBruttoSum $orderProductGross): array 38 | { 39 | return $this->orderProductInfrastructure->getVats($orderProductGross); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Payment/DataType/BasketPayment.php: -------------------------------------------------------------------------------- 1 | basketModel = $basketModel; 29 | 30 | parent::__construct($payment); 31 | } 32 | 33 | public function getBasketModel(): EshopBasketModel 34 | { 35 | return $this->basketModel; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Payment/Exception/MissingPayment.php: -------------------------------------------------------------------------------- 1 | repository = $repository; 26 | } 27 | 28 | /** 29 | * @throws PaymentNotFound 30 | */ 31 | public function payment(string $id): ?PaymentDataType 32 | { 33 | try { 34 | /** @var PaymentDataType $payment */ 35 | $payment = $this->repository->getById($id, PaymentDataType::class); 36 | } catch (NotFound $e) { 37 | throw new PaymentNotFound($id); 38 | } 39 | 40 | return $payment->isActive() ? $payment : null; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Product/DataType/ProductImage.php: -------------------------------------------------------------------------------- 1 | image = $image; 32 | $this->icon = $icon; 33 | $this->zoom = $zoom; 34 | } 35 | 36 | /** 37 | * @Field() 38 | */ 39 | public function getImage(): string 40 | { 41 | return $this->image; 42 | } 43 | 44 | /** 45 | * @Field() 46 | */ 47 | public function getIcon(): string 48 | { 49 | return $this->icon; 50 | } 51 | 52 | /** 53 | * @Field() 54 | */ 55 | public function getZoom(): string 56 | { 57 | return $this->zoom; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/Product/DataType/ProductRatingFilterList.php: -------------------------------------------------------------------------------- 1 | productId = $productId; 24 | parent::__construct(); 25 | } 26 | 27 | /** 28 | * @return array{ 29 | * oxobjectid: null|StringFilter 30 | * } 31 | */ 32 | public function getFilters(): array 33 | { 34 | return [ 35 | 'oxobjectid' => $this->productId, 36 | ]; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Product/Exception/ProductNotFound.php: -------------------------------------------------------------------------------- 1 | repository = $repository; 32 | } 33 | 34 | /** 35 | * @SuppressWarnings(PHPMD.UnusedFormalParameter) 36 | * 37 | * @return array 38 | */ 39 | public function getRatings(ProductRating $rating): array 40 | { 41 | return []; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Promotion/Controller/Promotion.php: -------------------------------------------------------------------------------- 1 | promotionService = $promotionService; 26 | } 27 | 28 | /** 29 | * @Query() 30 | */ 31 | public function promotion(ID $promotionId): PromotionDataType 32 | { 33 | return $this->promotionService->promotion($promotionId); 34 | } 35 | 36 | /** 37 | * @Query() 38 | * 39 | * @return PromotionDataType[] 40 | */ 41 | public function promotions(): array 42 | { 43 | return $this->promotionService->promotions(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Promotion/Exception/PromotionNotFound.php: -------------------------------------------------------------------------------- 1 | loadCurrent(); 25 | 26 | $result = []; 27 | 28 | $promotions = $actionList->getArray(); 29 | if ($promotions) { 30 | foreach ($promotions as $promotion) { 31 | $result[] = new PromotionDataType($promotion); 32 | } 33 | } 34 | 35 | return $result; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Review/DataType/ReviewFilterList.php: -------------------------------------------------------------------------------- 1 | user = $user; 25 | parent::__construct(); 26 | } 27 | 28 | /** 29 | * @return array{ 30 | * oxuserid: ?IDFilter, 31 | * } 32 | */ 33 | public function getFilters(): array 34 | { 35 | return [ 36 | 'oxuserid' => $this->user, 37 | ]; 38 | } 39 | 40 | /** 41 | * @Factory(name="ProductFilterList", default=true) 42 | */ 43 | public static function createProductFilterList( 44 | ?IDFilter $user = null 45 | ): self { 46 | return new self($user); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Review/DataType/Reviewer.php: -------------------------------------------------------------------------------- 1 | reviewer = $reviewer; 28 | } 29 | 30 | public function getEshopModel(): EshopUserModel 31 | { 32 | return $this->reviewer; 33 | } 34 | 35 | /** 36 | * @Field() 37 | */ 38 | public function getFirstName(): string 39 | { 40 | return (string)$this->reviewer->getRawFieldData('oxfname'); 41 | } 42 | 43 | public static function getModelClass(): string 44 | { 45 | return EshopUserModel::class; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Review/Exception/RatingOutOfBounds.php: -------------------------------------------------------------------------------- 1 | getEshopModel()->getRawFieldData('oxlang'); 20 | 21 | return new Language((int)$languageId); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Review/Infrastructure/ReviewFactory.php: -------------------------------------------------------------------------------- 1 | assign([ 26 | 'OXTYPE' => 'oxarticle', 27 | 'OXOBJECTID' => $productId, 28 | 'OXRATING' => $rating, 29 | 'OXUSERID' => $userId, 30 | 'OXTEXT' => $text, 31 | ]); 32 | 33 | return new ReviewDataType($model); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Review/Service/ActivityService.php: -------------------------------------------------------------------------------- 1 | legacyService = $legacyService; 28 | } 29 | 30 | /** 31 | * @Field() 32 | */ 33 | public function isActive(Review $review): bool 34 | { 35 | $reviewModel = $review->getEshopModel(); 36 | $moderationIsActive = (bool)$this->legacyService->getConfigParam('blGBModerate'); 37 | $reviewIsActive = (bool)$reviewModel->getRawFieldData('oxactive'); 38 | 39 | return $reviewIsActive || !$moderationIsActive; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Review/Service/Reviewer.php: -------------------------------------------------------------------------------- 1 | repository = $repository; 26 | } 27 | 28 | /** 29 | * @throws ReviewerNotFound 30 | */ 31 | public function reviewer(string $id): ReviewerDataType 32 | { 33 | try { 34 | /** @var ReviewerDataType $reviewer */ 35 | $reviewer = $this->repository->getById($id, ReviewerDataType::class); 36 | } catch (NotFound $e) { 37 | throw new ReviewerNotFound($id); 38 | } 39 | 40 | return $reviewer; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Shared/DataType/FilterList.php: -------------------------------------------------------------------------------- 1 | active = new BoolFilter(true); 23 | } 24 | 25 | /** 26 | * @return array 27 | */ 28 | abstract public function getFilters(): array; 29 | 30 | public function withActiveFilter(?BoolFilter $active): self 31 | { 32 | $filterList = clone $this; 33 | $filterList->active = $active; 34 | 35 | return $filterList; 36 | } 37 | 38 | public function getActive(): ?BoolFilter 39 | { 40 | return $this->active; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Shared/DataType/Language.php: -------------------------------------------------------------------------------- 1 | languageId = $languageId; 27 | } 28 | 29 | /** 30 | * @Field() 31 | */ 32 | public function getId(): ID 33 | { 34 | return new ID($this->getLanguageId()); 35 | } 36 | 37 | public function getLanguageId(): int 38 | { 39 | return $this->languageId; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Shared/DataType/ProductVat.php: -------------------------------------------------------------------------------- 1 | vatRate = $vatRate; 28 | $this->vatPrice = $vatPrice; 29 | } 30 | 31 | /** 32 | * @Field() 33 | */ 34 | public function getVatRate(): float 35 | { 36 | return (float)($this->vatRate); 37 | } 38 | 39 | /** 40 | * @Field() 41 | */ 42 | public function getVatPrice(): float 43 | { 44 | return (float)($this->vatPrice); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Shared/DataType/ProductVatsInterface.php: -------------------------------------------------------------------------------- 1 | setNettoPriceMode(); 21 | $price->setPrice($netSum); 22 | 23 | return $price; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Shared/Infrastructure/ActiveStatus.php: -------------------------------------------------------------------------------- 1 | getEshopModel(); 20 | 21 | $active = (bool)$model->getRawFieldData('oxactive'); 22 | 23 | if ($active) { 24 | return true; 25 | } 26 | 27 | $from = DateTimeImmutableFactory::fromString( 28 | (string)$model->getRawFieldData('oxactivefrom') 29 | ); 30 | $to = DateTimeImmutableFactory::fromString( 31 | (string)$model->getRawFieldData('oxactiveto') 32 | ); 33 | $now = $now ?? DateTimeImmutableFactory::fromString('now'); 34 | 35 | if ($from <= $now && $to >= $now) { 36 | return true; 37 | } 38 | 39 | return false; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Shared/Infrastructure/LanguageInfrastructure.php: -------------------------------------------------------------------------------- 1 | getLanguageAbbr($languageId); 19 | } 20 | 21 | public function getLanguageName(int $languageId): string 22 | { 23 | $languageNames = EshopRegistry::getLang()->getLanguageNames(); 24 | 25 | return $languageNames[$languageId]; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Shared/Infrastructure/OxNewFactory.php: -------------------------------------------------------------------------------- 1 | $class 18 | * 19 | * @return T 20 | */ 21 | public function getModel(string $class): object; 22 | } 23 | -------------------------------------------------------------------------------- /src/Shared/Service/AbstractActiveFilterService.php: -------------------------------------------------------------------------------- 1 | repository = $repository; 29 | $this->authorizationService = $authorizationService; 30 | } 31 | 32 | protected function setActiveFilter(FilterList &$filter): void 33 | { 34 | if ($this->authorizationService->isAllowed($this->getInactivePermission())) { 35 | $filter = $filter->withActiveFilter(null); 36 | } 37 | } 38 | 39 | abstract protected function getInactivePermission(): string; 40 | } 41 | -------------------------------------------------------------------------------- /src/Shared/Service/LanguageRelationService.php: -------------------------------------------------------------------------------- 1 | languageInfrastructure = $languageInfrastructure; 29 | } 30 | 31 | /** 32 | * @Field() 33 | */ 34 | public function getCode(Language $language): string 35 | { 36 | return $this->languageInfrastructure->getLanguageCode($language->getLanguageId()); 37 | } 38 | 39 | /** 40 | * @Field() 41 | */ 42 | public function getLanguage(Language $language): string 43 | { 44 | return $this->languageInfrastructure->getLanguageName($language->getLanguageId()); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Shared/Service/PriceRelationService.php: -------------------------------------------------------------------------------- 1 | currencyRepository = $currencyRepository; 30 | } 31 | 32 | /** 33 | * @Field() 34 | */ 35 | public function getCurrency(Price $price): Currency 36 | { 37 | $currencyObject = $price->getCurrencyObject(); 38 | if ($currencyObject) { 39 | return new Currency($currencyObject); 40 | } 41 | 42 | return $this->currencyRepository->getActiveCurrency(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Shared/Shop/Language.php: -------------------------------------------------------------------------------- 1 | 22 | */ 23 | public function getTranslationKeys(int $languageId): array 24 | { 25 | return $this->getLanguageFileData(false, $languageId); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Shared/Shop/User.php: -------------------------------------------------------------------------------- 1 | setAutoGroups((string)$this->getRawFieldData('oxcountryid')); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Translation/Controller/Translation.php: -------------------------------------------------------------------------------- 1 | translationService = $translationService; 25 | } 26 | 27 | /** 28 | * @Query 29 | */ 30 | public function translation(string $key): TranslationDataType 31 | { 32 | return $this->translationService->getTranslation($key); 33 | } 34 | 35 | /** 36 | * @Query 37 | * 38 | * @return TranslationDataType[] 39 | */ 40 | public function translations(): array 41 | { 42 | return $this->translationService->getTranslations(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Translation/DataType/Translation.php: -------------------------------------------------------------------------------- 1 | key = $key; 31 | $this->value = $value; 32 | } 33 | 34 | /** 35 | * @Field() 36 | */ 37 | public function getKey(): string 38 | { 39 | return $this->key; 40 | } 41 | 42 | /** 43 | * @Field() 44 | */ 45 | public function getValue(): string 46 | { 47 | return $this->value; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Translation/Exception/TranslationNotFound.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | public function getTranslations(int $languageId): array 18 | { 19 | /** @var \OxidEsales\GraphQL\Storefront\Shared\Shop\Language $language */ 20 | $language = \OxidEsales\Eshop\Core\Registry::getLang(); 21 | 22 | return $language->getTranslationKeys($languageId); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Vendor/DataType/Sorting.php: -------------------------------------------------------------------------------- 1 | $title, 25 | ]); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Vendor/Exception/VendorNotFound.php: -------------------------------------------------------------------------------- 1 | $id]); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Voucher/Exception/VoucherNotUsable.php: -------------------------------------------------------------------------------- 1 | $number]); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Voucher/Service/Voucher.php: -------------------------------------------------------------------------------- 1 | repository = $repository; 24 | } 25 | 26 | public function getVoucherById(string $id): VoucherDataType 27 | { 28 | return $this->repository->getVoucherById($id); 29 | } 30 | 31 | public function getVoucherByNumber(string $voucher): VoucherDataType 32 | { 33 | return $this->repository->getVoucherByNumber($voucher); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Voucher/Service/VoucherRelationService.php: -------------------------------------------------------------------------------- 1 | voucherSeriesService = $voucherSeriesService; 29 | } 30 | 31 | /** 32 | * @Field() 33 | */ 34 | public function series(Voucher $voucher): VoucherSeries 35 | { 36 | return $this->voucherSeriesService->series((string)$voucher->seriesId()); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Voucher/Service/VoucherSeries.php: -------------------------------------------------------------------------------- 1 | repository = $repository; 25 | } 26 | 27 | public function series(string $id): SeriesDataType 28 | { 29 | try { 30 | /** @var SeriesDataType $series */ 31 | $series = $this->repository->getById($id, SeriesDataType::class); 32 | } catch (NotFound $exception) { 33 | throw new SeriesNotFound($id); 34 | } 35 | 36 | return $series; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/WishedPrice/DataType/Inquirer.php: -------------------------------------------------------------------------------- 1 | inquirer = $inquirer; 28 | } 29 | 30 | public function getEshopModel(): EshopUserModel 31 | { 32 | return $this->inquirer; 33 | } 34 | 35 | /** 36 | * @Field() 37 | */ 38 | public function getFirstName(): string 39 | { 40 | return (string)$this->inquirer->getRawFieldData('oxfname'); 41 | } 42 | 43 | public static function getModelClass(): string 44 | { 45 | return EshopUserModel::class; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/WishedPrice/Exception/InquirerNotFound.php: -------------------------------------------------------------------------------- 1 | setPrice((float)$wishedPrice->getEshopModel()->getRawFieldData('oxprice')); 23 | 24 | return new Price($price); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/WishedPrice/Infrastructure/WishedPriceNotification.php: -------------------------------------------------------------------------------- 1 | sendPriceAlarmNotification( 24 | [ 25 | 'aid' => $wishedPrice->getProductId()->val(), 26 | 'email' => $wishedPrice->getEmail(), 27 | ], 28 | $wishedPrice->getEshopModel() 29 | ); 30 | 31 | if (!$result) { 32 | throw NotificationSendFailure::create($email->ErrorInfo); 33 | } 34 | 35 | return true; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/WishedPrice/Service/Inquirer.php: -------------------------------------------------------------------------------- 1 | repository = $repository; 26 | } 27 | 28 | /** 29 | * @throws InquirerNotFound 30 | */ 31 | public function inquirer(string $id): InquirerDataType 32 | { 33 | try { 34 | /** @var InquirerDataType $inquirer */ 35 | $inquirer = $this->repository->getById($id, InquirerDataType::class); 36 | } catch (NotFound $e) { 37 | throw new InquirerNotFound($id); 38 | } 39 | 40 | return $inquirer; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/Codeception/Acceptance/BaseCest.php: -------------------------------------------------------------------------------- 1 | logout(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/Codeception/Acceptance/Customer/CustomerBaseCest.php: -------------------------------------------------------------------------------- 1 | logout(); 27 | } 28 | 29 | protected function getAgentUsername(): string 30 | { 31 | return self::AGENT_USERNAME; 32 | } 33 | 34 | protected function getAgentPassword(): string 35 | { 36 | return self::AGENT_PASSWORD; 37 | } 38 | 39 | protected function getAdminUsername(): string 40 | { 41 | return self::ADMIN_USERNAME; 42 | } 43 | 44 | protected function getAdminPassword(): string 45 | { 46 | return self::ADMIN_PASSWORD; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /tests/Codeception/Acceptance/_bootstrap.php: -------------------------------------------------------------------------------- 1 | getShopRootPath(), 'source', 'bootstrap.php'); 14 | -------------------------------------------------------------------------------- /tests/Codeception/Data/testdata.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OXID-eSales/graphql-storefront-module/9f37f95b5885a321b5d62b26bb75552b093e40d7/tests/Codeception/Data/testdata.sql -------------------------------------------------------------------------------- /tests/Codeception/Support/AcceptanceTester.php: -------------------------------------------------------------------------------- 1 | _sCoreTable = 'oxuser'; 20 | } 21 | 22 | /** 23 | * @param mixed $data 24 | * @var array 25 | * 26 | */ 27 | public function assign($data): void 28 | { 29 | foreach ($data as $k => $v) { 30 | $this->{$this->_sCoreTable . '__' . $k} = new Field( 31 | $v, 32 | Field::T_RAW 33 | ); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/Integration/Customer/DependencyInjectionTest.php: -------------------------------------------------------------------------------- 1 | get(Password::class); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/Integration/EnterpriseTestCase.php: -------------------------------------------------------------------------------- 1 | get(Config::class); 24 | $configValue = match ($sizeName) { 25 | 'image' => $config->getConfigParam('aDetailImageSizes')['oxpic1'], 26 | 'icon' => $config->getConfigParam('sIconsize'), 27 | 'zoom' => $config->getConfigParam('sZoomImageSize'), 28 | 'thumb' => $config->getConfigParam('sThumbnailsize'), 29 | default => $this->fail('Wrong size name provided') 30 | }; 31 | $size = str_replace('*', '_', $configValue); 32 | 33 | $this->assertMatchesRegularExpression( 34 | sprintf('@https?://.*/out/pictures/generated/product/%s/%s_75/%s@', $key, $size, $fileName), 35 | $imageUrl 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tests/Integration/MultiLanguageTestCase.php: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | Standard OXID Ruleset 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /tests/PhpStan/phpstan-bootstrap.php: -------------------------------------------------------------------------------- 1 | assertSame(self::BASKET_ID, (string) $event->getBasketId()); 34 | $this->assertSame(self::PRODUCT_ID, (string) $event->getProductId()); 35 | $this->assertEquals(3, $event->getAmount()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tests/Unit/Basket/Event/AfterRemoveItemTest.php: -------------------------------------------------------------------------------- 1 | assertSame(self::BASKET_ID, (string) $event->getBasketId()); 34 | $this->assertSame(self::BASKETITEM_ID, (string) $event->getBasketItemId()); 35 | $this->assertEquals(3, $event->getAmount()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tests/Unit/Basket/Event/BeforeAddItemTest.php: -------------------------------------------------------------------------------- 1 | prepareEvent(); 23 | $event->setAmount((float)self::SET_AMMOUNT); 24 | 25 | $this->assertSame((float)self::SET_AMMOUNT, $event->getAmount()); 26 | } 27 | 28 | protected function prepareEvent(): Event 29 | { 30 | return new Event( 31 | new ID(self::BASKET_ID), 32 | new ID(self::BASKET_ITEM_ID), 33 | (float)self::AMMOUNT 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/Unit/Basket/Event/BeforeBasketDeliveryMethodsTest.php: -------------------------------------------------------------------------------- 1 | 'foo']; 26 | 27 | $event = $this->prepareEvent(); 28 | $event->setDeliveryMethods($deliveryMethods); 29 | 30 | $this->assertSame($deliveryMethods, $event->getDeliveryMethods()); 31 | } 32 | 33 | protected function prepareEvent(): Event 34 | { 35 | $event = 36 | new Event( 37 | new ID(self::BASKET_ID) 38 | ); 39 | 40 | $this->assertSame(self::BASKET_ID, (string) $event->getBasketId()); 41 | 42 | return $event; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tests/Unit/Basket/Event/BeforeBasketPaymentsTest.php: -------------------------------------------------------------------------------- 1 | 'foo']; 26 | 27 | $event = $this->prepareEvent(); 28 | $event->setPayments($payments); 29 | 30 | $this->assertSame($payments, $event->getPayments()); 31 | } 32 | 33 | protected function prepareEvent(): Event 34 | { 35 | $event = 36 | new Event( 37 | new ID(self::BASKET_ID) 38 | ); 39 | 40 | $this->assertSame(self::BASKET_ID, (string) $event->getBasketId()); 41 | 42 | return $event; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tests/Unit/Basket/Event/BeforeBasketRemoveOnPlaceOrderTest.php: -------------------------------------------------------------------------------- 1 | prepareEvent(); 26 | $this->assertFalse($event->getPreserveBasketAfterOrder()); 27 | 28 | $event->setPreserveBasketAfterOrder(true); 29 | $this->assertTrue($event->getPreserveBasketAfterOrder()); 30 | } 31 | 32 | protected function prepareEvent(): Event 33 | { 34 | $event = 35 | new Event( 36 | new ID(self::BASKET_ID) 37 | ); 38 | 39 | $this->assertSame(self::BASKET_ID, (string) $event->getBasketId()); 40 | 41 | return $event; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /tests/Unit/Basket/Event/BeforePlaceOrderTest.php: -------------------------------------------------------------------------------- 1 | assertSame(self::BASKET_ID, (string) $event->getBasketId()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /tests/Unit/Basket/Event/BeforeRemoveItemTest.php: -------------------------------------------------------------------------------- 1 | prepareEvent(); 23 | $event->setAmount((float)self::SET_AMMOUNT); 24 | 25 | $this->assertSame((float)self::SET_AMMOUNT, $event->getAmount()); 26 | } 27 | 28 | protected function prepareEvent(): Event 29 | { 30 | return new Event( 31 | new ID(self::BASKET_ID), 32 | new ID(self::BASKET_ITEM_ID), 33 | (float)self::AMMOUNT 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/Unit/Country/DataType/StateModelStub.php: -------------------------------------------------------------------------------- 1 | _sCoreTable = 'oxstates'; 20 | } 21 | 22 | /** 23 | * @param mixed $data 24 | * @var array 25 | * 26 | */ 27 | public function assign($data): void 28 | { 29 | foreach ($data as $k => $v) { 30 | $this->{$this->_sCoreTable . '__' . $k} = new Field( 31 | $v, 32 | Field::T_RAW 33 | ); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/Unit/DataType/CategoryStub.php: -------------------------------------------------------------------------------- 1 | _sCoreTable = 'oxcategories'; 23 | 24 | $this->oxcategories__oxactive = new Field( 25 | $active, 26 | Field::T_RAW 27 | ); 28 | $this->oxcategories__oxactivefrom = new Field( 29 | $activefrom, 30 | Field::T_RAW 31 | ); 32 | $this->oxcategories__oxactiveto = new Field( 33 | $activeto, 34 | Field::T_RAW 35 | ); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tests/Unit/DataType/NoEshopUrlContractModelStub.php: -------------------------------------------------------------------------------- 1 | assertEquals( 26 | [ 27 | 'oxtitle' => null, 28 | 'oxcatnid' => null, 29 | 'oxmanufacturerid' => null, 30 | 'oxvendorid' => null, 31 | 'oxparentid' => new IDFilter(new ID('')), 32 | ], 33 | $filter->getFilters() 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/Unit/DataType/ProductImageTest.php: -------------------------------------------------------------------------------- 1 | assertSame( 29 | $imageValue, 30 | $productImage->getImage() 31 | ); 32 | $this->assertSame( 33 | $iconValue, 34 | $productImage->getIcon() 35 | ); 36 | $this->assertSame( 37 | $zoomValue, 38 | $productImage->getZoom() 39 | ); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tests/Unit/DataType/ProductScalePriceModelStub.php: -------------------------------------------------------------------------------- 1 | _sCoreTable = 'oxprice2article'; 24 | 25 | $this->oxprice2article__oxaddabs = new Field( 26 | $addAbsolute, 27 | Field::T_RAW 28 | ); 29 | $this->oxprice2article__oxaddperc = new Field( 30 | $addPercentage, 31 | Field::T_RAW 32 | ); 33 | $this->oxprice2article__oxamount = new Field( 34 | $amountFrom, 35 | Field::T_RAW 36 | ); 37 | $this->oxprice2article__oxamountto = new Field( 38 | $amountTo, 39 | Field::T_RAW 40 | ); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/Unit/DataType/SeoTest.php: -------------------------------------------------------------------------------- 1 | assertNull( 27 | $seo->getUrl() 28 | ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/Unit/Delivery/DataType/DeliveryAddressModelStub.php: -------------------------------------------------------------------------------- 1 | _sCoreTable = 'oxaddress'; 20 | } 21 | 22 | /** 23 | * @param mixed $data 24 | * @var array 25 | * 26 | */ 27 | public function assign($data): void 28 | { 29 | foreach ($data as $k => $v) { 30 | $this->{$this->_sCoreTable . '__' . $k} = new Field( 31 | $v, 32 | Field::T_RAW 33 | ); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/Unit/Exception/AttributeNotFoundTest.php: -------------------------------------------------------------------------------- 1 | expectException(AttributeNotFound::class); 23 | $this->expectExceptionMessage('ATTRID'); 24 | 25 | throw new AttributeNotFound('ATTRID'); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tests/Unit/Exception/CategoryNotFoundTest.php: -------------------------------------------------------------------------------- 1 | expectException(CategoryNotFound::class); 23 | $this->expectExceptionMessage('CATID'); 24 | 25 | throw new CategoryNotFound('CATID'); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tests/Unit/Exception/ManufacturerNotFoundTest.php: -------------------------------------------------------------------------------- 1 | expectException(ManufacturerNotFound::class); 23 | $this->expectExceptionMessage('MANUID'); 24 | 25 | throw new ManufacturerNotFound('MANUID'); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tests/Unit/Exception/VendorNotFoundTest.php: -------------------------------------------------------------------------------- 1 | expectException(VendorNotFound::class); 23 | $this->expectExceptionMessage('VENDORID'); 24 | 25 | throw new VendorNotFound('VENDORID'); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tests/Unit/Shared/Service/NamespaceMapperTest.php: -------------------------------------------------------------------------------- 1 | assertCount( 24 | 20, 25 | $namespaceMapper->getControllerNamespaceMapping() 26 | ); 27 | $this->assertCount( 28 | 45, 29 | $namespaceMapper->getTypeNamespaceMapping() 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/Unit/travis_dummy: -------------------------------------------------------------------------------- 1 | This file is for having tests\Unit\ directory in git tree needed by Travis. Please remove it as soon as another files are put there. -------------------------------------------------------------------------------- /tests/codeception.yml: -------------------------------------------------------------------------------- 1 | namespace: OxidEsales\GraphQL\Storefront\Tests\Codeception 2 | params: 3 | - Codeception/Config/params.php 4 | paths: 5 | tests: Codeception 6 | output: Codeception/_output 7 | data: Codeception/Data 8 | support: Codeception/Support 9 | envs: Codeception/_envs 10 | actor_suffix: Tester 11 | 12 | settings: 13 | colors: true 14 | log: true 15 | memory_limit: 4096M 16 | 17 | extensions: 18 | enabled: 19 | - Codeception\Extension\RunFailed 20 | 21 | coverage: 22 | enabled: true 23 | remote: false 24 | local: true 25 | c3_url: '%SHOP_URL%' 26 | remote_config: 'tests/codeception.yml' 27 | include: 28 | - ../src/* 29 | -------------------------------------------------------------------------------- /tests/phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 21 | Unit/ 22 | 23 | 24 | Integration/ 25 | 26 | 27 | 28 | 29 | ../src 30 | 31 | 32 | 33 | --------------------------------------------------------------------------------